From 8901ef9490fdbdaa87d301f39741b0903fcaa8c2 Mon Sep 17 00:00:00 2001 From: Alexander Vlasov Date: Mon, 17 Apr 2017 16:05:41 +0300 Subject: [PATCH] BR-4992: Shadow memory leaks on PHP 7 --- shadow.c | 12 ++++++++++-- shadow_cache.c | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/shadow.c b/shadow.c index 6dd98a2..cc3c896 100644 --- a/shadow.c +++ b/shadow.c @@ -113,8 +113,8 @@ const zend_function_entry shadow_functions[] = { static PHP_GINIT_FUNCTION(shadow) { memset(shadow_globals, 0, sizeof(zend_shadow_globals)); - zend_hash_init(&shadow_globals->cache, 10, NULL, NULL, 1); // persistent! - zend_hash_init(&shadow_globals->replaced_function_table, 10, NULL, NULL, 1); + zend_hash_init(&shadow_globals->cache, 10, NULL, ZVAL_PTR_DTOR, 1); // persistent! + zend_hash_init(&shadow_globals->replaced_function_table, 10, NULL, ZVAL_PTR_DTOR, 1); // initial size 10 here is a common sense - look at the number of overriden functions } /* }}} */ @@ -123,6 +123,8 @@ static PHP_GINIT_FUNCTION(shadow) */ static PHP_GSHUTDOWN_FUNCTION(shadow) { + shadow_cache_clean(TSRMLS_C); + zend_hash_clean(&shadow_globals->replaced_function_table); zend_hash_destroy(&shadow_globals->replaced_function_table); zend_hash_destroy(&shadow_globals->cache); } @@ -544,6 +546,9 @@ static int is_instance_only(const char *filename TSRMLS_DC) } return result; } + if (realpath) { + efree(realpath); + } return 0; } @@ -754,6 +759,7 @@ zend_string *shadow_resolve_path(const char *filename, int filename_len) // in any case we have to call original resolver because that can be reimplemented by opcache for example if (shadow_result) { result = original_zend_resolve_path(shadow_result, strlen(shadow_result)); + efree(shadow_result); } else { result = original_zend_resolve_path(filename, filename_len); } @@ -1440,6 +1446,7 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS) efree(mergepath); } ZEND_HASH_FOREACH_END(); } + zval_dtor(return_value); return_value = &templdata; /* convert mergedata to return */ zend_hash_clean(Z_ARRVAL_P(return_value)); @@ -1448,6 +1455,7 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS) add_next_index_str(return_value, zend_string_copy(filename_zs)); } ZEND_HASH_FOREACH_END(); /* cleanup */ + zend_hash_clean(mergedata); zend_hash_destroy(mergedata); efree(mergedata); efree(path); diff --git a/shadow_cache.c b/shadow_cache.c index 4fccc93..8c0d635 100644 --- a/shadow_cache.c +++ b/shadow_cache.c @@ -65,18 +65,18 @@ int shadow_cache_get(const char *name, char **entry TSRMLS_DC) namelen = shadow_cache_segmented_name(&segname, name TSRMLS_CC); zend_string *segname_zs = zend_string_init(segname, namelen, 0); if ((centry = zend_hash_find(&SHADOW_G(cache), segname_zs)) != NULL) { + zend_string_release(segname_zs); + efree(segname); if(Z_STRLEN_P(centry) == 0){ *entry = NULL; return SUCCESS; } *entry = estrdup(Z_STR_P(centry)->val); - efree(segname); - zend_string_release(segname_zs); return SUCCESS; } else { *entry = NULL; + zend_string_release(segname_zs); efree(segname); - zend_string_release(segname_zs); return FAILURE; } }