From 57ae19a0b79f2f470b76963e43cd32366811bb7c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 16:57:48 +0800 Subject: Checkout refcounted before doing addref --- ext/standard/array.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index 0535e57849..459ea531f8 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2591,18 +2591,20 @@ PHP_FUNCTION(array_column) zkeyval = zend_hash_index_find(ht, Z_LVAL_P(zkey)); } - Z_ADDREF_P(zcolval); if (zkeyval && Z_TYPE_P(zkeyval) == IS_STRING) { -//??? + Z_ADDREF_P(zcolval); add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval); } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_LONG) { add_index_zval(return_value, Z_LVAL_P(zkeyval), zcolval); } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_OBJECT) { + Z_ADDREF_P(zcolval); SEPARATE_ZVAL(zkeyval); convert_to_string(zkeyval); -//??? add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval); } else { + if (Z_REFCOUNTED_P(zcolval)) { + Z_ADDREF_P(zcolval); + } add_next_index_zval(return_value, zcolval); } } @@ -2785,7 +2787,7 @@ PHP_FUNCTION(array_change_key_case) php_strtolower(new_key->val, new_key->len); } zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); - STR_FREE(new_key); + STR_RELEASE(new_key); break; } @@ -2990,7 +2992,9 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa } } if (ok) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED(p->val)) { + Z_ADDREF(p->val); + } zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val); } } else { @@ -3005,7 +3009,9 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa } } if (ok) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED(p->val)) { + Z_ADDREF(p->val); + } zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val); } } @@ -3409,7 +3415,9 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty } } if (ok) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED(p->val)) { + Z_ADDREF(p->val); + } zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val); } } else { @@ -3424,7 +3432,9 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty } } if (ok) { - Z_ADDREF(p->val); + if (Z_REFCOUNTED(p->val)) { + Z_ADDREF(p->val); + } zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val); } } -- cgit v1.2.1 From 2ee6bc1309d43539a90cabb9d82b3f7e2698a7f2 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 17:07:09 +0800 Subject: Remove "efree(args") --- ext/standard/array.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index 459ea531f8..40371d2310 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2970,8 +2970,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa for (i = 0; i < argc; i++) { if (Z_TYPE(args[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1); - RETVAL_NULL(); - goto out; + RETURN_NULL(); } } @@ -3016,8 +3015,6 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa } } } -out: - efree(args); } /* }}} */ @@ -3805,7 +3802,6 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC) /* {{{ for (k = 0; k < MULTISORT_LAST; k++) \ efree(ARRAYG(multisort_flags)[k]); \ efree(arrays); \ - efree(args); \ RETURN_FALSE; /* {{{ proto bool array_multisort(array ar1 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_FLAG_CASE]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_FLAG_CASE]], ...]) @@ -4297,7 +4293,6 @@ PHP_FUNCTION(array_map) for (i = 0; i < n_arrays; i++) { if (Z_TYPE(arrays[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d should be an array", i + 2); - efree(args); efree(array_len); efree(array_pos); return; @@ -4317,7 +4312,6 @@ PHP_FUNCTION(array_map) RETVAL_ZVAL(args[0], 1, 0); efree(array_len); efree(array_pos); - efree(args); return; } @@ -4369,7 +4363,6 @@ PHP_FUNCTION(array_map) if (zend_call_function(&fci, &fci_cache TSRMLS_CC) != SUCCESS || Z_TYPE(result) == IS_UNDEF) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the map callback"); efree(array_len); - efree(args); efree(array_pos); zval_dtor(return_value); efree(params); @@ -4392,7 +4385,6 @@ PHP_FUNCTION(array_map) efree(params); efree(array_len); efree(array_pos); - efree(args); } /* }}} */ -- cgit v1.2.1 From 75d567ef9a2a02e11bb64a73f928caaa52ca153c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 17:31:10 +0800 Subject: Fixed NULL pointer def in ext/standard/tests/array/array_fill_keys_variation2.php --- ext/standard/array.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index 40371d2310..cad4cc8d8e 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1525,6 +1525,10 @@ PHP_FUNCTION(array_fill_keys) zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos); while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), &pos)) != NULL) { + if (UNEXPECTED(Z_ISREF_P(entry))) { + entry = Z_REFVAL_P(entry); + } + if (Z_TYPE_P(entry) == IS_LONG) { zval_add_ref(val); zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val); -- cgit v1.2.1 From 0791bdb562afe0e8864ef44bb0d085eabe1dce07 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 17:53:01 +0800 Subject: retval might be IS_UNDEF even the call is successed --- ext/standard/array.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index cad4cc8d8e..98535e9fee 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4178,7 +4178,6 @@ PHP_FUNCTION(array_filter) zval *operand; zval args[2]; zval retval; -//??? zval *key = NULL; zend_bool have_callback = 0; long use_type = 0; zend_string *string_key; @@ -4200,16 +4199,7 @@ PHP_FUNCTION(array_filter) have_callback = 1; fci.no_separation = 0; fci.retval = &retval; - - if (use_type == ARRAY_FILTER_USE_BOTH) { - fci.param_count = 2; -//??? args[1] = &key; - } else { - fci.param_count = 1; - if (use_type == ARRAY_FILTER_USE_KEY) { -//??? args[0] = &key; - } - } + fci.param_count = 1; } for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); @@ -4223,28 +4213,40 @@ PHP_FUNCTION(array_filter) /* Set up the key */ switch (key_type) { case HASH_KEY_IS_LONG: - ZVAL_LONG(&args[0], num_key); + if (use_type == ARRAY_FILTER_USE_BOTH) { + fci.param_count = 2; + ZVAL_LONG(&args[1], num_key); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_LONG(&args[0], num_key); + } break; case HASH_KEY_IS_STRING: - ZVAL_STR(&args[0], STR_COPY(string_key)); + if (use_type == ARRAY_FILTER_USE_BOTH) { + ZVAL_STR(&args[1], STR_COPY(string_key)); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_STR(&args[0], STR_COPY(string_key)); + } break; } } - if (use_type != ARRAY_FILTER_USE_KEY) { ZVAL_COPY_VALUE(&args[0], operand); } fci.params = args; - if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { - int retval_true = zend_is_true(&retval TSRMLS_CC); + if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) { + if (!ZVAL_IS_UNDEF(&retval)) { + int retval_true = zend_is_true(&retval TSRMLS_CC); - zval_ptr_dtor(&retval); - if (use_type) { - zval_ptr_dtor(&args[0]); - } - if (!retval_true) { + zval_ptr_dtor(&retval); + if (use_type) { + zval_ptr_dtor(&args[0]); + } + if (!retval_true) { + continue; + } + } else { continue; } } else { -- cgit v1.2.1 From bfaa9669a6bed7eeb45873ee568c0e8aa64e2409 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 17:58:46 +0800 Subject: Fixed refcounted --- ext/standard/array.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index 98535e9fee..e59eb847fd 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1820,7 +1820,9 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval *l pos++; /* Get entry and increase reference count */ entry = &p->val; - Z_ADDREF_P(entry); + if (Z_REFCOUNTED_P(entry)) { + Z_ADDREF_P(entry); + } /* Update output hash depending on key type */ if (p->key == NULL) { @@ -1837,7 +1839,9 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval *l if (Z_TYPE(p->val) == IS_UNDEF) continue; pos++; entry = &p->val; - Z_ADDREF_P(entry); + if (Z_REFCOUNTED_P(entry)) { + Z_ADDREF_P(entry); + } if (p->key == NULL) { zend_hash_next_index_insert(removed, entry); } else { @@ -1863,7 +1867,9 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval *l p = in_hash->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; entry = &p->val; - if (IS_REFCOUNTED(Z_TYPE_P(entry))) Z_ADDREF_P(entry); + if (Z_REFCOUNTED_P(entry)) { + Z_ADDREF_P(entry); + } if (p->key == NULL) { zend_hash_next_index_insert(out_hash, entry); } else { @@ -2288,7 +2294,9 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC (dest_entry = zend_hash_find(dest, string_key)) == NULL || Z_TYPE_P(dest_entry) != IS_ARRAY) { - Z_ADDREF_P(src_entry); + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } zend_hash_update(dest, string_key, src_entry); continue; @@ -2300,7 +2308,9 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC (dest_entry = zend_hash_index_find(dest, num_key)) == NULL || Z_TYPE_P(dest_entry) != IS_ARRAY) { - Z_ADDREF_P(src_entry); + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } zend_hash_index_update(dest, num_key, src_entry); continue; -- cgit v1.2.1 From 74c2deecd8a7854e4cb12ab3e48379cde2c0b19c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 18:11:22 +0800 Subject: Fixed refcounted --- ext/standard/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index 90bbdc03ee..aefaef1d87 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1392,7 +1392,7 @@ PHP_FUNCTION(extract) } } else { ZVAL_DUP(&data, entry); - ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, &data, 1, 0); + ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name), &data, 1, 0); } count++; } -- cgit v1.2.1 From 70b788771243a13bcbdbc930137ae4fd6b446742 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 5 Mar 2014 18:17:16 +0800 Subject: Fixed refcounted handling --- ext/standard/array.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'ext/standard/array.c') diff --git a/ext/standard/array.c b/ext/standard/array.c index aefaef1d87..9c741ed613 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -411,6 +411,15 @@ static int php_array_natural_general_compare(const void *a, const void *b, int f fval = &f->val; sval = &s->val; + + if (Z_ISREF_P(fval)) { + fval = Z_REFVAL_P(fval); + } + + if (Z_ISREF_P(sval)) { + sval = Z_REFVAL_P(sval); + } + ZVAL_COPY_VALUE(&first, fval); ZVAL_COPY_VALUE(&second, sval); @@ -2605,20 +2614,18 @@ PHP_FUNCTION(array_column) zkeyval = zend_hash_index_find(ht, Z_LVAL_P(zkey)); } - if (zkeyval && Z_TYPE_P(zkeyval) == IS_STRING) { + if (Z_REFCOUNTED_P(zcolval)) { Z_ADDREF_P(zcolval); + } + if (zkeyval && Z_TYPE_P(zkeyval) == IS_STRING) { add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval); } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_LONG) { add_index_zval(return_value, Z_LVAL_P(zkeyval), zcolval); } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_OBJECT) { - Z_ADDREF_P(zcolval); SEPARATE_ZVAL(zkeyval); convert_to_string(zkeyval); add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval); } else { - if (Z_REFCOUNTED_P(zcolval)) { - Z_ADDREF_P(zcolval); - } add_next_index_zval(return_value, zcolval); } } -- cgit v1.2.1