Skip to content

Commit 4766335

Browse files
committed
Various bug fixes
1 parent 241b616 commit 4766335

File tree

4 files changed

+52
-39
lines changed

4 files changed

+52
-39
lines changed

php_libmemcached_compat.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ memcached_st *php_memc_create_str (const char *str, size_t str_len)
4949
}
5050
return memc;
5151
#endif
52-
}
52+
}
53+

php_memcached.c

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ static zend_bool php_memcached_on_new_callback(zval *object, zend_fcall_info *fc
366366
}
367367

368368
/* Call the cb */
369-
ZVAL_COPY_VALUE(&params[0], object);
369+
ZVAL_COPY(&params[0], object);
370370

371371
fci->params = params;
372372
fci->param_count = 2;
@@ -420,7 +420,7 @@ static PHP_METHOD(Memcached, __construct)
420420

421421
is_persistent = 1;
422422
plist_key = zend_string_alloc(sizeof("memcached:id=") + persistent_id->len - 1, 0);
423-
snprintf(plist_key->val, plist_key->len+1, "memcached:id=%s", persistent_id->val);
423+
snprintf(plist_key->val, plist_key->len + 1, "memcached:id=%s", persistent_id->val);
424424
if ((le = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) {
425425
if (le->type == php_memc_list_entry()) {
426426
m_obj = (struct memc_obj *) le->ptr;
@@ -500,7 +500,8 @@ static PHP_METHOD(Memcached, __construct)
500500
le.type = php_memc_list_entry();
501501
le.ptr = m_obj;
502502
GC_REFCOUNT(&le) = 1;
503-
if (zend_hash_update_mem(&EG(persistent_list), plist_key, &le, sizeof(le)) == NULL) {
503+
/* plist_key is not a persistent allocated key, thus we use str_update here */
504+
if (zend_hash_str_update_mem(&EG(persistent_list), plist_key->val, plist_key->len, &le, sizeof(le)) == NULL) {
504505
if (plist_key) {
505506
zend_string_release(plist_key);
506507
}
@@ -580,7 +581,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
580581
/*
581582
* Enable CAS support, but only if it is currently disabled.
582583
*/
583-
if (cas_token && Z_IS_REF(cas_token) && orig_cas_flag == 0) {
584+
if (cas_token && Z_ISREF_P(cas_token) && orig_cas_flag == 0) {
584585
memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
585586
}
586587

@@ -589,7 +590,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
589590
} else {
590591
status = memcached_mget(m_obj->memc, keys, key_lens, 1);
591592
}
592-
if (cas_token && Z_IS_REF(cas_token) && orig_cas_flag == 0) {
593+
if (cas_token && Z_ISREF_P(cas_token) && orig_cas_flag == 0) {
593594
memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag);
594595
}
595596

@@ -760,7 +761,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
760761
/*
761762
* Enable CAS support, but only if it is currently disabled.
762763
*/
763-
if (cas_tokens && Z_IS_REF(cas_tokens)) {
764+
if (cas_tokens && Z_ISREF_P(cas_tokens)) {
764765
orig_cas_flag = memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS);
765766
if (orig_cas_flag == 0) {
766767
memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
@@ -778,7 +779,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
778779
/*
779780
* Restore the CAS support flag, but only if we had to turn it on.
780781
*/
781-
if (cas_tokens && Z_IS_REF(cas_tokens) && orig_cas_flag == 0) {
782+
if (cas_tokens && Z_ISREF_P(cas_tokens) && orig_cas_flag == 0) {
782783
memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag);
783784
}
784785

@@ -790,7 +791,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
790791
* returned as doubles, because we cannot store potential 64-bit values in longs.
791792
*/
792793
if (cas_tokens) {
793-
if (Z_IS_REF(cas_tokens)) {
794+
if (Z_ISREF_P(cas_tokens)) {
794795
/* cas_tokens was passed by reference, we'll create an array for it. */
795796
ZVAL_DEREF(cas_tokens);
796797
SEPARATE_ZVAL(cas_tokens);
@@ -853,13 +854,13 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
853854
continue;
854855
}
855856

856-
add_assoc_zval_ex(return_value, res_key, res_key_len+1, &value);
857+
add_assoc_zval_ex(return_value, res_key, res_key_len, &value);
857858
if (cas_tokens) {
858859
cas = memcached_result_cas(&result);
859-
add_assoc_double_ex(cas_tokens, res_key, res_key_len+1, (double)cas);
860+
add_assoc_double_ex(cas_tokens, res_key, res_key_len, (double)cas);
860861
}
861862
if (udf_flags) {
862-
add_assoc_long_ex(udf_flags, res_key, res_key_len+1, MEMC_VAL_GET_USER_FLAGS(flags));
863+
add_assoc_long_ex(udf_flags, res_key, res_key_len, MEMC_VAL_GET_USER_FLAGS(flags));
863864
}
864865
}
865866

@@ -946,7 +947,7 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_
946947
convert_to_string_ex(entry);
947948
}
948949

949-
if (Z_TYPE_PP(entry) == IS_STRING && Z_STRLEN_PP(entry) > 0) {
950+
if (Z_TYPE_P(entry) == IS_STRING && Z_STRLEN_P(entry) > 0) {
950951
mkeys[i] = Z_STRVAL_P(entry);
951952
mkeys_len[i] = Z_STRLEN_P(entry);
952953
i++;
@@ -1227,7 +1228,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
12271228
time_t expiration = 0;
12281229
long udf_flags = 0;
12291230
zval *entry;
1230-
zend_string *str_key = NULL;
1231+
zend_string *skey, *str_key = NULL;
12311232
ulong num_key;
12321233
char *payload;
12331234
size_t payload_len;
@@ -1262,9 +1263,9 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
12621263
}
12631264
}
12641265

1265-
ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, str_key, entry) {
1266-
if (str_key) {
1267-
str_key = zend_string_init(str_key->val, str_key->len, 0);
1266+
ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, skey, entry) {
1267+
if (skey) {
1268+
str_key = skey;
12681269
} else if (num_key || num_key == 0) {
12691270
/* Array keys are unsigned, but php integers are signed.
12701271
* Keys must be converted to signed strings that match
@@ -1288,26 +1289,36 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
12881289
payload = php_memc_zval_to_payload(entry, &payload_len, &flags, m_obj->serializer, m_obj->compression_type);
12891290
if (payload == NULL) {
12901291
i_obj->rescode = MEMC_RES_PAYLOAD_FAILURE;
1291-
zend_string_release(str_key);
1292+
if (!skey) {
1293+
zend_string_release(str_key);
1294+
}
12921295
RETURN_FALSE;
12931296
}
12941297

12951298
retry:
12961299
if (!by_key) {
12971300
status = memcached_set(m_obj->memc, str_key->val, str_key->len, payload, payload_len, expiration, flags);
1298-
zend_string_release(str_key);
1301+
if (!skey) {
1302+
zend_string_release(str_key);
1303+
}
12991304
} else {
13001305
status = memcached_set_by_key(m_obj->memc, server_key->val, server_key->len, str_key->val, str_key->len, payload, payload_len, expiration, flags);
1301-
zend_string_release(str_key);
1306+
if (!skey) {
1307+
zend_string_release(str_key);
1308+
}
13021309
}
13031310

13041311
if (php_memc_handle_error(i_obj, status) < 0) {
13051312
PHP_MEMC_FAILOVER_RETRY
1306-
zend_string_release(str_key);
1313+
if (!skey) {
1314+
zend_string_release(str_key);
1315+
}
13071316
efree(payload);
13081317
RETURN_FALSE;
13091318
}
1310-
zend_string_release(str_key);
1319+
if (!skey) {
1320+
zend_string_release(str_key);
1321+
}
13111322
efree(payload);
13121323
} ZEND_HASH_FOREACH_END();
13131324

@@ -2334,7 +2345,7 @@ static PHP_METHOD(Memcached, getOption)
23342345
result = memcached_callback_get(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval);
23352346
if (retval == MEMCACHED_SUCCESS && result) {
23362347
#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX == 0x00049000
2337-
RETURN_STRINGL(result, strlen(result) - 1);
2348+
RETURN_STRINGL(result, strlen(result));
23382349
#else
23392350
RETURN_STRING(result);
23402351
#endif
@@ -2831,7 +2842,6 @@ static void php_memc_free_storage(zend_object *obj)
28312842

28322843
zend_object_std_dtor(&i_obj->zo);
28332844
i_obj->obj = NULL;
2834-
efree(i_obj);
28352845
}
28362846

28372847
zend_object *php_memc_new(zend_class_entry *ce)
@@ -2950,7 +2960,7 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, php_
29502960
add_assoc_long(&entry, "bytes_written", context->stats[context->i].bytes_written);
29512961
add_assoc_stringl(&entry, "version", context->stats[context->i].version, strlen(context->stats[context->i].version));
29522962

2953-
add_assoc_zval_ex(context->return_value, hostport, hostport_len+1, &entry);
2963+
add_assoc_zval_ex(context->return_value, hostport, hostport_len, &entry);
29542964
efree(hostport);
29552965

29562966
/* Increment the server count in our context structure. Failure to do so will cause only the stats for the last server to get displayed. */
@@ -2978,7 +2988,7 @@ static memcached_return php_memc_do_version_callback(const memcached_st *ptr, ph
29782988
instance->micro_version);
29792989
#endif
29802990

2981-
add_assoc_stringl_ex(context->return_value, hostport, hostport_len+1, version, version_len);
2991+
add_assoc_stringl_ex(context->return_value, hostport, hostport_len, version, version_len);
29822992
efree(hostport);
29832993
return MEMCACHED_SUCCESS;
29842994
}
@@ -3210,7 +3220,7 @@ char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags
32103220

32113221
default:
32123222
if (!s_serialize_value (serializer, value, &buf, flags)) {
3213-
smart_str_free (&buf);
3223+
smart_str_free(&buf);
32143224
return NULL;
32153225
}
32163226
pl = buf.s->val;
@@ -3392,12 +3402,7 @@ static int php_memc_zval_from_payload(zval *value, const char *payload_in, size_
33923402

33933403
switch (MEMC_VAL_GET_TYPE(flags)) {
33943404
case MEMC_VAL_IS_STRING:
3395-
if (payload_emalloc) {
3396-
ZVAL_STRINGL(value, pl, payload_len);
3397-
payload_emalloc = 0;
3398-
} else {
3399-
ZVAL_STRINGL(value, pl, payload_len);
3400-
}
3405+
ZVAL_STRINGL(value, pl, payload_len);
34013406
break;
34023407

34033408
case MEMC_VAL_IS_LONG:
@@ -3518,6 +3523,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i
35183523
zval params[4];
35193524
zval retval;
35203525
zval z_key;
3526+
zval z_val;
35213527
zval z_expiration;
35223528

35233529
uint32_t flags = 0;
@@ -3527,8 +3533,10 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i
35273533
int result;
35283534

35293535
ZVAL_STR(&z_key, key);
3530-
ZVAL_NULL(value);
3531-
ZVAL_LONG(&z_expiration, 0);
3536+
ZVAL_NULL(&z_val);
3537+
ZVAL_NEW_REF(value, &z_val);
3538+
ZVAL_NEW_REF(&z_expiration, &z_val);
3539+
ZVAL_LONG(Z_REFVAL(z_expiration), 0);
35323540

35333541
ZVAL_COPY(&params[0], zmemc_obj);
35343542
ZVAL_COPY(&params[1], &z_key);
@@ -3540,9 +3548,12 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i
35403548
fci->param_count = 4;
35413549

35423550
result = zend_call_function(fci, fcc);
3551+
ZVAL_UNREF(value);
3552+
ZVAL_UNREF(&z_expiration);
35433553
if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
3544-
i_obj = (php_memc_t *) Z_OBJ_P(zmemc_obj);
3545-
struct memc_obj *m_obj = i_obj->obj;
3554+
struct memc_obj *m_obj;
3555+
i_obj = Z_MEMC_OBJ_P(zmemc_obj)
3556+
m_obj = i_obj->obj;
35463557

35473558
if (zend_is_true(&retval)) {
35483559
time_t expiration;

php_memcached.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "php.h"
2323
#include "main/php_config.h"
24+
#include "Zend/zend_smart_str.h"
2425

2526
#ifdef HAVE_CONFIG_H
2627
# include "config.h"

tests/version.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ echo "OK" . PHP_EOL;
1313
--EXPECTF--
1414
array(1) {
1515
["%s:%d"]=>
16-
string(6) "%d.%d.%d"
16+
string(%d) "%d.%d.%d"
1717
}
18-
OK
18+
OK

0 commit comments

Comments
 (0)