diff --git a/utils.c b/utils.c index a663ce0..5736527 100644 --- a/utils.c +++ b/utils.c @@ -596,18 +596,63 @@ static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */ /* }}} */ #endif -void xc_copy_zend_constant(zend_constant *c) /* {{{ */ +void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker) /* {{{ */ { + Bucket *p; + void *new_entry; + zend_bool setTargetPointer; + + setTargetPointer = !target->pInternalPointer; + p = source->pListHead; + while (p) { + if (checker(p->pData)) { + if (setTargetPointer && source->pInternalPointer == p) { + target->pInternalPointer = NULL; + } + if (p->nKeyLength) { + zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &new_entry); + } else { + zend_hash_index_update(target, p->h, p->pData, size, &new_entry); + } + if (pCopyConstructor) { + pCopyConstructor(new_entry); + } + } + p = p->pListNext; + } + if (!target->pInternalPointer) { + target->pInternalPointer = target->pListHead; + } +} +/* }}} */ +#ifdef HAVE_XCACHE_CONSTANT +static zend_bool xc_is_internal_zend_constant(zend_constant *c) /* {{{ */ +{ + return (c->flags & CONST_PERSISTENT) ? 1 : 0; +} +/* }}} */ +void xc_zend_constant_ctor(zend_constant *c) /* {{{ */ +{ + assert((c->flags & CONST_PERSISTENT)); #ifdef IS_UNICODE c->name.u = zend_ustrndup(c->name.u, c->name_len - 1); #else c->name = zend_strndup(c->name, c->name_len - 1); #endif - if (!(c->flags & CONST_PERSISTENT)) { - zval_copy_ctor(&c->value); - } } /* }}} */ +void xc_zend_constant_dtor(zend_constant *c) /* {{{ */ +{ + free(ZSTR_U(c->name)); +} +/* }}} */ +void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{{ */ +{ + zend_constant tmp_const; + xc_hash_copy_if(target, source, (copy_ctor_func_t) xc_zend_constant_ctor, (void *) &tmp_const, sizeof(zend_constant), (xc_if_func_t) xc_is_internal_zend_constant); +} +/* }}} */ +#endif xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /* {{{ */ { HashTable *h; @@ -645,9 +690,10 @@ xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) / #ifdef HAVE_XCACHE_CONSTANT h = OG(zend_constants); zend_hash_init_ex(&TG(zend_constants), 20, NULL, h->pDestructor, h->persistent, h->bApplyProtection); + xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table)); { zend_constant tmp_const; - zend_hash_copy(&TG(zend_constants), &XG(internal_constant_table), (copy_ctor_func_t) xc_copy_zend_constant, (void *) &tmp_const, sizeof(tmp_const)); + zend_hash_copy(&TG(zend_constants), &XG(internal_constant_table), (copy_ctor_func_t) xc_zend_constant_ctor, (void *) &tmp_const, sizeof(tmp_const)); } #endif h = OG(function_table); diff --git a/utils.h b/utils.h index 1d721ed..9005692 100644 --- a/utils.h +++ b/utils.h @@ -122,4 +122,12 @@ typedef enum _xc_install_action_t { void xc_zend_class_add_ref(zend_class_entry ZESW(*ce, **ce)); xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC); void xc_sandbox_free(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_DC); -void xc_copy_zend_constant(zend_constant *c); + +typedef zend_bool (*xc_if_func_t)(void *data); + +void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker); +#ifdef HAVE_XCACHE_CONSTANT +void xc_zend_constant_ctor(zend_constant *c); +void xc_zend_constant_dtor(zend_constant *c); +void xc_copy_internal_zend_constants(HashTable *target, HashTable *source); +#endif diff --git a/xcache.c b/xcache.c index 07fa820..2d5461b 100644 --- a/xcache.c +++ b/xcache.c @@ -1853,9 +1853,6 @@ static void xc_request_init(TSRMLS_D) /* {{{ */ int i; if (!XG(internal_table_copied)) { -#ifdef HAVE_XCACHE_CONSTANT - zend_constant tmp_const; -#endif zend_function tmp_func; xc_cest_t tmp_cest; @@ -1866,13 +1863,13 @@ static void xc_request_init(TSRMLS_D) /* {{{ */ zend_hash_destroy(&XG(internal_class_table)); #ifdef HAVE_XCACHE_CONSTANT - zend_hash_init_ex(&XG(internal_constant_table), 20, NULL, NULL, 1, 0); + zend_hash_init_ex(&XG(internal_constant_table), 20, NULL, (dtor_func_t) xc_zend_constant_dtor, 1, 0); #endif zend_hash_init_ex(&XG(internal_function_table), 100, NULL, NULL, 1, 0); zend_hash_init_ex(&XG(internal_class_table), 10, NULL, NULL, 1, 0); #ifdef HAVE_XCACHE_CONSTANT - zend_hash_copy(&XG(internal_constant_table), EG(zend_constants), (copy_ctor_func_t) xc_copy_zend_constant, &tmp_const, sizeof(tmp_const)); + xc_copy_internal_zend_constants(&XG(internal_constant_table), EG(zend_constants)); #endif zend_hash_copy(&XG(internal_function_table), CG(function_table), NULL, &tmp_func, sizeof(tmp_func)); zend_hash_copy(&XG(internal_class_table), CG(class_table), NULL, &tmp_cest, sizeof(tmp_cest)); @@ -1933,7 +1930,7 @@ void xc_init_globals(zend_xcache_globals* xcache_globals TSRMLS_DC) memset(xcache_globals, 0, sizeof(zend_xcache_globals)); #ifdef HAVE_XCACHE_CONSTANT - zend_hash_init_ex(&xcache_globals->internal_constant_table, 1, NULL, NULL, 1, 0); + zend_hash_init_ex(&xcache_globals->internal_constant_table, 1, NULL, (dtor_func_t) xc_zend_constant_dtor, 1, 0); #endif zend_hash_init_ex(&xcache_globals->internal_function_table, 1, NULL, NULL, 1, 0); zend_hash_init_ex(&xcache_globals->internal_class_table, 1, NULL, NULL, 1, 0);