From 32350801185684abc5028e30574b4d95ea255b70 Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sun, 27 Oct 2013 17:46:35 +0200 Subject: [PATCH 1/3] Test case for #1455 --- ext/tests/issue-1455.phpt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 ext/tests/issue-1455.phpt diff --git a/ext/tests/issue-1455.phpt b/ext/tests/issue-1455.phpt new file mode 100644 index 00000000000..b829e1f27ec --- /dev/null +++ b/ext/tests/issue-1455.phpt @@ -0,0 +1,21 @@ +--TEST-- +Memory leak in Phalcon\Cache\Backend\Apc::flush() - https://github.com/phalcon/cphalcon/issues/1455 +--INI-- +report_memleaks=1 +--SKIPIF-- + +--FILE-- + 600)); +$cache = new \Phalcon\Cache\Backend\Apc($front, array('prefix' => 'prefix_')); + +$cache->save('foo', 1); +$cache->save('bar', 1); +$cache->flush(); +?> +--EXPECT-- From 245b817c3ddc7c71423e24f3c6be4b77b5918e37 Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sun, 27 Oct 2013 17:46:47 +0200 Subject: [PATCH 2/3] Fix #1455 --- ext/cache/backend/apc.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ext/cache/backend/apc.c b/ext/cache/backend/apc.c index 900b27bf768..f4383217deb 100644 --- a/ext/cache/backend/apc.c +++ b/ext/cache/backend/apc.c @@ -512,20 +512,17 @@ PHP_METHOD(Phalcon_Cache_Backend_Apc, flush){ PHALCON_MM_GROW(); - PHALCON_INIT_VAR(prefix_pattern); + PHALCON_INIT_VAR(prefix_pattern); ZVAL_STRING(prefix_pattern, "/^_PHCA/", 1); - array_init(return_value); - - PHALCON_INIT_VAR(type); - ZVAL_STRING(type, "user", 1); - apciterator_ce = zend_fetch_class(SL("APCIterator"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); PHALCON_INIT_VAR(iterator); object_init_ex(iterator, apciterator_ce); assert(phalcon_has_constructor(iterator TSRMLS_CC)); if (!phalcon_cache_backend_is_apcu) { + PHALCON_ALLOC_GHOST_ZVAL(type); + ZVAL_STRING(type, "user", 1); phalcon_call_method_p2_noret(iterator, "__construct", type, prefix_pattern); } else { @@ -552,21 +549,23 @@ PHP_METHOD(Phalcon_Cache_Backend_Apc, flush){ #if PHP_VERSION_ID < 50500 key_type = it->funcs->get_current_key(it, &str_key, &str_key_len, &int_key TSRMLS_CC); if (likely(key_type == HASH_KEY_IS_STRING)) { - /** - * Note that str_key_len includes the trailing zero. - * Remove the _PHCA prefix. - */ ZVAL_STRINGL(key, str_key, str_key_len - 1, 1); efree(str_key); - phalcon_call_func_p1_noret("apc_delete", key); + phalcon_call_func_params(NULL, NULL, SL("apc_delete") TSRMLS_CC, 1, key); + if (unlikely(EG(exception) != NULL)) { + break; + } } #else PHALCON_INIT_NVAR(itkey); it->funcs->get_current_key(it, itkey TSRMLS_CC); if (likely(Z_TYPE_P(itkey) == IS_STRING)) { ZVAL_STRINGL(key, Z_STRVAL_P(itkey), Z_STRLEN_P(itkey), 1); - phalcon_call_func_p1_noret("apc_delete", key); + phalcon_call_func_params(NULL, NULL, SL("apc_delete") TSRMLS_CC, 1, key); + if (unlikely(EG(exception) != NULL)) { + break; + } } #endif From 5fc474ab74dca87ea4d18bb242eaab24ab5add50 Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sun, 27 Oct 2013 17:50:27 +0200 Subject: [PATCH 3/3] Safer queryKeys() --- ext/cache/backend/apc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/cache/backend/apc.c b/ext/cache/backend/apc.c index f4383217deb..7407e3a6576 100644 --- a/ext/cache/backend/apc.c +++ b/ext/cache/backend/apc.c @@ -393,15 +393,14 @@ PHP_METHOD(Phalcon_Cache_Backend_Apc, queryKeys){ array_init(return_value); - PHALCON_INIT_VAR(type); - ZVAL_STRING(type, "user", 1); - apciterator_ce = zend_fetch_class(SL("APCIterator"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); PHALCON_INIT_VAR(iterator); object_init_ex(iterator, apciterator_ce); assert(phalcon_has_constructor(iterator TSRMLS_CC)); if (!phalcon_cache_backend_is_apcu) { + PHALCON_ALLOC_GHOST_ZVAL(type); + ZVAL_STRING(type, "user", 1); phalcon_call_method_p2_noret(iterator, "__construct", type, prefix_pattern); } else { @@ -423,7 +422,7 @@ PHP_METHOD(Phalcon_Cache_Backend_Apc, queryKeys){ assert(it->funcs->rewind != NULL); it->funcs->rewind(it TSRMLS_CC); - while (it->funcs->valid(it TSRMLS_CC) == SUCCESS) { + while (it->funcs->valid(it TSRMLS_CC) == SUCCESS && !EG(exception)) { PHALCON_INIT_NVAR(key); #if PHP_VERSION_ID < 50500 key_type = it->funcs->get_current_key(it, &str_key, &str_key_len, &int_key TSRMLS_CC);