summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 62279287b6..def7d7c465 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1771,7 +1771,7 @@ PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, size_t
Imports variables into symbol table from an array */
PHP_FUNCTION(extract)
{
- zval *var_array, *prefix = NULL;
+ zval *var_array_param, *prefix = NULL;
zend_long extract_type = EXTR_OVERWRITE;
zval *entry;
zend_string *var_name;
@@ -1779,14 +1779,15 @@ PHP_FUNCTION(extract)
int var_exists, count = 0;
int extract_refs = 0;
zend_array *symbol_table;
+ zval var_array;
#ifndef FAST_ZPP
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|lz/", &var_array_param, &extract_type, &prefix) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(1, 3)
- Z_PARAM_ARRAY(var_array)
+ Z_PARAM_ARRAY(var_array_param)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(extract_type)
Z_PARAM_ZVAL_EX(prefix, 0, 1)
@@ -1795,7 +1796,7 @@ PHP_FUNCTION(extract)
extract_refs = (extract_type & EXTR_REFS);
if (extract_refs) {
- SEPARATE_ZVAL(var_array);
+ SEPARATE_ZVAL(var_array_param);
}
extract_type &= 0xff;
@@ -1825,7 +1826,11 @@ PHP_FUNCTION(extract)
}
#endif
- ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(var_array), num_key, var_name, entry) {
+ /* The array might be stored in a local variable that will be overwritten. To avoid losing the
+ * reference in that case we work on a copy. */
+ ZVAL_COPY(&var_array, var_array_param);
+
+ ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL(var_array), num_key, var_name, entry) {
zval final_name;
ZVAL_NULL(&final_name);
@@ -1926,6 +1931,7 @@ PHP_FUNCTION(extract)
}
zval_dtor(&final_name);
} ZEND_HASH_FOREACH_END();
+ zval_ptr_dtor(&var_array);
RETURN_LONG(count);
}
@@ -1938,6 +1944,7 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
ZVAL_DEREF(entry);
if (Z_TYPE_P(entry) == IS_STRING) {
if ((value_ptr = zend_hash_find_ind(eg_active_symbol_table, Z_STR_P(entry))) != NULL) {
+ ZVAL_DEREF(value_ptr);
ZVAL_COPY(&data, value_ptr);
zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
}
@@ -3491,6 +3498,10 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv)
}
}
+ if (prop) {
+ ZVAL_DEREF(prop);
+ }
+
return prop;
}