From 9bf4bad8ef3ee7f713904d8c85b73fe54f461739 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Tue, 22 May 2012 00:10:39 -0400 Subject: [PATCH] Fix issue where stale result set might end up being read (this has never been reported as a bug). --- libmemcached/fetch.cc | 8 ++++--- libmemcached/get.cc | 28 +++++++++++++++---------- libmemcached/initialize_query.cc | 1 + tests/libmemcached-1.0/mem_functions.cc | 11 +++++----- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/libmemcached/fetch.cc b/libmemcached/fetch.cc index 2b5b8006..27ea3a84 100644 --- a/libmemcached/fetch.cc +++ b/libmemcached/fetch.cc @@ -155,10 +155,12 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, memcached_return_t *error) { memcached_return_t unused; - if (not error) + if (error == NULL) + { error= &unused; + } - if (not ptr) + if (ptr == NULL) { *error= MEMCACHED_INVALID_ARGUMENTS; return NULL; @@ -176,7 +178,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, // create one. if (memcached_is_initialized(&ptr->result)) { - if (not (result= memcached_result_create(ptr, NULL))) + if ((result= memcached_result_create(ptr, NULL)) == NULL) { *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE; return NULL; diff --git a/libmemcached/get.cc b/libmemcached/get.cc index 86f13670..be7d9e5f 100644 --- a/libmemcached/get.cc +++ b/libmemcached/get.cc @@ -119,8 +119,9 @@ char *memcached_get_by_key(memcached_st *ptr, { if (ptr->get_key_failure and *error == MEMCACHED_NOTFOUND) { - memcached_result_reset(&ptr->result); - memcached_return_t rc= ptr->get_key_failure(ptr, key, key_length, &ptr->result); + memcached_result_st key_failure_result; + memcached_result_st* result_ptr= memcached_result_create(ptr, &key_failure_result); + memcached_return_t rc= ptr->get_key_failure(ptr, key, key_length, result_ptr); /* On all failure drop to returning NULL */ if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED) @@ -135,10 +136,10 @@ char *memcached_get_by_key(memcached_st *ptr, } rc= memcached_set(ptr, key, key_length, - (memcached_result_value(&ptr->result)), - (memcached_result_length(&ptr->result)), + (memcached_result_value(result_ptr)), + (memcached_result_length(result_ptr)), 0, - (memcached_result_flags(&ptr->result))); + (memcached_result_flags(result_ptr))); if (rc == MEMCACHED_BUFFERED and latch == 0) { @@ -148,20 +149,25 @@ char *memcached_get_by_key(memcached_st *ptr, else { rc= memcached_set(ptr, key, key_length, - (memcached_result_value(&ptr->result)), - (memcached_result_length(&ptr->result)), + (memcached_result_value(result_ptr)), + (memcached_result_length(result_ptr)), 0, - (memcached_result_flags(&ptr->result))); + (memcached_result_flags(result_ptr))); } if (rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED) { *error= rc; - *value_length= memcached_result_length(&ptr->result); - *flags= memcached_result_flags(&ptr->result); - return memcached_string_take_value(&ptr->result.value); + *value_length= memcached_result_length(result_ptr); + *flags= memcached_result_flags(result_ptr); + char *result_value= memcached_string_take_value(&result_ptr->value); + memcached_result_free(result_ptr); + + return result_value; } } + + memcached_result_free(result_ptr); } assert_msg(ptr->query_id == query_id +1, "Programmer error, the query_id was not incremented."); diff --git a/libmemcached/initialize_query.cc b/libmemcached/initialize_query.cc index dca3c4d8..0a4aae07 100644 --- a/libmemcached/initialize_query.cc +++ b/libmemcached/initialize_query.cc @@ -59,6 +59,7 @@ memcached_return_t initialize_query(memcached_st *self, bool increment_query_id) } memcached_error_free(*self); + memcached_result_reset(&self->result); return MEMCACHED_SUCCESS; } diff --git a/tests/libmemcached-1.0/mem_functions.cc b/tests/libmemcached-1.0/mem_functions.cc index f8ac3da6..8b88697a 100644 --- a/tests/libmemcached-1.0/mem_functions.cc +++ b/tests/libmemcached-1.0/mem_functions.cc @@ -1026,12 +1026,11 @@ test_return_t bad_key_test(memcached_st *memc) } #define READ_THROUGH_VALUE "set for me" -static memcached_return_t read_through_trigger(memcached_st *memc, - char *key, - size_t key_length, +static memcached_return_t read_through_trigger(memcached_st *, // memc + char *, // key + size_t, // key_length, memcached_result_st *result) { - (void)memc;(void)key;(void)key_length; return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE)); } @@ -1062,8 +1061,8 @@ test_return_t read_through(memcached_st *memc) &string_length, &flags, &rc); test_compare(MEMCACHED_SUCCESS, rc); - test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1); - test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0); + test_compare(sizeof(READ_THROUGH_VALUE) -1, string_length); + test_compare(0, string[sizeof(READ_THROUGH_VALUE) -1]); test_strcmp(READ_THROUGH_VALUE, string); free(string); -- 2.30.2