From: Michael Wallner Date: Tue, 9 Aug 2022 08:29:13 +0000 (+0200) Subject: libmemcached: fix #125: allocation failure on negative expiration X-Git-Tag: 1.1.2~4 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=a124aaabc96a1e58b03f90ac17a75e1df1918cd5;p=awesomized%2Flibmemcached libmemcached: fix #125: allocation failure on negative expiration --- diff --git a/ChangeLog-1.1.md b/ChangeLog-1.1.md index 9546980e..b430d936 100644 --- a/ChangeLog-1.1.md +++ b/ChangeLog-1.1.md @@ -1,5 +1,13 @@ # ChangeLog v1.1 +## v 1.1.2 + +> released 2022-08-08 + +* Fix handling of negative expiration values, which are somehow allowed by legacy. + See also [gh #125](https://github.com/awesomized/libmemcached/issues/125), + and [gh #76](https://github.com/awesomized/libmemcached/issues/76). + ## v 1.1.1 > released 2021-09-16 diff --git a/src/libmemcached/flush.cc b/src/libmemcached/flush.cc index 5e358b08..e0b45b68 100644 --- a/src/libmemcached/flush.cc +++ b/src/libmemcached/flush.cc @@ -61,10 +61,10 @@ static memcached_return_t memcached_flush_binary(Memcached *ptr, time_t expirati static memcached_return_t memcached_flush_textual(Memcached *ptr, time_t expiration, const bool reply) { - char buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1]; + char buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1 + 1]; int send_length = 0; if (expiration) { - send_length = snprintf(buffer, sizeof(buffer), "%llu", (unsigned long long) expiration); + send_length = snprintf(buffer, sizeof(buffer), "%lld", (long long) expiration); } if (size_t(send_length) >= sizeof(buffer) or send_length < 0) { diff --git a/src/libmemcached/storage.cc b/src/libmemcached/storage.cc index eacc04f0..31eadb1e 100644 --- a/src/libmemcached/storage.cc +++ b/src/libmemcached/storage.cc @@ -189,9 +189,9 @@ memcached_send_ascii(Memcached *ptr, memcached_instance_st *instance, const char memcached_literal_param("snprintf(MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH)")); } - char expiration_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1]; - int expiration_buffer_length = snprintf(expiration_buffer, sizeof(expiration_buffer), " %llu", - (unsigned long long) expiration); + char expiration_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1 + 1]; + int expiration_buffer_length = snprintf(expiration_buffer, sizeof(expiration_buffer), " %lld", + (long long) expiration); if (size_t(expiration_buffer_length) >= sizeof(expiration_buffer) or expiration_buffer_length < 0) { return memcached_set_error( diff --git a/src/libmemcached/touch.cc b/src/libmemcached/touch.cc index 6d8fdc4e..b55f33e0 100644 --- a/src/libmemcached/touch.cc +++ b/src/libmemcached/touch.cc @@ -17,9 +17,9 @@ static memcached_return_t ascii_touch(memcached_instance_st *instance, const char *key, size_t key_length, time_t expiration) { - char expiration_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1]; - int expiration_buffer_length = snprintf(expiration_buffer, sizeof(expiration_buffer), " %llu", - (unsigned long long) expiration); + char expiration_buffer[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH + 1 + 1]; + int expiration_buffer_length = snprintf(expiration_buffer, sizeof(expiration_buffer), " %lld", + (long long) expiration); if (size_t(expiration_buffer_length) >= sizeof(expiration_buffer) + 1 or expiration_buffer_length < 0) { diff --git a/test/tests/memcached/regression/gh_0125.cpp b/test/tests/memcached/regression/gh_0125.cpp new file mode 100644 index 00000000..ca04af21 --- /dev/null +++ b/test/tests/memcached/regression/gh_0125.cpp @@ -0,0 +1,15 @@ +#include "test/lib/common.hpp" +#include "test/lib/MemcachedCluster.hpp" + +TEST_CASE("memcached_regression_gh_0125") { + auto test = MemcachedCluster::network(); + auto memc = &test.memc; + auto blob = random_ascii_string(1024); + auto binary = GENERATE(0, 1); + + test.enableBinaryProto(binary); + INFO("binary: " << binary); + + memcached_return_t rc = memcached_set(memc, S("key"), blob.c_str(), blob.length(), -123, 0); + REQUIRE_SUCCESS(rc); +}