Skip to content

Commit c85f34c

Browse files
committed
Make sure that s_compress_value() will always leave a valid payload, even if it did not get compressed
1 parent 7283b11 commit c85f34c

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

Diff for: php_memcached.c

+27-26
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
830830
/* status */
831831
zend_bool compress_status = 0;
832832
zend_string *payload = *payload_in;
833+
uint32_t compression_type_flag = 0;
833834

834835
/* Additional 5% for the data */
835836
size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0);
@@ -847,7 +848,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
847848

848849
if (compressed_size > 0) {
849850
compress_status = 1;
850-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ);
851+
compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ;
851852
}
852853
}
853854
break;
@@ -859,7 +860,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
859860

860861
if (status == Z_OK) {
861862
compress_status = 1;
862-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_ZLIB);
863+
compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB;
863864
}
864865
}
865866
break;
@@ -869,31 +870,29 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str
869870
break;
870871
}
871872

872-
if (!compress_status) {
873-
php_error_docref(NULL, E_WARNING, "could not compress value");
874-
efree (buffer);
875-
return 0;
876-
}
877-
878-
/* This means the value was too small to be compressed, still a success */
873+
/* This means the value was too small to be compressed and ended up larger */
879874
if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) {
880-
MEMC_VAL_DEL_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ | MEMC_VAL_COMPRESSION_ZLIB);
881-
efree (buffer);
882-
return 1;
875+
compress_status = 0;
883876
}
884877

885-
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED);
878+
/* Replace the payload with the compressed copy */
879+
if (compress_status) {
880+
MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag);
881+
payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0);
886882

887-
payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0);
883+
/* Copy the uin32_t at the beginning */
884+
memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t));
885+
memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size);
886+
efree(buffer);
888887

889-
/* Copy the uin32_t at the beginning */
890-
memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t));
891-
memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size);
892-
efree(buffer);
888+
zend_string_forget_hash_val(payload);
889+
*payload_in = payload;
893890

894-
zend_string_forget_hash_val(payload);
895-
*payload_in = payload;
896-
return 1;
891+
return 1;
892+
}
893+
894+
/* Original payload was not modified */
895+
return 0;
897896
}
898897

899898
static
@@ -1043,11 +1042,13 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t
10431042

10441043
/* If we have compression flag, compress the value */
10451044
if (should_compress) {
1046-
/* status */
1047-
if (!s_compress_value (memc_user_data->compression_type, &payload, flags)) {
1048-
zend_string_release(payload);
1049-
return NULL;
1050-
}
1045+
/* s_compress_value() will always leave a valid payload, even if that payload
1046+
* did not actually get compressed. The flags will be set according to the
1047+
* to the compression type or no compression.
1048+
*
1049+
* No need to check the return value because the payload is always valid.
1050+
*/
1051+
(void)s_compress_value (memc_user_data->compression_type, &payload, flags);
10511052
}
10521053

10531054
if (memc_user_data->set_udf_flags >= 0) {

Diff for: tests/compression_conditions.phpt

-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ bool(true)
8080
len=[4877] set=[] factor=[1.3] threshold=[4]
8181
bool(true)
8282
len=[7] set=[zlib] factor=[1.3] threshold=[4]
83-
Memcached::set(): could not compress value
8483
bool(true)
8584
len=[7] set=[fastlz] factor=[1.3] threshold=[4]
8685
bool(true)
@@ -93,7 +92,6 @@ bool(true)
9392
len=[4877] set=[] factor=[0.3] threshold=[4]
9493
bool(true)
9594
len=[7] set=[zlib] factor=[0.3] threshold=[4]
96-
Memcached::set(): could not compress value
9795
bool(true)
9896
len=[7] set=[fastlz] factor=[0.3] threshold=[4]
9997
bool(true)

0 commit comments

Comments
 (0)