From 399b86bdcdd67039d271da9bbbe46cebe1749ffe Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Tue, 3 Feb 2015 12:35:55 -0800 Subject: [PATCH 01/11] More tests pass now --- php_memcached.c | 54 ++++++++++++++++++++++++++--------------- php_memcached_session.c | 2 -- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 33570992..58fb66d4 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -536,7 +536,7 @@ PHP_METHOD(Memcached, getByKey) static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zend_string *key; - zend_string *server_key; + zend_string *server_key = NULL; const char *payload = NULL; size_t payload_len = 0; uint32_t flags = 0; @@ -584,8 +584,11 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); } - status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, keys, key_lens, 1); - + if (by_key) { + status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, keys, key_lens, 1); + } else { + status = memcached_mget(m_obj->memc, keys, key_lens, 1); + } if (cas_token && Z_IS_REF(cas_token) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); } @@ -685,7 +688,7 @@ PHP_METHOD(Memcached, getMultiByKey) static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zval *keys = NULL; - zend_string *server_key; + zend_string *server_key = NULL; size_t num_keys = 0; zval *entry = NULL; const char *payload = NULL; @@ -764,7 +767,11 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke } } - status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, mkeys, mkeys_len, i); + if (by_key) { + status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, mkeys, mkeys_len, i); + } else { + status = memcached_mget(m_obj->memc, mkeys, mkeys_len, i); + } /* Handle error, but ignore, there might still be some result */ php_memc_handle_error(i_obj, status); @@ -898,7 +905,7 @@ PHP_METHOD(Memcached, getDelayedByKey) static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zval *keys = NULL; - zend_string *server_key; + zend_string *server_key = NULL; zend_bool with_cas = 0; size_t num_keys = 0; zval *entry = NULL; @@ -967,8 +974,11 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ /* * Issue the request, but collect results only if the result callback is provided. */ - status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, mkeys, mkeys_len, i); - + if (by_key) { + status = memcached_mget_by_key(m_obj->memc, server_key->val, server_key->len, mkeys, mkeys_len, i); + } else { + status = memcached_mget(m_obj->memc, mkeys, mkeys_len, i); + } /* * Restore the CAS support flag, but only if we had to turn it on. */ @@ -1213,7 +1223,7 @@ PHP_METHOD(Memcached, setMultiByKey) static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zval *entries; - zend_string *server_key; + zend_string *server_key = NULL; time_t expiration = 0; long udf_flags = 0; zval *entry; @@ -1373,7 +1383,7 @@ PHP_METHOD(Memcached, replaceByKey) static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key) { zend_string *key; - zend_string *server_key; + zend_string *server_key = NULL; zend_string *s_value; zval s_zvalue; zval *value; @@ -1468,7 +1478,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool retry: switch (op) { case MEMC_OP_SET: - if (!server_key->val) { + if (!server_key) { status = memcached_set(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); } else { status = memcached_set_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1477,7 +1487,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool break; #ifdef HAVE_MEMCACHED_TOUCH case MEMC_OP_TOUCH: - if (!server_key->val) { + if (!server_key) { status = memcached_touch(m_obj->memc, key->val, key->len, expiration); } else { status = memcached_touch_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1486,7 +1496,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool break; #endif case MEMC_OP_ADD: - if (!server_key->val) { + if (!server_key) { status = memcached_add(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); } else { status = memcached_add_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1495,7 +1505,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool break; case MEMC_OP_REPLACE: - if (!server_key->val) { + if (!server_key) { status = memcached_replace(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); } else { status = memcached_replace_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1504,7 +1514,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool break; case MEMC_OP_APPEND: - if (!server_key->val) { + if (!server_key) { status = memcached_append(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); } else { status = memcached_append_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1513,7 +1523,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool break; case MEMC_OP_PREPEND: - if (!server_key->val) { + if (!server_key) { status = memcached_prepend(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); } else { status = memcached_prepend_by_key(m_obj->memc, server_key->val, server_key->len, key->val, @@ -1547,7 +1557,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) double cas_d; uint64_t cas; zend_string *key; - zend_string *server_key; + zend_string *server_key = NULL; zval *value; time_t expiration = 0; long udf_flags = 0; @@ -1689,8 +1699,12 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) RETURN_FALSE; } - status = memcached_delete_by_key(m_obj->memc, server_key->val, server_key->len, key->val, + if (by_key) { + status = memcached_delete_by_key(m_obj->memc, server_key->val, server_key->len, key->val, key->len, expiration); + } else { + status = memcached_delete(m_obj->memc, key->val, key->len, expiration); + } if (php_memc_handle_error(i_obj, status) < 0) { RETURN_FALSE; @@ -1704,7 +1718,7 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zval *entries; - zend_string *server_key; + zend_string *server_key = NULL; time_t expiration = 0; zval *entry; @@ -1755,7 +1769,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by /* {{{ -- php_memc_incdec_impl */ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, zend_bool incr) { - zend_string *key, *server_key; + zend_string *key, *server_key = NULL; long offset = 1; uint64_t value, initial = 0; time_t expiry = 0; diff --git a/php_memcached_session.c b/php_memcached_session.c index 118805aa..1d2dbe32 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -310,7 +310,6 @@ PS_READ_FUNC(memcached) key_length = strlen(MEMC_G(sess_prefix)) + key_len + 5; // prefix + "lock." if (!key_length || key_length >= MEMCACHED_MAX_KEY) { php_error_docref(NULL, E_WARNING, "The session id is too long or contains illegal characters"); - PS(invalid_session_id) = 1; return FAILURE; } @@ -344,7 +343,6 @@ PS_WRITE_FUNC(memcached) key_length = strlen(MEMC_G(sess_prefix)) + key_len + 5; // prefix + "lock." if (!key_length || key_length >= MEMCACHED_MAX_KEY) { php_error_docref(NULL, E_WARNING, "The session id is too long or contains illegal characters"); - PS(invalid_session_id) = 1; return FAILURE; } From 479b6e2ef455e1a2679553a5538ba605f594363b Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Tue, 3 Feb 2015 12:57:34 -0800 Subject: [PATCH 02/11] Fix 4 more tests --- php_memcached.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 58fb66d4..eda04625 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -580,7 +580,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) /* * Enable CAS support, but only if it is currently disabled. */ - if (cas_token && Z_IS_REF(cas_token) && orig_cas_flag == 0) { + if (cas_token && Z_ISREF_P(cas_token) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); } @@ -589,7 +589,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) } else { status = memcached_mget(m_obj->memc, keys, key_lens, 1); } - if (cas_token && Z_IS_REF(cas_token) && orig_cas_flag == 0) { + if (cas_token && Z_ISREF_P(cas_token) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); } @@ -760,7 +760,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke /* * Enable CAS support, but only if it is currently disabled. */ - if (cas_tokens && Z_IS_REF(cas_tokens)) { + if (cas_tokens && Z_ISREF_P(cas_tokens)) { orig_cas_flag = memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS); if (orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); @@ -778,7 +778,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke /* * Restore the CAS support flag, but only if we had to turn it on. */ - if (cas_tokens && Z_IS_REF(cas_tokens) && orig_cas_flag == 0) { + if (cas_tokens && Z_ISREF_P(cas_tokens) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); } @@ -790,7 +790,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke * returned as doubles, because we cannot store potential 64-bit values in longs. */ if (cas_tokens) { - if (Z_IS_REF(cas_tokens)) { + if (Z_ISREF_P(cas_tokens)) { /* cas_tokens was passed by reference, we'll create an array for it. */ ZVAL_DEREF(cas_tokens); SEPARATE_ZVAL(cas_tokens); From 3a93af390d0430dcae00b860b65e8ec5eddf82e9 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Tue, 3 Feb 2015 13:32:52 -0800 Subject: [PATCH 03/11] minor cleanup --- php_memcached.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index eda04625..9e381584 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2861,12 +2861,8 @@ zend_object_value php_memc_server_new(zend_class_entry *ce) zval *tmp; intern = ecalloc(1, sizeof(php_memc_server_t)); - zend_object_std_init (&intern->zo, ce); -#if PHP_VERSION_ID >= 50400 - object_properties_init( (zend_object *) intern, ce); -#else - zend_hash_copy(intern->zo.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); -#endif + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); intern->handler = php_memc_proto_handler_new (); From a3279a8478483f750274bc1e74fe5d1a540aa354 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 17:30:29 +0800 Subject: [PATCH 04/11] Various bug fixes --- php_libmemcached_compat.c | 3 +- php_memcached.c | 73 ++++++++++++++++++++++----------------- php_memcached.h | 1 + tests/version.phpt | 4 +-- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/php_libmemcached_compat.c b/php_libmemcached_compat.c index f238709e..f49b162b 100644 --- a/php_libmemcached_compat.c +++ b/php_libmemcached_compat.c @@ -49,4 +49,5 @@ memcached_st *php_memc_create_str (const char *str, size_t str_len) } return memc; #endif -} \ No newline at end of file +} + diff --git a/php_memcached.c b/php_memcached.c index 9e381584..500110af 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -366,7 +366,7 @@ static zend_bool php_memcached_on_new_callback(zval *object, zend_fcall_info *fc } /* Call the cb */ - ZVAL_COPY_VALUE(¶ms[0], object); + ZVAL_COPY(¶ms[0], object); fci->params = params; fci->param_count = 2; @@ -420,7 +420,7 @@ static PHP_METHOD(Memcached, __construct) is_persistent = 1; plist_key = zend_string_alloc(sizeof("memcached:id=") + persistent_id->len - 1, 0); - snprintf(plist_key->val, plist_key->len+1, "memcached:id=%s", persistent_id->val); + snprintf(plist_key->val, plist_key->len + 1, "memcached:id=%s", persistent_id->val); if ((le = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) { if (le->type == php_memc_list_entry()) { m_obj = (struct memc_obj *) le->ptr; @@ -500,7 +500,8 @@ static PHP_METHOD(Memcached, __construct) le.type = php_memc_list_entry(); le.ptr = m_obj; GC_REFCOUNT(&le) = 1; - if (zend_hash_update_mem(&EG(persistent_list), plist_key, &le, sizeof(le)) == NULL) { + /* plist_key is not a persistent allocated key, thus we use str_update here */ + if (zend_hash_str_update_mem(&EG(persistent_list), plist_key->val, plist_key->len, &le, sizeof(le)) == NULL) { if (plist_key) { zend_string_release(plist_key); } @@ -853,13 +854,13 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke continue; } - add_assoc_zval_ex(return_value, res_key, res_key_len+1, &value); + add_assoc_zval_ex(return_value, res_key, res_key_len, &value); if (cas_tokens) { cas = memcached_result_cas(&result); - add_assoc_double_ex(cas_tokens, res_key, res_key_len+1, (double)cas); + add_assoc_double_ex(cas_tokens, res_key, res_key_len, (double)cas); } if (udf_flags) { - add_assoc_long_ex(udf_flags, res_key, res_key_len+1, MEMC_VAL_GET_USER_FLAGS(flags)); + add_assoc_long_ex(udf_flags, res_key, res_key_len, MEMC_VAL_GET_USER_FLAGS(flags)); } } @@ -946,7 +947,7 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ convert_to_string_ex(entry); } - if (Z_TYPE_PP(entry) == IS_STRING && Z_STRLEN_PP(entry) > 0) { + if (Z_TYPE_P(entry) == IS_STRING && Z_STRLEN_P(entry) > 0) { mkeys[i] = Z_STRVAL_P(entry); mkeys_len[i] = Z_STRLEN_P(entry); i++; @@ -1227,7 +1228,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke time_t expiration = 0; long udf_flags = 0; zval *entry; - zend_string *str_key = NULL; + zend_string *skey, *str_key = NULL; ulong num_key; char *payload; size_t payload_len; @@ -1262,9 +1263,9 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke } } - ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, str_key, entry) { - if (str_key) { - str_key = zend_string_init(str_key->val, str_key->len, 0); + ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, skey, entry) { + if (skey) { + str_key = skey; } else if (num_key || num_key == 0) { /* Array keys are unsigned, but php integers are signed. * 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 payload = php_memc_zval_to_payload(entry, &payload_len, &flags, m_obj->serializer, m_obj->compression_type); if (payload == NULL) { i_obj->rescode = MEMC_RES_PAYLOAD_FAILURE; - zend_string_release(str_key); + if (!skey) { + zend_string_release(str_key); + } RETURN_FALSE; } retry: if (!by_key) { status = memcached_set(m_obj->memc, str_key->val, str_key->len, payload, payload_len, expiration, flags); - zend_string_release(str_key); + if (!skey) { + zend_string_release(str_key); + } } else { 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); - zend_string_release(str_key); + if (!skey) { + zend_string_release(str_key); + } } if (php_memc_handle_error(i_obj, status) < 0) { PHP_MEMC_FAILOVER_RETRY - zend_string_release(str_key); + if (!skey) { + zend_string_release(str_key); + } efree(payload); RETURN_FALSE; } - zend_string_release(str_key); + if (!skey) { + zend_string_release(str_key); + } efree(payload); } ZEND_HASH_FOREACH_END(); @@ -2334,7 +2345,7 @@ static PHP_METHOD(Memcached, getOption) result = memcached_callback_get(m_obj->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); if (retval == MEMCACHED_SUCCESS && result) { #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX == 0x00049000 - RETURN_STRINGL(result, strlen(result) - 1); + RETURN_STRINGL(result, strlen(result)); #else RETURN_STRING(result); #endif @@ -2831,7 +2842,6 @@ static void php_memc_free_storage(zend_object *obj) zend_object_std_dtor(&i_obj->zo); i_obj->obj = NULL; - efree(i_obj); } zend_object *php_memc_new(zend_class_entry *ce) @@ -2946,7 +2956,7 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, php_ add_assoc_long(&entry, "bytes_written", context->stats[context->i].bytes_written); add_assoc_stringl(&entry, "version", context->stats[context->i].version, strlen(context->stats[context->i].version)); - add_assoc_zval_ex(context->return_value, hostport, hostport_len+1, &entry); + add_assoc_zval_ex(context->return_value, hostport, hostport_len, &entry); efree(hostport); /* Increment the server count in our context structure. Failure to do so will cause only the stats for the last server to get displayed. */ @@ -2974,7 +2984,7 @@ static memcached_return php_memc_do_version_callback(const memcached_st *ptr, ph instance->micro_version); #endif - add_assoc_stringl_ex(context->return_value, hostport, hostport_len+1, version, version_len); + add_assoc_stringl_ex(context->return_value, hostport, hostport_len, version, version_len); efree(hostport); return MEMCACHED_SUCCESS; } @@ -3206,7 +3216,7 @@ char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags default: if (!s_serialize_value (serializer, value, &buf, flags)) { - smart_str_free (&buf); + smart_str_free(&buf); return NULL; } pl = buf.s->val; @@ -3388,12 +3398,7 @@ static int php_memc_zval_from_payload(zval *value, const char *payload_in, size_ switch (MEMC_VAL_GET_TYPE(flags)) { case MEMC_VAL_IS_STRING: - if (payload_emalloc) { - ZVAL_STRINGL(value, pl, payload_len); - payload_emalloc = 0; - } else { - ZVAL_STRINGL(value, pl, payload_len); - } + ZVAL_STRINGL(value, pl, payload_len); break; case MEMC_VAL_IS_LONG: @@ -3514,6 +3519,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i zval params[4]; zval retval; zval z_key; + zval z_val; zval z_expiration; uint32_t flags = 0; @@ -3523,8 +3529,10 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i int result; ZVAL_STR(&z_key, key); - ZVAL_NULL(value); - ZVAL_LONG(&z_expiration, 0); + ZVAL_NULL(&z_val); + ZVAL_NEW_REF(value, &z_val); + ZVAL_NEW_REF(&z_expiration, &z_val); + ZVAL_LONG(Z_REFVAL(z_expiration), 0); ZVAL_COPY(¶ms[0], zmemc_obj); ZVAL_COPY(¶ms[1], &z_key); @@ -3536,9 +3544,12 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i fci->param_count = 4; result = zend_call_function(fci, fcc); + ZVAL_UNREF(value); + ZVAL_UNREF(&z_expiration); if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - i_obj = (php_memc_t *) Z_OBJ_P(zmemc_obj); - struct memc_obj *m_obj = i_obj->obj; + struct memc_obj *m_obj; + i_obj = Z_MEMC_OBJ_P(zmemc_obj) + m_obj = i_obj->obj; if (zend_is_true(&retval)) { time_t expiration; diff --git a/php_memcached.h b/php_memcached.h index da4d6b92..2ce8e730 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -21,6 +21,7 @@ #include "php.h" #include "main/php_config.h" +#include "Zend/zend_smart_str.h" #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/tests/version.phpt b/tests/version.phpt index f9adcc52..8ffe275a 100644 --- a/tests/version.phpt +++ b/tests/version.phpt @@ -13,6 +13,6 @@ echo "OK" . PHP_EOL; --EXPECTF-- array(1) { ["%s:%d"]=> - string(6) "%d.%d.%d" + string(%d) "%d.%d.%d" } -OK \ No newline at end of file +OK From 35a543f0cb7a9825b8b19ddcf2ff44435a208355 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 17:48:36 +0800 Subject: [PATCH 05/11] Fixed memory leak --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 500110af..be745c26 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1699,7 +1699,7 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &key, &expiration) == FAILURE) { return; } - server_key = zend_string_copy(key); + server_key = key; } MEMC_METHOD_FETCH_OBJECT; From cbcbece3619bd067d64094cc04f7d6a676a28b66 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 17:54:26 +0800 Subject: [PATCH 06/11] Fixed getStat --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index be745c26..6a9776ab 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2927,7 +2927,7 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, php_ int hostport_len; struct callbackContext* context = (struct callbackContext*) in_context; zval entry; - hostport_len = spprintf(&hostport, 0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance) - 1); + hostport_len = spprintf(&hostport, 0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); array_init(&entry); From 6851bdd95f2a0f776fc55b4be8a43e2993a1268e Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 18:01:11 +0800 Subject: [PATCH 07/11] Fixed memory leak --- php_memcached.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 6a9776ab..99eed2f1 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2548,16 +2548,9 @@ uint32_t *s_zval_to_uint32_array (zval *input, size_t *num_elements) if (Z_TYPE_P(pzval) == IS_LONG) { value = Z_LVAL_P(pzval); - } - else { - zval *tmp_zval, *tmp_pzval; - tmp_zval = pzval; - zval_copy_ctor(tmp_zval); - tmp_pzval = tmp_zval; - convert_to_long(tmp_pzval); - - value = (Z_LVAL_P(tmp_pzval) > 0) ? Z_LVAL_P(tmp_pzval) : 0; - zval_dtor(tmp_pzval); + } else { + value = zval_get_long(pzval); + value = value > 0? value : 0; } if (value < 0) { From 229c6842225876c8f8bfca8706616db516451bc8 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 18:34:34 +0800 Subject: [PATCH 08/11] Better implementation --- php_memcached.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 99eed2f1..ef49c8ec 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3513,7 +3513,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i zval retval; zval z_key; zval z_val; - zval z_expiration; + zval *expiration, z_expiration; uint32_t flags = 0; memcached_return rc; @@ -3523,41 +3523,37 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i ZVAL_STR(&z_key, key); ZVAL_NULL(&z_val); - ZVAL_NEW_REF(value, &z_val); - ZVAL_NEW_REF(&z_expiration, &z_val); + ZVAL_NEW_REF(&z_val, value); + ZVAL_NEW_REF(&z_expiration, value); ZVAL_LONG(Z_REFVAL(z_expiration), 0); ZVAL_COPY(¶ms[0], zmemc_obj); ZVAL_COPY(¶ms[1], &z_key); - ZVAL_COPY(¶ms[2], value); - ZVAL_COPY(¶ms[3], &z_expiration); + ZVAL_COPY_VALUE(¶ms[2], &z_val); + ZVAL_COPY_VALUE(¶ms[3], &z_expiration); fci->retval = &retval; fci->params = params; fci->param_count = 4; result = zend_call_function(fci, fcc); - ZVAL_UNREF(value); - ZVAL_UNREF(&z_expiration); + ZVAL_DUP(value, Z_REFVAL(z_val)); + expiration = Z_REFVAL(z_expiration); if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { struct memc_obj *m_obj; i_obj = Z_MEMC_OBJ_P(zmemc_obj) m_obj = i_obj->obj; if (zend_is_true(&retval)) { - time_t expiration; + time_t expir; - if (Z_TYPE(z_expiration) != IS_LONG) { - convert_to_long(&z_expiration); - } - - expiration = Z_LVAL(z_expiration); + expir = zval_get_long(expiration); payload = php_memc_zval_to_payload(value, &payload_len, &flags, m_obj->serializer, m_obj->compression_type); if (payload == NULL) { status = (memcached_return)MEMC_RES_PAYLOAD_FAILURE; } else { - rc = memcached_set(m_obj->memc, key->val, key->len, payload, payload_len, expiration, flags); + rc = memcached_set(m_obj->memc, key->val, key->len, payload, payload_len, expir, flags); if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED) { status = rc; } @@ -3571,8 +3567,6 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i } else { if (result == FAILURE) { - zval_ptr_dtor(&z_key); - zval_ptr_dtor(&z_expiration); php_error_docref(NULL, E_WARNING, "could not invoke cache callback"); } status = MEMCACHED_FAILURE; @@ -3585,6 +3579,7 @@ static memcached_return php_memc_do_cache_callback(zval *zmemc_obj, zend_fcall_i } zval_ptr_dtor(&z_key); + zval_ptr_dtor(&z_val); zval_ptr_dtor(&z_expiration); return status; From 1b2c2251f954d785c6ef9e05a8153eba69b96573 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 4 Feb 2015 20:52:34 +0800 Subject: [PATCH 09/11] Fixed memleak, and use the recently added object_size api --- php_memcached.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index ef49c8ec..3a25a1a6 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -546,6 +546,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) size_t key_lens[1] = { 0 }; zval *cas_token = NULL; zval *udf_flags = NULL; + uint64_t orig_cas_flag; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; memcached_result_st result; @@ -575,7 +576,6 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) keys[0] = key->val; key_lens[0] = key->len; - uint64_t orig_cas_flag; orig_cas_flag = memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS); /* @@ -612,6 +612,8 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) * ourselves. */ if (cas_token) { + ZVAL_DEREF(cas_token); + zval_ptr_dtor(cas_token); ZVAL_DOUBLE(cas_token, 0.0); } @@ -653,8 +655,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) if (cas_token) { ZVAL_DEREF(cas_token); - SEPARATE_ZVAL(cas_token); - zval_dtor(cas_token); + zval_ptr_dtor(cas_token); ZVAL_DOUBLE(cas_token, (double)cas); } @@ -2839,7 +2840,7 @@ static void php_memc_free_storage(zend_object *obj) zend_object *php_memc_new(zend_class_entry *ce) { - php_memc_t *i_obj = ecalloc(1, sizeof(php_memc_t) + sizeof(zval) * (ce->default_properties_count - 1)); + php_memc_t *i_obj = ecalloc(1, sizeof(php_memc_t) + zend_object_properties_size(ce)); zend_object_std_init(&i_obj->zo, ce); object_properties_init(&i_obj->zo, ce); From e4f8f395f979a80e52ed04b32e6ce62eb2c9b298 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Wed, 4 Feb 2015 08:16:57 -0800 Subject: [PATCH 10/11] Down to 18 failed tests now --- php_memcached.h | 1 - 1 file changed, 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 2ce8e730..da4d6b92 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -21,7 +21,6 @@ #include "php.h" #include "main/php_config.h" -#include "Zend/zend_smart_str.h" #ifdef HAVE_CONFIG_H # include "config.h" From 1bb38ab0f7f58d2a7e91b90769e427a5066db4db Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Wed, 4 Feb 2015 09:37:06 -0800 Subject: [PATCH 11/11] Oops, need this for the inline stuff --- php_memcached.h | 1 + 1 file changed, 1 insertion(+) diff --git a/php_memcached.h b/php_memcached.h index da4d6b92..b96ef37a 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -20,6 +20,7 @@ #define PHP_MEMCACHED_H #include "php.h" +#include "Zend/zend_smart_str.h" #include "main/php_config.h" #ifdef HAVE_CONFIG_H