diff -ru a/libmemcached-0.32/libmemcached/memcached_response.c b/libmemcached-0.32/libmemcached/memcached_response.c --- a/libmemcached-0.32/libmemcached/memcached_response.c 2011-03-08 13:07:36.000000000 -0800 +++ b/libmemcached-0.32/libmemcached/memcached_response.c 2011-03-08 13:02:11.000000000 -0800 @@ -239,32 +239,19 @@ } else if (buffer[1] == 'E') /* SERVER_ERROR */ { - char *rel_ptr; - char *startptr= buffer + 13, *endptr= startptr; - - while (*endptr != '\r' && *endptr != '\n') endptr++; + memcached_server_error_reset(ptr); - /* - Yes, we could make this "efficent" but to do that we would need - to maintain more state for the size of the buffer. Why waste - memory in the struct, which is important, for something that - rarely should happen? - */ - rel_ptr= (char *)ptr->root->call_realloc(ptr->root, - ptr->cached_server_error, - (size_t) (endptr - startptr + 1)); - - if (rel_ptr == NULL) - { - /* If we happened to have some memory, we just null it since we don't know the size */ - if (ptr->cached_server_error) - ptr->cached_server_error[0]= 0; - return MEMCACHED_SERVER_ERROR; - } - ptr->cached_server_error= rel_ptr; + char *startptr= buffer + 13, *endptr= startptr; + while (*endptr != '\r' && *endptr != '\n') + endptr++; + size_t err_len = (endptr - startptr + 1); + + ptr->cached_server_error = malloc(err_len); + if (ptr->cached_server_error == NULL) + return MEMCACHED_SERVER_ERROR; - memcpy(ptr->cached_server_error, startptr, (size_t) (endptr - startptr)); - ptr->cached_server_error[endptr - startptr]= 0; + strncpy(ptr->cached_server_error, startptr, err_len); + ptr->cached_server_error[err_len - 1]= 0; return MEMCACHED_SERVER_ERROR; } else if (buffer[1] == 'T') diff -ru a/libmemcached-0.32/libmemcached/memcached_server.c b/libmemcached-0.32/libmemcached/memcached_server.c --- a/libmemcached-0.32/libmemcached/memcached_server.c 2009-07-15 03:34:17.000000000 -0700 +++ b/libmemcached-0.32/libmemcached/memcached_server.c 2011-03-08 13:02:11.000000000 -0800 @@ -16,14 +16,14 @@ } else memset(ptr, 0, sizeof(memcached_server_st)); - + ptr->root= memc; return ptr; } -memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_server_st *host, - const char *hostname, unsigned int port, +memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_server_st *host, + const char *hostname, unsigned int port, uint32_t weight, memcached_connection type) { host= memcached_server_create(memc, host); @@ -52,9 +52,7 @@ void memcached_server_free(memcached_server_st *ptr) { memcached_quit_server(ptr, 0); - - if (ptr->cached_server_error) - free(ptr->cached_server_error); + memcached_server_error_reset(ptr); if (ptr->address_info) freeaddrinfo(ptr->address_info); @@ -76,21 +74,24 @@ if (ptr == NULL) return NULL; - rv = memcached_server_create_with(ptr->root, clone, + rv = memcached_server_create_with(ptr->root, clone, ptr->hostname, ptr->port, ptr->weight, ptr->type); if (rv != NULL) { rv->cached_errno= ptr->cached_errno; - if (ptr->cached_server_error) - rv->cached_server_error= strdup(ptr->cached_server_error); + if (ptr->cached_server_error) { + size_t err_len = strlen(ptr->cached_server_error) + 1; + rv->cached_server_error = malloc(err_len); + strncpy(rv->cached_server_error, ptr->cached_server_error, err_len); + } } return rv; } -memcached_return memcached_server_cursor(memcached_st *ptr, +memcached_return memcached_server_cursor(memcached_st *ptr, memcached_server_function *callback, void *context, unsigned int number_of_callbacks) @@ -119,7 +120,7 @@ { uint32_t server_key; - *error= memcached_validate_key_length(key_length, + *error= memcached_validate_key_length(key_length, ptr->flags & MEM_BINARY_PROTOCOL); unlikely (*error != MEMCACHED_SUCCESS) return NULL; @@ -144,13 +145,16 @@ const char *memcached_server_error(memcached_server_st *ptr) { - if (ptr) + if (ptr->cached_server_error) return ptr->cached_server_error; - else + else return NULL; } void memcached_server_error_reset(memcached_server_st *ptr) { - ptr->cached_server_error[0]= 0; + if (ptr->cached_server_error) { + free(ptr->cached_server_error); + ptr->cached_server_error = 0; + } }