summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/array.c141
1 files changed, 72 insertions, 69 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 400e305f3c..28fbb5188d 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -4113,6 +4113,9 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
if (Z_OBJ_HANDLER_P(data, has_property)(data, name, 2, NULL)
|| Z_OBJ_HANDLER_P(data, has_property)(data, name, 0, NULL)) {
prop = Z_OBJ_HANDLER_P(data, read_property)(data, name, BP_VAR_R, NULL, rv);
+ if (prop) {
+ ZVAL_DEREF(prop);
+ }
}
} else if (Z_TYPE_P(data) == IS_ARRAY) {
if (Z_TYPE_P(name) == IS_STRING) {
@@ -4120,11 +4123,12 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
} else if (Z_TYPE_P(name) == IS_LONG) {
prop = zend_hash_index_find(Z_ARRVAL_P(data), Z_LVAL_P(name));
}
+ if (prop) {
+ ZVAL_DEREF(prop);
+ Z_TRY_ADDREF_P(prop);
+ }
}
- if (prop) {
- ZVAL_DEREF(prop);
- }
return prop;
}
@@ -4135,98 +4139,97 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
value_key and optionally indexed by the index_key */
PHP_FUNCTION(array_column)
{
- zval *zcolumn = NULL, *zkey = NULL, *data;
- HashTable *arr_hash;
- zval *zcolval = NULL, *zkeyval = NULL, rvc, rvk;
+ HashTable *input;
+ zval *colval, *data, rv;
+ zval *column = NULL, *index = NULL;
ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_ARRAY_HT(arr_hash)
- Z_PARAM_ZVAL_EX(zcolumn, 1, 0)
+ Z_PARAM_ARRAY_HT(input)
+ Z_PARAM_ZVAL_EX(column, 1, 0)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL_EX(zkey, 1, 0)
+ Z_PARAM_ZVAL_EX(index, 1, 0)
ZEND_PARSE_PARAMETERS_END();
- if ((zcolumn && !array_column_param_helper(zcolumn, "column")) ||
- (zkey && !array_column_param_helper(zkey, "index"))) {
+ if ((column && !array_column_param_helper(column, "column")) ||
+ (index && !array_column_param_helper(index, "index"))) {
RETURN_FALSE;
}
- array_init_size(return_value, zend_hash_num_elements(arr_hash));
- if (!zkey) {
+ array_init_size(return_value, zend_hash_num_elements(input));
+ if (!index) {
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
- ZEND_HASH_FOREACH_VAL(arr_hash, data) {
+ ZEND_HASH_FOREACH_VAL(input, data) {
ZVAL_DEREF(data);
- if (!zcolumn) {
- zcolval = data;
- Z_TRY_ADDREF_P(zcolval);
- } else if ((zcolval = array_column_fetch_prop(data, zcolumn, &rvc)) == NULL) {
+ if (!column) {
+ Z_TRY_ADDREF_P(data);
+ colval = data;
+ } else if ((colval = array_column_fetch_prop(data, column, &rv)) == NULL) {
continue;
- } else if (zcolval != &rvc) {
- Z_TRY_ADDREF_P(zcolval);
}
- ZEND_HASH_FILL_ADD(zcolval);
+ ZEND_HASH_FILL_ADD(colval);
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FILL_END();
} else {
- ZEND_HASH_FOREACH_VAL(arr_hash, data) {
+ ZEND_HASH_FOREACH_VAL(input, data) {
ZVAL_DEREF(data);
- if (!zcolumn) {
- zcolval = data;
- Z_TRY_ADDREF_P(zcolval);
- } else if ((zcolval = array_column_fetch_prop(data, zcolumn, &rvc)) == NULL) {
+ if (!column) {
+ Z_TRY_ADDREF_P(data);
+ colval = data;
+ } else if ((colval = array_column_fetch_prop(data, column, &rv)) == NULL) {
continue;
- } else if (zcolval != &rvc) {
- Z_TRY_ADDREF_P(zcolval);
}
- /* Failure will leave zkeyval alone which will land us on the final else block below
+ /* Failure will leave keyval alone which will land us on the final else block below
* which is to append the value as next_index
*/
- if (zkey) {
- zkeyval = array_column_fetch_prop(data, zkey, &rvk);
- }
- if (zkeyval) {
- switch (Z_TYPE_P(zkeyval)) {
- case IS_STRING:
- zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(zkeyval), zcolval);
- break;
- case IS_LONG:
- zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(zkeyval), zcolval);
- break;
- case IS_OBJECT:
- {
- zend_string *tmp_key;
- zend_string *key = zval_get_tmp_string(zkeyval, &tmp_key);
- zend_symtable_update(Z_ARRVAL_P(return_value), key, zcolval);
- zend_tmp_string_release(tmp_key);
- break;
+ if (index) {
+ zval rv;
+ zval *keyval = array_column_fetch_prop(data, index, &rv);
+
+ if (keyval) {
+ switch (Z_TYPE_P(keyval)) {
+ case IS_STRING:
+ zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(keyval), colval);
+ break;
+ case IS_LONG:
+ zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(keyval), colval);
+ break;
+ case IS_OBJECT:
+ {
+ zend_string *tmp_key;
+ zend_string *key = zval_get_tmp_string(keyval, &tmp_key);
+ zend_symtable_update(Z_ARRVAL_P(return_value), key, colval);
+ zend_tmp_string_release(tmp_key);
+ break;
+ }
+ case IS_NULL:
+ zend_hash_update(Z_ARRVAL_P(return_value), ZSTR_EMPTY_ALLOC(), colval);
+ break;
+ case IS_DOUBLE:
+ zend_hash_index_update(Z_ARRVAL_P(return_value),
+ zend_dval_to_lval(Z_DVAL_P(keyval)), colval);
+ break;
+ case IS_TRUE:
+ zend_hash_index_update(Z_ARRVAL_P(return_value), 1, colval);
+ break;
+ case IS_FALSE:
+ zend_hash_index_update(Z_ARRVAL_P(return_value), 0, colval);
+ break;
+ case IS_RESOURCE:
+ zend_hash_index_update(Z_ARRVAL_P(return_value), Z_RES_HANDLE_P(keyval), colval);
+ break;
+ default:
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), colval);
+ break;
}
- case IS_NULL:
- zend_hash_update(Z_ARRVAL_P(return_value), ZSTR_EMPTY_ALLOC(), zcolval);
- break;
- case IS_DOUBLE:
- zend_hash_index_update(Z_ARRVAL_P(return_value), zend_dval_to_lval(Z_DVAL_P(zkeyval)), zcolval);
- break;
- case IS_TRUE:
- zend_hash_index_update(Z_ARRVAL_P(return_value), 1, zcolval);
- break;
- case IS_FALSE:
- zend_hash_index_update(Z_ARRVAL_P(return_value), 0, zcolval);
- break;
- case IS_RESOURCE:
- zend_hash_index_update(Z_ARRVAL_P(return_value), Z_RES_HANDLE_P(zkeyval), zcolval);
- break;
- default:
- add_next_index_zval(return_value, zcolval);
- break;
- }
- if (zkeyval == &rvk) {
- zval_ptr_dtor(&rvk);
+ zval_ptr_dtor(keyval);
+ } else {
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), colval);
}
} else {
- add_next_index_zval(return_value, zcolval);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), colval);
}
} ZEND_HASH_FOREACH_END();
}