X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fresponse.cc;h=809d5b6fb7606793b71d06c9c60e21e47d515958;hb=299c04f7d92895d0ec5e1cce437d19b3334b75ac;hp=69ac26a4ac54ae6fa1057a8910f7013f6e7c7363;hpb=dd3626ef6e3fd2a4f7d88a23cd9a91fc2ab5e32d;p=m6w6%2Flibmemcached diff --git a/libmemcached/response.cc b/libmemcached/response.cc index 69ac26a4..809d5b6f 100644 --- a/libmemcached/response.cc +++ b/libmemcached/response.cc @@ -55,12 +55,15 @@ static memcached_return_t textual_value_fetch(memcached_server_write_instance_st string_ptr+= 6; /* "VALUE " */ + // Just used for cases of AES decrypt currently + memcached_return_t rc= MEMCACHED_SUCCESS; + /* We load the key */ { char *key= result->item_key; result->key_length= 0; - for (size_t prefix_length= memcached_array_size(instance->root->_namespace); !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++) + for (ptrdiff_t prefix_length= memcached_array_size(instance->root->_namespace); !(iscntrl(*string_ptr) || isspace(*string_ptr)) ; string_ptr++) { if (prefix_length == 0) { @@ -169,7 +172,34 @@ static memcached_return_t textual_value_fetch(memcached_server_write_instance_st memcached_string_set_length(&result->value, value_length); } - return MEMCACHED_SUCCESS; + if (memcached_is_encrypted(instance->root) and memcached_result_length(result)) + { + hashkit_string_st *destination; + + if ((destination= hashkit_decrypt(&instance->root->hashkit, + memcached_result_value(result), memcached_result_length(result))) == NULL) + { + rc= memcached_set_error(*instance->root, MEMCACHED_FAILURE, + MEMCACHED_AT, memcached_literal_param("hashkit_decrypt() failed")); + } + else + { + memcached_result_reset_value(result); + if (memcached_failed(memcached_result_set_value(result, hashkit_string_c_str(destination), hashkit_string_length(destination)))) + { + rc= memcached_set_error(*instance->root, MEMCACHED_FAILURE, + MEMCACHED_AT, memcached_literal_param("hashkit_decrypt() failed")); + } + } + + if (memcached_failed(rc)) + { + memcached_result_reset(result); + } + hashkit_string_free(destination); + } + + return rc; read_error: memcached_io_reset(instance); @@ -206,35 +236,31 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta { /* Find the space, and then move one past it to copy version */ char *response_ptr= index(buffer, ' '); - response_ptr++; - long int version= strtol(response_ptr, (char **)NULL, 10); + char *endptr; + 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) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); } instance->major_version= uint8_t(version); - response_ptr= index(response_ptr, '.'); - response_ptr++; - - version= strtol(response_ptr, (char **)NULL, 10); + endptr++; + version= strtol(endptr, &endptr, 10); if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); } instance->minor_version= uint8_t(version); - response_ptr= index(response_ptr, '.'); - response_ptr++; - - version= strtol(response_ptr, (char **)NULL, 10); + endptr++; + version= strtol(endptr, &endptr, 10); if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); } instance->micro_version= uint8_t(version); @@ -558,6 +584,21 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan break; case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: + { + if (header.response.keylen != 0 || bodylen + 1 > buffer_length) + { + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + else + { + if ((rc= memcached_safe_read(instance, buffer, bodylen)) != MEMCACHED_SUCCESS) + { + return MEMCACHED_UNKNOWN_READ_FAILURE; + } + } + } + break; + case PROTOCOL_BINARY_CMD_VERSION: { char version_buffer[32]; // @todo document this number @@ -568,28 +609,30 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan return MEMCACHED_UNKNOWN_READ_FAILURE; } - char *p; - long int version= strtol(version_buffer, &p, 10); + char *endptr; + 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) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version")); } instance->major_version= uint8_t(version); - version= strtol(p +1, &p, 10); + endptr++; + version= strtol(endptr, &endptr, 10); if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version")); } instance->minor_version= uint8_t(version); - version= strtol(p + 1, NULL, 10); - if (errno == ERANGE) + endptr++; + version= strtol(endptr, &endptr, 10); + if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX) { instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX; - return memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); + return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version")); } instance->micro_version= uint8_t(version); } @@ -764,7 +807,6 @@ static memcached_return_t _read_one_response(memcached_server_write_instance_st else { rc= textual_read_one_response(instance, buffer, buffer_length, result); - assert(rc != MEMCACHED_PROTOCOL_ERROR); } if (memcached_fatal(rc))