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.c479
1 files changed, 245 insertions, 234 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index d44e5d50e7..413ed319d7 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1,7 +1,5 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
- +----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
@@ -365,7 +363,6 @@ static int php_array_data_compare(const void *a, const void *b) /* {{{ */
{
Bucket *f;
Bucket *s;
- zval result;
zval *first;
zval *second;
@@ -381,12 +378,7 @@ static int php_array_data_compare(const void *a, const void *b) /* {{{ */
if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
second = Z_INDIRECT_P(second);
}
- if (compare_function(&result, first, second) == FAILURE) {
- return 0;
- }
-
- ZEND_ASSERT(Z_TYPE(result) == IS_LONG);
- return ZEND_NORMALIZE_BOOL(Z_LVAL(result));
+ return zend_compare(first, second);
}
/* }}} */
@@ -696,13 +688,12 @@ PHP_FUNCTION(krsort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_key_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 0);
+
RETURN_TRUE;
}
/* }}} */
@@ -719,13 +710,12 @@ PHP_FUNCTION(ksort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_key_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 0);
+
RETURN_TRUE;
}
/* }}} */
@@ -791,7 +781,7 @@ PHP_FUNCTION(count)
/* first, we check if the handler is defined */
if (Z_OBJ_HT_P(array)->count_elements) {
RETVAL_LONG(1);
- if (SUCCESS == Z_OBJ_HT(*array)->count_elements(array, &Z_LVAL_P(return_value))) {
+ if (SUCCESS == Z_OBJ_HT(*array)->count_elements(Z_OBJ_P(array), &Z_LVAL_P(return_value))) {
return;
}
if (EG(exception)) {
@@ -800,7 +790,7 @@ PHP_FUNCTION(count)
}
/* if not and the object implements Countable we call its count() method */
if (instanceof_function(Z_OBJCE_P(array), zend_ce_countable)) {
- zend_call_method_with_0_params(array, NULL, NULL, "count", &retval);
+ zend_call_method_with_0_params(Z_OBJ_P(array), NULL, NULL, "count", &retval);
if (Z_TYPE(retval) != IS_UNDEF) {
RETVAL_LONG(zval_get_long(&retval));
zval_ptr_dtor(&retval);
@@ -830,13 +820,9 @@ static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, int fold_case) /* {{{ */
ZEND_PARSE_PARAMETERS_END();
if (fold_case) {
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_natural_case_compare, 0) == FAILURE) {
- return;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), php_array_natural_case_compare, 0);
} else {
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_natural_compare, 0) == FAILURE) {
- return;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), php_array_natural_compare, 0);
}
RETURN_TRUE;
@@ -871,13 +857,12 @@ PHP_FUNCTION(asort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_data_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 0);
+
RETURN_TRUE;
}
/* }}} */
@@ -894,13 +879,12 @@ PHP_FUNCTION(arsort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_data_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 0);
+
RETURN_TRUE;
}
/* }}} */
@@ -917,13 +901,12 @@ PHP_FUNCTION(sort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_data_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 1) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 1);
+
RETURN_TRUE;
}
/* }}} */
@@ -940,13 +923,12 @@ PHP_FUNCTION(rsort)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(sort_type)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
cmp = php_get_data_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 1) == FAILURE) {
- RETURN_FALSE;
- }
+ zend_hash_sort(Z_ARRVAL_P(array), cmp, 1);
+
RETURN_TRUE;
}
/* }}} */
@@ -1016,7 +998,6 @@ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, compare_func_t compare_func,
{
zval *array;
zend_array *arr;
- zend_bool retval;
PHP_ARRAY_CMP_FUNC_VARS;
PHP_ARRAY_CMP_FUNC_BACKUP();
@@ -1035,13 +1016,13 @@ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, compare_func_t compare_func,
/* Copy array, so the in-place modifications will not be visible to the callback function */
arr = zend_array_dup(arr);
- retval = zend_hash_sort(arr, compare_func, renumber) != FAILURE;
+ zend_hash_sort(arr, compare_func, renumber);
zval_ptr_dtor(array);
ZVAL_ARR(array, arr);
PHP_ARRAY_CMP_FUNC_RESTORE();
- RETURN_BOOL(retval);
+ RETURN_TRUE;
}
/* }}} */
@@ -1254,7 +1235,9 @@ PHP_FUNCTION(key)
}
/* }}} */
-/* {{{ proto mixed min(mixed arg1 [, mixed arg2 [, mixed ...]])
+/* {{{
+ * proto mixed min(array values)
+ * proto mixed min(mixed arg1 [, mixed arg2 [, mixed ...]])
Return the lowest value in an array or a series of arguments */
PHP_FUNCTION(min)
{
@@ -1270,14 +1253,14 @@ PHP_FUNCTION(min)
zval *result;
if (Z_TYPE(args[0]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "When only one parameter is given, it must be an array");
- RETVAL_NULL();
+ zend_type_error("When only one parameter is given, it must be an array");
+ return;
} else {
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 0)) != NULL) {
ZVAL_COPY_DEREF(return_value, result);
} else {
- php_error_docref(NULL, E_WARNING, "Array must contain at least one element");
- RETVAL_FALSE;
+ zend_throw_error(NULL, "Array must contain at least one element");
+ return;
}
}
} else {
@@ -1299,7 +1282,9 @@ PHP_FUNCTION(min)
}
/* }}} */
-/* {{{ proto mixed max(mixed arg1 [, mixed arg2 [, mixed ...]])
+/* {{{
+ * proto mixed max(array values)
+ * proto mixed max(mixed arg1 [, mixed arg2 [, mixed ...]])
Return the highest value in an array or a series of arguments */
PHP_FUNCTION(max)
{
@@ -1315,14 +1300,14 @@ PHP_FUNCTION(max)
zval *result;
if (Z_TYPE(args[0]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "When only one parameter is given, it must be an array");
- RETVAL_NULL();
+ zend_type_error("When only one parameter is given, it must be an array");
+ return;
} else {
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 1)) != NULL) {
ZVAL_COPY_DEREF(return_value, result);
} else {
- php_error_docref(NULL, E_WARNING, "Array must contain at least one element");
- RETVAL_FALSE;
+ zend_throw_error(NULL, "Array must contain at least one element");
+ return;
}
}
} else {
@@ -1409,7 +1394,7 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
SEPARATE_ARRAY(zv);
thash = Z_ARRVAL_P(zv);
if (GC_IS_RECURSIVE(thash)) {
- php_error_docref(NULL, E_WARNING, "recursion detected");
+ zend_throw_error(NULL, "Recursion detected");
result = FAILURE;
break;
}
@@ -1460,7 +1445,7 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
target_hash = Z_OBJPROP_P(array);
pos = zend_hash_iterator_pos(ht_iter, target_hash);
} else {
- php_error_docref(NULL, E_WARNING, "Iterated value is no longer an array or object");
+ zend_type_error("Iterated value is no longer an array or object");
result = FAILURE;
break;
}
@@ -1716,16 +1701,16 @@ static zend_always_inline int php_valid_var_name(const char *var_name, size_t va
}
/* }}} */
-PHPAPI int php_prefix_varname(zval *result, const zval *prefix, const char *var_name, size_t var_name_len, zend_bool add_underscore) /* {{{ */
+PHPAPI int php_prefix_varname(zval *result, zend_string *prefix, const char *var_name, size_t var_name_len, zend_bool add_underscore) /* {{{ */
{
- ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0) + var_name_len, 0));
- memcpy(Z_STRVAL_P(result), Z_STRVAL_P(prefix), Z_STRLEN_P(prefix));
+ ZVAL_NEW_STR(result, zend_string_alloc(ZSTR_LEN(prefix) + (add_underscore ? 1 : 0) + var_name_len, 0));
+ memcpy(Z_STRVAL_P(result), ZSTR_VAL(prefix), ZSTR_LEN(prefix));
if (add_underscore) {
- Z_STRVAL_P(result)[Z_STRLEN_P(prefix)] = '_';
+ Z_STRVAL_P(result)[ZSTR_LEN(prefix)] = '_';
}
- memcpy(Z_STRVAL_P(result) + Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0), var_name, var_name_len + 1);
+ memcpy(Z_STRVAL_P(result) + ZSTR_LEN(prefix) + (add_underscore ? 1 : 0), var_name, var_name_len + 1);
return SUCCESS;
}
@@ -1904,7 +1889,7 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table
}
/* }}} */
-static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -1960,7 +1945,7 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
}
/* }}} */
-static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2011,7 +1996,7 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo
}
/* }}} */
-static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2085,7 +2070,7 @@ prefix:
}
/* }}} */
-static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2151,7 +2136,7 @@ prefix:
}
/* }}} */
-static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2198,7 +2183,7 @@ static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_
}
/* }}} */
-static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2245,7 +2230,7 @@ static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_tabl
}
/* }}} */
-static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2300,7 +2285,7 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
}
/* }}} */
-static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_table, zval *prefix) /* {{{ */
+static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */
{
zend_long count = 0;
zend_string *var_name;
@@ -2441,9 +2426,10 @@ static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /*
Imports variables into symbol table from an array */
PHP_FUNCTION(extract)
{
- zval *var_array_param, *prefix = NULL;
+ zval *var_array_param;
zend_long extract_refs;
zend_long extract_type = EXTR_OVERWRITE;
+ zend_string *prefix = NULL;
zend_long count;
zend_array *symbol_table;
@@ -2451,7 +2437,7 @@ PHP_FUNCTION(extract)
Z_PARAM_ARRAY_EX2(var_array_param, 0, 1, 0)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(extract_type)
- Z_PARAM_ZVAL(prefix)
+ Z_PARAM_STR(prefix)
ZEND_PARSE_PARAMETERS_END();
extract_refs = (extract_type & EXTR_REFS);
@@ -2461,22 +2447,18 @@ PHP_FUNCTION(extract)
extract_type &= 0xff;
if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) {
- php_error_docref(NULL, E_WARNING, "Invalid extract type");
+ zend_throw_error(NULL, "Invalid extract type");
return;
}
if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS && ZEND_NUM_ARGS() < 3) {
- php_error_docref(NULL, E_WARNING, "specified extract type requires the prefix parameter");
+ zend_throw_error(NULL, "Specified extract type requires the prefix parameter");
return;
}
if (prefix) {
- if (!try_convert_to_string(prefix)) {
- return;
- }
-
- if (Z_STRLEN_P(prefix) && !php_valid_var_name(Z_STRVAL_P(prefix), Z_STRLEN_P(prefix))) {
- php_error_docref(NULL, E_WARNING, "prefix is not a valid identifier");
+ if (ZSTR_LEN(prefix) && !php_valid_var_name(ZSTR_VAL(prefix), ZSTR_LEN(prefix))) {
+ zend_throw_error(NULL, "Prefix is not a valid identifier");
return;
}
}
@@ -2486,6 +2468,7 @@ PHP_FUNCTION(extract)
}
symbol_table = zend_rebuild_symbol_table();
+ ZEND_ASSERT(symbol_table && "A symbol table should always be available here");
if (extract_refs) {
switch (extract_type) {
@@ -2568,7 +2551,7 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
} else if (Z_TYPE_P(entry) == IS_ARRAY) {
if (Z_REFCOUNTED_P(entry)) {
if (Z_IS_RECURSIVE_P(entry)) {
- php_error_docref(NULL, E_WARNING, "recursion detected");
+ zend_throw_error(NULL, "Recursion detected");
return;
}
Z_PROTECT_RECURSION_P(entry);
@@ -2600,9 +2583,7 @@ PHP_FUNCTION(compact)
}
symbol_table = zend_rebuild_symbol_table();
- if (UNEXPECTED(symbol_table == NULL)) {
- return;
- }
+ ZEND_ASSERT(symbol_table && "A symbol table should always be available here");
/* compact() is probably most used with a single array of var_names
or multiple string names, rather than a combination of both.
@@ -2634,11 +2615,11 @@ PHP_FUNCTION(array_fill)
if (EXPECTED(num > 0)) {
if (sizeof(num) > 4 && UNEXPECTED(EXPECTED(num > 0x7fffffff))) {
- php_error_docref(NULL, E_WARNING, "Too many elements");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Too many elements");
+ return;
} else if (UNEXPECTED(start_key > ZEND_LONG_MAX - num + 1)) {
- php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied");
+ return;
} else if (EXPECTED(start_key >= 0) && EXPECTED(start_key < num)) {
/* create packed array */
Bucket *p;
@@ -2683,8 +2664,8 @@ PHP_FUNCTION(array_fill)
} else if (EXPECTED(num == 0)) {
RETURN_EMPTY_ARRAY();
} else {
- php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Number of elements can't be negative");
+ return;
}
}
/* }}} */
@@ -2721,8 +2702,9 @@ PHP_FUNCTION(array_fill_keys)
#define RANGE_CHECK_DOUBLE_INIT_ARRAY(start, end) do { \
double __calc_size = ((start - end) / step) + 1; \
if (__calc_size >= (double)HT_MAX_SIZE) { \
- php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=%0.0f end=%0.0f", end, start); \
- RETURN_FALSE; \
+ zend_throw_error(NULL, \
+ "The supplied range exceeds the maximum array size: start=%0.0f end=%0.0f", end, start); \
+ return; \
} \
size = (uint32_t)_php_math_round(__calc_size, 0, PHP_ROUND_HALF_UP); \
array_init_size(return_value, size); \
@@ -2732,8 +2714,9 @@ PHP_FUNCTION(array_fill_keys)
#define RANGE_CHECK_LONG_INIT_ARRAY(start, end) do { \
zend_ulong __calc_size = ((zend_ulong) start - end) / lstep; \
if (__calc_size >= HT_MAX_SIZE - 1) { \
- php_error_docref(NULL, E_WARNING, "The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \
- RETURN_FALSE; \
+ zend_throw_error(NULL, \
+ "The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \
+ return; \
} \
size = (uint32_t)(__calc_size + 1); \
array_init_size(return_value, size); \
@@ -2752,24 +2735,11 @@ PHP_FUNCTION(range)
Z_PARAM_ZVAL(zlow)
Z_PARAM_ZVAL(zhigh)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL(zstep)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ Z_PARAM_NUMBER(zstep)
+ ZEND_PARSE_PARAMETERS_END();
if (zstep) {
- if (Z_TYPE_P(zstep) == IS_DOUBLE) {
- is_step_double = 1;
- } else if (Z_TYPE_P(zstep) == IS_STRING) {
- int type = is_numeric_string(Z_STRVAL_P(zstep), Z_STRLEN_P(zstep), NULL, NULL, 0);
- if (type == IS_DOUBLE) {
- is_step_double = 1;
- }
- if (type == 0) {
- /* bad number */
- php_error_docref(NULL, E_WARNING, "Invalid range string - must be numeric");
- RETURN_FALSE;
- }
- }
-
+ is_step_double = Z_TYPE_P(zstep) == IS_DOUBLE;
step = zval_get_double(zstep);
/* We only want positive step values. */
@@ -2842,8 +2812,8 @@ double_str:
high = zval_get_double(zhigh);
if (zend_isinf(high) || zend_isinf(low)) {
- php_error_docref(NULL, E_WARNING, "Invalid range supplied: start=%0.0f end=%0.0f", low, high);
- RETURN_FALSE;
+ zend_throw_error(NULL, "Invalid range supplied: start=%0.0f end=%0.0f", low, high);
+ return;
}
if (low > high) { /* Negative steps */
@@ -2935,8 +2905,8 @@ long_str:
}
err:
if (err) {
- php_error_docref(NULL, E_WARNING, "step exceeds the specified range");
- RETURN_FALSE;
+ zend_throw_error(NULL, "step exceeds the specified range");
+ return;
}
}
/* }}} */
@@ -3033,7 +3003,7 @@ PHP_FUNCTION(shuffle)
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY_EX(array, 0, 1)
- ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
+ ZEND_PARSE_PARAMETERS_END();
php_array_data_shuffle(array);
@@ -3198,8 +3168,8 @@ PHP_FUNCTION(array_push)
if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var) == NULL) {
Z_TRY_DELREF(new_var);
- php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Cannot add element to the array as the next element is already occupied");
+ return;
}
}
@@ -3243,7 +3213,7 @@ PHP_FUNCTION(array_pop)
}
ZVAL_COPY_DEREF(return_value, val);
- if (!p->key && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
+ if (!p->key && (zend_long)p->h == (Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
}
@@ -3431,19 +3401,20 @@ PHP_FUNCTION(array_splice)
HashTable *rem_hash = NULL;
zend_long offset,
length = 0;
+ zend_bool length_is_null = 1;
int num_in; /* Number of elements in the input array */
ZEND_PARSE_PARAMETERS_START(2, 4)
Z_PARAM_ARRAY_EX(array, 0, 1)
Z_PARAM_LONG(offset)
Z_PARAM_OPTIONAL
- Z_PARAM_LONG(length)
+ Z_PARAM_LONG_OR_NULL(length, length_is_null)
Z_PARAM_ZVAL(repl_array)
ZEND_PARSE_PARAMETERS_END();
num_in = zend_hash_num_elements(Z_ARRVAL_P(array));
- if (ZEND_NUM_ARGS() < 3) {
+ if (length_is_null) {
length = num_in;
}
@@ -3474,6 +3445,9 @@ PHP_FUNCTION(array_splice)
/* Initialize return value */
array_init_size(return_value, size > 0 ? (uint32_t)size : 0);
rem_hash = Z_ARRVAL_P(return_value);
+ } else {
+ /* The return value will not be used, but make sure it still has the correct type. */
+ RETVAL_EMPTY_ARRAY();
}
/* Perform splice */
@@ -3481,18 +3455,44 @@ PHP_FUNCTION(array_splice)
}
/* }}} */
+/* {{{ find_bucket_at_offset(HashTable* ht, zend_long offset)
+ Finds the bucket at the given valid offset */
+static inline Bucket* find_bucket_at_offset(HashTable* ht, zend_long offset)
+{
+ zend_long pos;
+ Bucket *bucket;
+ ZEND_ASSERT(offset >= 0 && offset <= ht->nNumOfElements);
+ if (HT_IS_WITHOUT_HOLES(ht)) {
+ /* There's no need to iterate over the array to filter out holes if there are no holes */
+ /* This properly handles both packed and unpacked arrays. */
+ return ht->arData + offset;
+ }
+ /* Otherwise, this code has to iterate over the HashTable and skip holes in the array. */
+ pos = 0;
+ ZEND_HASH_FOREACH_BUCKET(ht, bucket) {
+ if (pos >= offset) {
+ /* This is the bucket of the array element at the requested offset */
+ return bucket;
+ }
+ ++pos;
+ } ZEND_HASH_FOREACH_END();
+
+ /* Return a pointer to the end of the bucket array. */
+ return ht->arData + ht->nNumUsed;
+}
+/* }}} */
+
/* {{{ proto array array_slice(array input, int offset [, int length [, bool preserve_keys]])
Returns elements specified by offset and length */
PHP_FUNCTION(array_slice)
{
- zval *input, /* Input array */
- *z_length = NULL, /* How many elements to get */
- *entry; /* An array entry */
- zend_long offset, /* Offset to get elements from */
- length = 0;
- zend_bool preserve_keys = 0; /* Whether to preserve keys while copying to the new array or not */
- int num_in, /* Number of elements in the input array */
- pos; /* Current position in the array */
+ zval *input; /* Input array */
+ zval *entry; /* An array entry */
+ zend_long offset; /* Offset to get elements from */
+ zend_long length = 0; /* How many elements to get */
+ zend_bool length_is_null = 1; /* Whether an explicit length has been omitted */
+ zend_bool preserve_keys = 0; /* Whether to preserve keys while copying to the new array */
+ uint32_t num_in; /* Number of elements in the input array */
zend_string *string_key;
zend_ulong num_key;
@@ -3500,7 +3500,7 @@ PHP_FUNCTION(array_slice)
Z_PARAM_ARRAY(input)
Z_PARAM_LONG(offset)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL(z_length)
+ Z_PARAM_LONG_OR_NULL(length, length_is_null)
Z_PARAM_BOOL(preserve_keys)
ZEND_PARSE_PARAMETERS_END();
@@ -3508,14 +3508,12 @@ PHP_FUNCTION(array_slice)
num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
/* We want all entries from offset to the end if length is not passed or is null */
- if (ZEND_NUM_ARGS() < 3 || Z_TYPE_P(z_length) == IS_NULL) {
+ if (length_is_null) {
length = num_in;
- } else {
- length = zval_get_long(z_length);
}
/* Clamp the offset.. */
- if (offset > num_in) {
+ if (offset > (zend_long) num_in) {
RETURN_EMPTY_ARRAY();
} else if (offset < 0 && (offset = (num_in + offset)) < 0) {
offset = 0;
@@ -3535,50 +3533,61 @@ PHP_FUNCTION(array_slice)
/* Initialize returned array */
array_init_size(return_value, (uint32_t)length);
- /* Start at the beginning and go until we hit offset */
- pos = 0;
- if (HT_IS_PACKED(Z_ARRVAL_P(input)) &&
- (!preserve_keys ||
- (offset == 0 && HT_IS_WITHOUT_HOLES(Z_ARRVAL_P(input))))) {
- zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
- ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) {
- pos++;
- if (pos <= offset) {
+ // Contains modified variants of ZEND_HASH_FOREACH_VAL
+ {
+ HashTable *ht = Z_ARRVAL_P(input);
+ Bucket *p = find_bucket_at_offset(ht, offset);
+ Bucket *end = ht->arData + ht->nNumUsed;
+
+ /* Start at the beginning and go until we hit offset */
+ if (HT_IS_PACKED(Z_ARRVAL_P(input)) &&
+ (!preserve_keys ||
+ (offset == 0 && HT_IS_WITHOUT_HOLES(Z_ARRVAL_P(input))))) {
+
+ zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (; p != end; p++) {
+ if (__fill_idx >= length) {
+ break;
+ }
+ entry = &p->val;
+ if (UNEXPECTED(Z_TYPE_P(entry) == IS_UNDEF)) {
+ continue;
+ }
+ if (UNEXPECTED(Z_ISREF_P(entry)) &&
+ UNEXPECTED(Z_REFCOUNT_P(entry) == 1)) {
+ entry = Z_REFVAL_P(entry);
+ }
+ Z_TRY_ADDREF_P(entry);
+ ZEND_HASH_FILL_ADD(entry);
+ }
+ } ZEND_HASH_FILL_END();
+ } else {
+ zend_long n = 0; /* Current number of elements */
+ for (; p != end; p++) {
+ entry = &p->val;
+ if (UNEXPECTED(Z_TYPE_P(entry) == IS_UNDEF)) {
continue;
}
- if (pos > offset + length) {
+ if (n >= length) {
break;
}
- if (UNEXPECTED(Z_ISREF_P(entry)) &&
- UNEXPECTED(Z_REFCOUNT_P(entry) == 1)) {
- entry = Z_REFVAL_P(entry);
- }
- Z_TRY_ADDREF_P(entry);
- ZEND_HASH_FILL_ADD(entry);
- } ZEND_HASH_FOREACH_END();
- } ZEND_HASH_FILL_END();
- } else {
- ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) {
- pos++;
- if (pos <= offset) {
- continue;
- }
- if (pos > offset + length) {
- break;
- }
+ n++;
+ num_key = p->h;
+ string_key = p->key;
- if (string_key) {
- entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
- } else {
- if (preserve_keys) {
- entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+ if (string_key) {
+ entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
} else {
- entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+ if (preserve_keys) {
+ entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+ } else {
+ entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+ }
}
+ zval_add_ref(entry);
}
- zval_add_ref(entry);
- } ZEND_HASH_FOREACH_END();
+ }
}
}
/* }}} */
@@ -3601,7 +3610,7 @@ PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src) /* {{{ */
ZVAL_DEREF(dest_zval);
thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL;
if ((thash && GC_IS_RECURSIVE(thash)) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
- php_error_docref(NULL, E_WARNING, "recursion detected");
+ zend_throw_error(NULL, "Recursion detected");
return 0;
}
@@ -3722,7 +3731,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src) /* {{{ *
if (Z_IS_RECURSIVE_P(dest_zval) ||
Z_IS_RECURSIVE_P(src_zval) ||
(Z_ISREF_P(src_entry) && Z_ISREF_P(dest_entry) && Z_REF_P(src_entry) == Z_REF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
- php_error_docref(NULL, E_WARNING, "recursion detected");
+ zend_throw_error(NULL, "Recursion detected");
return 0;
}
@@ -3771,8 +3780,8 @@ static zend_always_inline void php_array_replace_wrapper(INTERNAL_FUNCTION_PARAM
zval *arg = args + i;
if (Z_TYPE_P(arg) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
+ return;
}
}
@@ -3815,8 +3824,8 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
zval *arg = args + i;
if (Z_TYPE_P(arg) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
+ return;
}
count += zend_hash_num_elements(Z_ARRVAL_P(arg));
}
@@ -3957,7 +3966,7 @@ PHP_FUNCTION(array_keys)
/* Base case: empty input */
if (!elem_count) {
- RETURN_ZVAL(input, 1, 0)
+ RETURN_ZVAL(input, 1, 0);
}
/* Initialize return array */
@@ -4016,7 +4025,7 @@ PHP_FUNCTION(array_keys)
}
/* }}} */
-/* {{{ proto mixed array_key_first(array stack)
+/* {{{ proto int|string|false array_key_first(array stack)
Get the key of the first element of the array */
PHP_FUNCTION(array_key_first)
{
@@ -4032,7 +4041,7 @@ PHP_FUNCTION(array_key_first)
}
/* }}} */
-/* {{{ proto mixed array_key_last(array stack)
+/* {{{ proto int|string|false array_key_last(array stack)
Get the key of the last element of the array */
PHP_FUNCTION(array_key_last)
{
@@ -4130,7 +4139,7 @@ PHP_FUNCTION(array_count_values)
Z_LVAL_P(tmp)++;
}
} else {
- php_error_docref(NULL, E_WARNING, "Can only count STRING and INTEGER values!");
+ php_error_docref(NULL, E_WARNING, "Can only count string and integer values, entry skipped");
}
} ZEND_HASH_FOREACH_END();
}
@@ -4158,7 +4167,7 @@ zend_bool array_column_param_helper(zval *param,
return 1;
default:
- php_error_docref(NULL, E_WARNING, "The %s key should be either a string or an integer", name);
+ zend_type_error("The %s key should be either a string or an integer", name);
return 0;
}
}
@@ -4172,9 +4181,12 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
/* The has_property check is first performed in "exists" mode (which returns true for
* properties that are null but exist) and then in "has" mode to handle objects that
* implement __isset (which is not called in "exists" mode). */
- if (Z_OBJ_HANDLER_P(data, has_property)(data, name, ZEND_PROPERTY_EXISTS, NULL)
- || Z_OBJ_HANDLER_P(data, has_property)(data, name, ZEND_PROPERTY_ISSET, NULL)) {
- prop = Z_OBJ_HANDLER_P(data, read_property)(data, name, BP_VAR_R, NULL, rv);
+ zend_string *str, *tmp_str;
+
+ str = zval_get_tmp_string(name, &tmp_str);
+ if (Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), str, ZEND_PROPERTY_EXISTS, NULL)
+ || Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), str, ZEND_PROPERTY_ISSET, NULL)) {
+ prop = Z_OBJ_HANDLER_P(data, read_property)(Z_OBJ_P(data), str, BP_VAR_R, NULL, rv);
if (prop) {
ZVAL_DEREF(prop);
if (prop != rv) {
@@ -4182,6 +4194,7 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
}
}
}
+ zend_tmp_string_release(tmp_str);
} else if (Z_TYPE_P(data) == IS_ARRAY) {
if (Z_TYPE_P(name) == IS_STRING) {
prop = zend_symtable_find(Z_ARRVAL_P(data), Z_STR_P(name));
@@ -4217,7 +4230,7 @@ PHP_FUNCTION(array_column)
if ((column && !array_column_param_helper(column, "column")) ||
(index && !array_column_param_helper(index, "index"))) {
- RETURN_FALSE;
+ return;
}
array_init_size(return_value, zend_hash_num_elements(input));
@@ -4372,8 +4385,8 @@ PHP_FUNCTION(array_pad)
input_size = zend_hash_num_elements(Z_ARRVAL_P(input));
pad_size_abs = ZEND_ABS(pad_size);
if (pad_size_abs < 0 || pad_size_abs - input_size > Z_L(1048576)) {
- php_error_docref(NULL, E_WARNING, "You may only pad up to 1048576 elements at a time");
- RETURN_FALSE;
+ zend_throw_error(NULL, "You may only pad up to 1048576 elements at a time");
+ return;
}
if (input_size >= pad_size_abs) {
@@ -4469,7 +4482,7 @@ PHP_FUNCTION(array_flip)
}
zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
} else {
- php_error_docref(NULL, E_WARNING, "Can only flip STRING and INTEGER values!");
+ php_error_docref(NULL, E_WARNING, "Can only flip string and integer values, entry skipped");
}
} ZEND_HASH_FOREACH_END();
}
@@ -4693,7 +4706,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
}
if (argc < req_args) {
- php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, argc);
+ zend_argument_count_error("At least %d parameters are required, %d given", req_args, argc);
return;
}
@@ -4703,8 +4716,8 @@ 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, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
}
@@ -4788,12 +4801,12 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
param_spec = "+f";
intersect_data_compare_func = php_array_user_compare;
} else {
- php_error_docref(NULL, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
+ ZEND_ASSERT(0 && "Invalid data_compare_type");
return;
}
if (ZEND_NUM_ARGS() < req_args) {
- php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+ zend_argument_count_error("At least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
return;
}
@@ -4840,12 +4853,12 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
fci_key = &fci2;
fci_key_cache = &fci2_cache;
} else {
- php_error_docref(NULL, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);
+ ZEND_ASSERT(0 && "Invalid data_compare_type / key_compare_type");
return;
}
if (ZEND_NUM_ARGS() < req_args) {
- php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+ zend_argument_count_error("At least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
return;
}
@@ -4854,7 +4867,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
}
} else {
- php_error_docref(NULL, E_WARNING, "behavior is %d. This should never happen. Please report as a bug", behavior);
+ ZEND_ASSERT(0 && "Invalid behavior");
return;
}
@@ -4874,7 +4887,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
for (i = 0; i < arr_argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
arr_argc = i; /* only free up to i - 1 */
goto out;
}
@@ -5092,7 +5105,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
argc = ZEND_NUM_ARGS();
if (data_compare_type == DIFF_COMP_DATA_USER) {
if (argc < 3) {
- php_error_docref(NULL, E_WARNING, "at least 3 parameters are required, %d given", ZEND_NUM_ARGS());
+ zend_argument_count_error("At least 3 parameters are required, %d given", ZEND_NUM_ARGS());
return;
}
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+f", &args, &argc, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) {
@@ -5101,7 +5114,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
diff_data_compare_func = zval_user_compare;
} else {
if (argc < 2) {
- php_error_docref(NULL, E_WARNING, "at least 2 parameters are required, %d given", ZEND_NUM_ARGS());
+ zend_argument_count_error("At least 2 parameters are required, %d given", ZEND_NUM_ARGS());
return;
}
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
@@ -5114,8 +5127,8 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
for (i = 0; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
}
@@ -5204,7 +5217,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
}
if (ZEND_NUM_ARGS() < req_args) {
- php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+ zend_argument_count_error("At least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
return;
}
@@ -5251,12 +5264,12 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
fci_key = &fci2;
fci_key_cache = &fci2_cache;
} else {
- php_error_docref(NULL, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);
+ ZEND_ASSERT(0 && "Invalid data_compare_type / key_compare_type");
return;
}
if (ZEND_NUM_ARGS() < req_args) {
- php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+ zend_argument_count_error("At least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
return;
}
@@ -5265,7 +5278,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
}
} else {
- php_error_docref(NULL, E_WARNING, "behavior is %d. This should never happen. Please report as a bug", behavior);
+ ZEND_ASSERT(0 && "Invalid behavior");
return;
}
@@ -5285,7 +5298,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
for (i = 0; i < arr_argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
arr_argc = i; /* only free up to i - 1 */
goto out;
}
@@ -5453,7 +5466,7 @@ PHP_FUNCTION(array_diff)
zval dummy;
if (ZEND_NUM_ARGS() < 2) {
- php_error_docref(NULL, E_WARNING, "at least 2 parameters are required, %d given", ZEND_NUM_ARGS());
+ zend_argument_count_error("At least 2 parameters are required, %d given", ZEND_NUM_ARGS());
return;
}
@@ -5462,16 +5475,16 @@ PHP_FUNCTION(array_diff)
ZEND_PARSE_PARAMETERS_END();
if (Z_TYPE(args[0]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter 1 to be an array, %s given", zend_zval_type_name(&args[0]));
- RETURN_NULL();
+ zend_type_error("Expected parameter 1 to be an array, %s given", zend_zval_type_name(&args[0]));
+ return;
}
num = zend_hash_num_elements(Z_ARRVAL(args[0]));
if (num == 0) {
for (i = 1; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
}
RETURN_EMPTY_ARRAY();
@@ -5487,8 +5500,8 @@ PHP_FUNCTION(array_diff)
if (!value) {
for (i = 1; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
}
RETURN_EMPTY_ARRAY();
@@ -5498,8 +5511,8 @@ PHP_FUNCTION(array_diff)
for (i = 1; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
if (!found) {
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(args[i]), value) {
@@ -5528,8 +5541,8 @@ PHP_FUNCTION(array_diff)
num = 0;
for (i = 1; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
- RETURN_NULL();
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
+ return;
}
num += zend_hash_num_elements(Z_ARRVAL(args[i]));
}
@@ -5636,7 +5649,7 @@ PHPAPI int php_multisort_compare(const void *a, const void *b) /* {{{ */
#define MULTISORT_ABORT \
efree(func); \
efree(arrays); \
- RETURN_FALSE;
+ return;
static void array_bucket_p_sawp(void *p, void *q) /* {{{ */ {
Bucket *t;
@@ -5713,7 +5726,7 @@ PHP_FUNCTION(array_multisort)
sort_order = Z_LVAL_P(arg) == PHP_SORT_DESC ? PHP_SORT_DESC : PHP_SORT_ASC;
parse_state[MULTISORT_ORDER] = 0;
} else {
- php_error_docref(NULL, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
+ zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
MULTISORT_ABORT;
}
break;
@@ -5729,19 +5742,19 @@ PHP_FUNCTION(array_multisort)
sort_type = (int)Z_LVAL_P(arg);
parse_state[MULTISORT_TYPE] = 0;
} else {
- php_error_docref(NULL, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
+ zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
MULTISORT_ABORT;
}
break;
default:
- php_error_docref(NULL, E_WARNING, "Argument #%d is an unknown sort flag", i + 1);
+ zend_type_error("Argument #%d is an unknown sort flag", i + 1);
MULTISORT_ABORT;
break;
}
} else {
- php_error_docref(NULL, E_WARNING, "Argument #%d is expected to be an array or a sort flag", i + 1);
+ zend_type_error("Argument #%d is expected to be an array or a sort flag", i + 1);
MULTISORT_ABORT;
}
}
@@ -5752,7 +5765,7 @@ PHP_FUNCTION(array_multisort)
array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
for (i = 0; i < num_arrays; i++) {
if (zend_hash_num_elements(Z_ARRVAL_P(arrays[i])) != (uint32_t)array_size) {
- php_error_docref(NULL, E_WARNING, "Array sizes are inconsistent");
+ zend_throw_error(NULL, "Array sizes are inconsistent");
MULTISORT_ABORT;
}
}
@@ -5824,7 +5837,7 @@ PHP_FUNCTION(array_multisort)
}
/* }}} */
-/* {{{ proto mixed array_rand(array input [, int num_req])
+/* {{{ proto int|string|array array_rand(array input [, int num_req])
Return key/keys for random entry/entries in the array */
PHP_FUNCTION(array_rand)
{
@@ -5848,7 +5861,7 @@ PHP_FUNCTION(array_rand)
num_avail = zend_hash_num_elements(Z_ARRVAL_P(input));
if (num_avail == 0) {
- php_error_docref(NULL, E_WARNING, "Array is empty");
+ zend_throw_error(NULL, "Array is empty");
return;
}
@@ -5889,7 +5902,7 @@ PHP_FUNCTION(array_rand)
}
if (num_req <= 0 || num_req > num_avail) {
- php_error_docref(NULL, E_WARNING, "Second argument has to be between 1 and the number of elements in the array");
+ zend_throw_error(NULL, "Second argument has to be between 1 and the number of elements in the array");
return;
}
@@ -5935,7 +5948,7 @@ PHP_FUNCTION(array_rand)
}
/* }}} */
-/* {{{ proto mixed array_sum(array input)
+/* {{{ proto int|float array_sum(array input)
Returns the sum of the array entries */
PHP_FUNCTION(array_sum)
{
@@ -5960,7 +5973,7 @@ PHP_FUNCTION(array_sum)
}
/* }}} */
-/* {{{ proto mixed array_product(array input)
+/* {{{ proto int|float array_product(array input)
Returns the product of the array entries */
PHP_FUNCTION(array_product)
{
@@ -6063,7 +6076,7 @@ PHP_FUNCTION(array_reduce)
}
/* }}} */
-/* {{{ proto array array_filter(array input [, mixed callback])
+/* {{{ proto array array_filter(array input [, mixed callback [, int use_type]])
Filters elements from the array via the callback. */
PHP_FUNCTION(array_filter)
{
@@ -6172,8 +6185,6 @@ PHP_FUNCTION(array_map)
Z_PARAM_VARIADIC('+', arrays, n_arrays)
ZEND_PARSE_PARAMETERS_END();
- RETVAL_NULL();
-
if (n_arrays == 1) {
zend_ulong num_key;
zend_string *str_key;
@@ -6181,7 +6192,7 @@ PHP_FUNCTION(array_map)
int ret;
if (Z_TYPE(arrays[0]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter 2 to be an array, %s given", zend_zval_type_name(&arrays[0]));
+ zend_type_error("Expected parameter 2 to be an array, %s given", zend_zval_type_name(&arrays[0]));
return;
}
maxlen = zend_hash_num_elements(Z_ARRVAL(arrays[0]));
@@ -6222,7 +6233,7 @@ PHP_FUNCTION(array_map)
for (i = 0; i < n_arrays; i++) {
if (Z_TYPE(arrays[i]) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 2, zend_zval_type_name(&arrays[i]));
+ zend_type_error("Expected parameter %d to be an array, %s given", i + 2, zend_zval_type_name(&arrays[i]));
efree(array_pos);
return;
}
@@ -6381,7 +6392,7 @@ PHP_FUNCTION(array_chunk)
/* Do bounds checking for size parameter. */
if (size < 1) {
- php_error_docref(NULL, E_WARNING, "Size parameter expected to be greater than 0");
+ zend_throw_error(NULL, "Size parameter expected to be greater than 0");
return;
}
@@ -6446,8 +6457,8 @@ PHP_FUNCTION(array_combine)
num_values = zend_hash_num_elements(values);
if (num_keys != num_values) {
- php_error_docref(NULL, E_WARNING, "Both parameters should have an equal number of elements");
- RETURN_FALSE;
+ zend_throw_error(NULL, "Both parameters should have an equal number of elements");
+ return;
}
if (!num_keys) {