X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fresponse.cc;h=7503c5a0d2da58aa8764810441775b2c1c17132f;hb=9763b8e9b681d1d6713b95e4d7ce6ffeafeafca5;hp=85d675bb53bc9bc4bbb859423d8e754c5d2d4712;hpb=599f5fe51b935465234e8085e549915d9b131fd1;p=awesomized%2Flibmemcached diff --git a/libmemcached/response.cc b/libmemcached/response.cc index 85d675bb..7503c5a0 100644 --- a/libmemcached/response.cc +++ b/libmemcached/response.cc @@ -90,9 +90,10 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta } for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {}; + errno= 0; result->item_flags= (uint32_t) strtoul(next_ptr, &string_ptr, 10); - if (end_ptr == string_ptr) + if (errno != 0 or end_ptr == string_ptr) { goto read_error; } @@ -105,9 +106,10 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta } for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {}; + errno= 0; value_length= (size_t)strtoull(next_ptr, &string_ptr, 10); - if (end_ptr == string_ptr) + if (errno != 0 or end_ptr == string_ptr) { goto read_error; } @@ -122,10 +124,11 @@ static memcached_return_t textual_value_fetch(org::libmemcached::Instance* insta { string_ptr++; for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++) {}; + errno= 0; result->item_cas= strtoull(next_ptr, &string_ptr, 10); } - if (end_ptr < string_ptr) + if (errno != 0 or end_ptr < string_ptr) { goto read_error; } @@ -238,8 +241,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance* char *response_ptr= index(buffer, ' '); char *endptr; + errno= 0; long int version= strtol(response_ptr, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX or version == 0) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); @@ -247,8 +251,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance* instance->major_version= uint8_t(version); endptr++; + errno= 0; version= strtol(endptr, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); @@ -256,8 +261,9 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance* instance->minor_version= uint8_t(version); endptr++; + errno= 0; version= strtol(endptr, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); @@ -442,6 +448,7 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance* case '8': /* INCR/DECR response */ case '9': /* INCR/DECR response */ { + errno= 0; unsigned long long int auto_return_value= strtoull(buffer, (char **)NULL, 10); if (auto_return_value == ULLONG_MAX and errno == ERANGE) @@ -456,6 +463,12 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance* return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("Numeric response was out of range")); } + else if (errno != 0) + { + result->numeric_value= UINT64_MAX; + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, + memcached_literal_param("Numeric response was out of range")); + } result->numeric_value= uint64_t(auto_return_value); @@ -620,8 +633,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance* } char *endptr; + errno= 0; long int version= strtol(version_buffer, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX or version == 0) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); @@ -629,8 +643,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance* instance->major_version= uint8_t(version); endptr++; + errno= 0; version= strtol(endptr, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); @@ -638,8 +653,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance* instance->minor_version= uint8_t(version); endptr++; + errno= 0; version= strtol(endptr, &endptr, 10); - if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) + if (errno != 0 or version == LONG_MIN or version == LONG_MAX or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); @@ -648,6 +664,25 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance* } break; + case PROTOCOL_BINARY_CMD_TOUCH: + { + rc= MEMCACHED_SUCCESS; + if (bodylen == 4) // The four byte read is a bug? + { + char touch_buffer[4]; // @todo document this number + rc= memcached_safe_read(instance, touch_buffer, sizeof(touch_buffer)); +#if 0 + fprintf(stderr, "%s:%d %d %d %d %d %.*s(%d)\n", __FILE__, __LINE__, + int(touch_buffer[0]), + int(touch_buffer[1]), + int(touch_buffer[2]), + int(touch_buffer[3]), + int(bodylen), touch_buffer, int(bodylen)); +#endif + } + return memcached_set_error(*instance, rc, MEMCACHED_AT); + } + case PROTOCOL_BINARY_CMD_FLUSH: case PROTOCOL_BINARY_CMD_QUIT: case PROTOCOL_BINARY_CMD_SET: @@ -656,14 +691,9 @@ static memcached_return_t binary_read_one_response(org::libmemcached::Instance* case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_PREPEND: case PROTOCOL_BINARY_CMD_DELETE: - case PROTOCOL_BINARY_CMD_TOUCH: { - if (bodylen != 0) - { - char touch_buffer[32]; // @todo document this number - rc= memcached_safe_read(instance, buffer, sizeof(touch_buffer)); - } - return memcached_set_error(*instance, rc, MEMCACHED_AT); + WATCHPOINT_ASSERT(bodylen == 0); + return MEMCACHED_SUCCESS; } case PROTOCOL_BINARY_CMD_NOOP: