Skip to content

Commit bb6f374

Browse files
committed
Improve argument error messages in ext/standard
Closes GH-5198
1 parent c2f1c36 commit bb6f374

File tree

109 files changed

+1876
-1854
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+1876
-1854
lines changed

Zend/zend_API.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *e
241241
}
242242
/* }}} */
243243

244-
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...) /* {{{ */
244+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */
245245
{
246246
const char *space;
247247
const char *class_name;
@@ -254,20 +254,45 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *erro
254254
class_name = get_active_class_name(&space);
255255
arg_name = get_active_function_arg_name(arg_num);
256256

257-
va_list va;
258-
va_start(va, format);
259257
zend_vspprintf(&message, 0, format, va);
260-
va_end(va);
261-
262258
zend_throw_error(error_ce, "%s%s%s(): Argument #%d%s%s%s %s",
263-
class_name, space, get_active_function_name(),
264-
arg_num, arg_name ? " ($" : "", arg_name ? arg_name : "", arg_name ? ")" : "",
265-
message
259+
class_name, space, get_active_function_name(), arg_num,
260+
arg_name ? " ($" : "", arg_name ? arg_name : "", arg_name ? ")" : "", message
266261
);
267262
efree(message);
268263
}
269264
/* }}} */
270265

266+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...) /* {{{ */
267+
{
268+
va_list va;
269+
270+
va_start(va, format);
271+
zend_argument_error_variadic(error_ce, arg_num, format, va);
272+
va_end(va);
273+
}
274+
/* }}} */
275+
276+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_type_error(uint32_t arg_num, const char *format, ...) /* {{{ */
277+
{
278+
va_list va;
279+
280+
va_start(va, format);
281+
zend_argument_error_variadic(zend_ce_type_error, arg_num, format, va);
282+
va_end(va);
283+
}
284+
/* }}} */
285+
286+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num, const char *format, ...) /* {{{ */
287+
{
288+
va_list va;
289+
290+
va_start(va, format);
291+
zend_argument_error_variadic(zend_ce_value_error, arg_num, format, va);
292+
va_end(va);
293+
}
294+
/* }}} */
295+
271296
ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
272297
{
273298
zend_class_entry *ce_base = *pce;

Zend/zend_API.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,10 +1154,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, z
11541154
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, const char *name, zval *arg);
11551155
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error);
11561156
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...);
1157-
#define zend_argument_type_error(arg_num, ...) \
1158-
zend_argument_error(zend_ce_type_error, arg_num, __VA_ARGS__)
1159-
#define zend_argument_value_error(arg_num, ...) \
1160-
zend_argument_error(zend_ce_value_error, arg_num, __VA_ARGS__)
1157+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_type_error(uint32_t arg_num, const char *format, ...);
1158+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num, const char *format, ...);
11611159

11621160
#define ZPP_ERROR_OK 0
11631161
#define ZPP_ERROR_FAILURE 1

ext/standard/array.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,13 +1191,13 @@ PHP_FUNCTION(min)
11911191
zval *result;
11921192

11931193
if (Z_TYPE(args[0]) != IS_ARRAY) {
1194-
zend_type_error("When only one parameter is given, it must be an array");
1194+
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_type_name(&args[0]));
11951195
RETURN_THROWS();
11961196
} else {
11971197
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 0)) != NULL) {
11981198
ZVAL_COPY_DEREF(return_value, result);
11991199
} else {
1200-
zend_value_error("Array must contain at least one element");
1200+
zend_argument_value_error(1, "must contain at least one element");
12011201
RETURN_THROWS();
12021202
}
12031203
}
@@ -1238,13 +1238,13 @@ PHP_FUNCTION(max)
12381238
zval *result;
12391239

12401240
if (Z_TYPE(args[0]) != IS_ARRAY) {
1241-
zend_type_error("When only one parameter is given, it must be an array");
1241+
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_type_name(&args[0]));
12421242
RETURN_THROWS();
12431243
} else {
12441244
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 1)) != NULL) {
12451245
ZVAL_COPY_DEREF(return_value, result);
12461246
} else {
1247-
zend_value_error("Array must contain at least one element");
1247+
zend_argument_value_error(1, "must contain at least one element");
12481248
RETURN_THROWS();
12491249
}
12501250
}
@@ -3718,7 +3718,7 @@ static zend_always_inline void php_array_replace_wrapper(INTERNAL_FUNCTION_PARAM
37183718
zval *arg = args + i;
37193719

37203720
if (Z_TYPE_P(arg) != IS_ARRAY) {
3721-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
3721+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(arg));
37223722
RETURN_THROWS();
37233723
}
37243724
}
@@ -3762,7 +3762,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
37623762
zval *arg = args + i;
37633763

37643764
if (Z_TYPE_P(arg) != IS_ARRAY) {
3765-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
3765+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(arg));
37663766
RETURN_THROWS();
37673767
}
37683768
count += zend_hash_num_elements(Z_ARRVAL_P(arg));
@@ -4654,7 +4654,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
46544654

46554655
for (i = 0; i < argc; i++) {
46564656
if (Z_TYPE(args[i]) != IS_ARRAY) {
4657-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
4657+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
46584658
RETURN_THROWS();
46594659
}
46604660
}
@@ -4819,7 +4819,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
48194819

48204820
for (i = 0; i < arr_argc; i++) {
48214821
if (Z_TYPE(args[i]) != IS_ARRAY) {
4822-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
4822+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
48234823
arr_argc = i; /* only free up to i - 1 */
48244824
goto out;
48254825
}
@@ -5061,7 +5061,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
50615061

50625062
for (i = 0; i < argc; i++) {
50635063
if (Z_TYPE(args[i]) != IS_ARRAY) {
5064-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5064+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
50655065
RETURN_THROWS();
50665066
}
50675067
}
@@ -5226,7 +5226,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
52265226

52275227
for (i = 0; i < arr_argc; i++) {
52285228
if (Z_TYPE(args[i]) != IS_ARRAY) {
5229-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5229+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
52305230
arr_argc = i; /* only free up to i - 1 */
52315231
goto out;
52325232
}
@@ -5405,15 +5405,15 @@ PHP_FUNCTION(array_diff)
54055405
ZEND_PARSE_PARAMETERS_END();
54065406

54075407
if (Z_TYPE(args[0]) != IS_ARRAY) {
5408-
zend_type_error("Expected parameter 1 to be an array, %s given", zend_zval_type_name(&args[0]));
5408+
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_type_name(&args[0]));
54095409
RETURN_THROWS();
54105410
}
54115411

54125412
num = zend_hash_num_elements(Z_ARRVAL(args[0]));
54135413
if (num == 0) {
54145414
for (i = 1; i < argc; i++) {
54155415
if (Z_TYPE(args[i]) != IS_ARRAY) {
5416-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5416+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
54175417
RETURN_THROWS();
54185418
}
54195419
}
@@ -5430,7 +5430,7 @@ PHP_FUNCTION(array_diff)
54305430
if (!value) {
54315431
for (i = 1; i < argc; i++) {
54325432
if (Z_TYPE(args[i]) != IS_ARRAY) {
5433-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5433+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
54345434
RETURN_THROWS();
54355435
}
54365436
}
@@ -5441,7 +5441,7 @@ PHP_FUNCTION(array_diff)
54415441

54425442
for (i = 1; i < argc; i++) {
54435443
if (Z_TYPE(args[i]) != IS_ARRAY) {
5444-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5444+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
54455445
RETURN_THROWS();
54465446
}
54475447
if (!found) {
@@ -5471,7 +5471,7 @@ PHP_FUNCTION(array_diff)
54715471
num = 0;
54725472
for (i = 1; i < argc; i++) {
54735473
if (Z_TYPE(args[i]) != IS_ARRAY) {
5474-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5474+
zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_type_name(&args[i]));
54755475
RETURN_THROWS();
54765476
}
54775477
num += zend_hash_num_elements(Z_ARRVAL(args[i]));
@@ -5656,7 +5656,7 @@ PHP_FUNCTION(array_multisort)
56565656
sort_order = Z_LVAL_P(arg) == PHP_SORT_DESC ? PHP_SORT_DESC : PHP_SORT_ASC;
56575657
parse_state[MULTISORT_ORDER] = 0;
56585658
} else {
5659-
zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
5659+
zend_argument_type_error(i + 1, "must be an array or a sort flag that has not already been specified");
56605660
MULTISORT_ABORT;
56615661
}
56625662
break;
@@ -5672,19 +5672,19 @@ PHP_FUNCTION(array_multisort)
56725672
sort_type = (int)Z_LVAL_P(arg);
56735673
parse_state[MULTISORT_TYPE] = 0;
56745674
} else {
5675-
zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
5675+
zend_argument_type_error(i + 1, "must be an array or a sort flag that has not already been specified");
56765676
MULTISORT_ABORT;
56775677
}
56785678
break;
56795679

56805680
default:
5681-
zend_type_error("Argument #%d is an unknown sort flag", i + 1);
5681+
zend_argument_value_error(i + 1, "must be a valid sort flag");
56825682
MULTISORT_ABORT;
56835683
break;
56845684

56855685
}
56865686
} else {
5687-
zend_type_error("Argument #%d is expected to be an array or a sort flag", i + 1);
5687+
zend_argument_type_error(i + 1, "must be an array or a sort flag");
56885688
MULTISORT_ABORT;
56895689
}
56905690
}
@@ -6120,7 +6120,7 @@ PHP_FUNCTION(array_map)
61206120
int ret;
61216121

61226122
if (Z_TYPE(arrays[0]) != IS_ARRAY) {
6123-
zend_type_error("Expected parameter 2 to be an array, %s given", zend_zval_type_name(&arrays[0]));
6123+
zend_argument_type_error(2, "must be of type array, %s given", zend_zval_type_name(&arrays[0]));
61246124
RETURN_THROWS();
61256125
}
61266126
maxlen = zend_hash_num_elements(Z_ARRVAL(arrays[0]));
@@ -6161,7 +6161,7 @@ PHP_FUNCTION(array_map)
61616161

61626162
for (i = 0; i < n_arrays; i++) {
61636163
if (Z_TYPE(arrays[i]) != IS_ARRAY) {
6164-
zend_type_error("Expected parameter %d to be an array, %s given", i + 2, zend_zval_type_name(&arrays[i]));
6164+
zend_argument_type_error(i + 2, "must be of type array, %s given", zend_zval_type_name(&arrays[i]));
61656165
efree(array_pos);
61666166
RETURN_THROWS();
61676167
}
@@ -6291,7 +6291,7 @@ PHP_FUNCTION(array_key_exists)
62916291
RETVAL_BOOL(zend_hash_index_exists(ht, Z_RES_HANDLE_P(key)));
62926292
break;
62936293
default:
6294-
zend_type_error("Illegal offset type");
6294+
zend_argument_type_error(1, "must be a valid array offset type");
62956295
break;
62966296
}
62976297
}

ext/standard/basic_functions.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,7 @@ PHP_FUNCTION(sleep)
19381938
ZEND_PARSE_PARAMETERS_END();
19391939

19401940
if (num < 0) {
1941-
zend_value_error("Number of seconds must be greater than or equal to 0");
1941+
zend_argument_value_error(1, "must be greater than or equal to 0");
19421942
RETURN_THROWS();
19431943
}
19441944

@@ -1958,7 +1958,7 @@ PHP_FUNCTION(usleep)
19581958
ZEND_PARSE_PARAMETERS_END();
19591959

19601960
if (num < 0) {
1961-
zend_value_error("Number of microseconds must be greater than or equal to 0");
1961+
zend_argument_value_error(1, "must be greater than or equal to 0");
19621962
RETURN_THROWS();
19631963
}
19641964
if (usleep((unsigned int)num) < 0) {
@@ -1985,11 +1985,11 @@ PHP_FUNCTION(time_nanosleep)
19851985
ZEND_PARSE_PARAMETERS_END();
19861986

19871987
if (tv_sec < 0) {
1988-
zend_value_error("The seconds value must be greater than 0");
1988+
zend_argument_value_error(1, "must be greater than or equal to 0");
19891989
RETURN_THROWS();
19901990
}
19911991
if (tv_nsec < 0) {
1992-
zend_value_error("The nanoseconds value must be greater than 0");
1992+
zend_argument_value_error(2, "must be greater than or equal to 0");
19931993
RETURN_THROWS();
19941994
}
19951995

ext/standard/exec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ PHP_FUNCTION(escapeshellcmd)
484484

485485
if (command_len) {
486486
if (command_len != strlen(command)) {
487-
zend_type_error("Input string contains NULL bytes");
487+
zend_argument_type_error(1, "must not contain any null bytes");
488488
RETURN_THROWS();
489489
}
490490
RETVAL_STR(php_escape_shell_cmd(command));
@@ -506,7 +506,7 @@ PHP_FUNCTION(escapeshellarg)
506506
ZEND_PARSE_PARAMETERS_END();
507507

508508
if (argument_len != strlen(argument)) {
509-
zend_type_error("Input string contains NULL bytes");
509+
zend_argument_type_error(1, "must not contain any null bytes");
510510
RETURN_THROWS();
511511
}
512512

ext/standard/file.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ PHP_FUNCTION(file_get_contents)
543543
ZEND_PARSE_PARAMETERS_END();
544544

545545
if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
546-
zend_value_error("Length must be greater than or equal to zero");
546+
zend_argument_value_error(5, "must be greater than or equal to 0");
547547
RETURN_THROWS();
548548
}
549549

@@ -1040,7 +1040,7 @@ PHPAPI PHP_FUNCTION(fgets)
10401040
efree(buf);
10411041
} else if (argc > 1) {
10421042
if (len <= 0) {
1043-
zend_value_error("Length parameter must be greater than 0");
1043+
zend_argument_value_error(2, "must be greater than 0");
10441044
RETURN_THROWS();
10451045
}
10461046

@@ -1750,7 +1750,7 @@ PHPAPI PHP_FUNCTION(fread)
17501750
PHP_STREAM_TO_ZVAL(stream, res);
17511751

17521752
if (len <= 0) {
1753-
zend_value_error("Length parameter must be greater than 0");
1753+
zend_argument_value_error(2, "must be greater than 0");
17541754
RETURN_THROWS();
17551755
}
17561756

@@ -1829,7 +1829,7 @@ PHP_FUNCTION(fputcsv)
18291829
if (delimiter_str != NULL) {
18301830
/* Make sure that there is at least one character in string */
18311831
if (delimiter_str_len < 1) {
1832-
zend_value_error("delimiter must be a character");
1832+
zend_argument_value_error(3, "must be a single character");
18331833
RETURN_THROWS();
18341834
} else if (delimiter_str_len > 1) {
18351835
php_error_docref(NULL, E_NOTICE, "delimiter must be a single character");
@@ -1841,7 +1841,7 @@ PHP_FUNCTION(fputcsv)
18411841

18421842
if (enclosure_str != NULL) {
18431843
if (enclosure_str_len < 1) {
1844-
zend_value_error("enclosure must be a character");
1844+
zend_argument_value_error(4, "must be a single character");
18451845
RETURN_THROWS();
18461846
} else if (enclosure_str_len > 1) {
18471847
php_error_docref(NULL, E_NOTICE, "enclosure must be a single character");
@@ -1967,7 +1967,7 @@ PHP_FUNCTION(fgetcsv)
19671967
if (delimiter_str != NULL) {
19681968
/* Make sure that there is at least one character in string */
19691969
if (delimiter_str_len < 1) {
1970-
zend_value_error("delimiter must be a character");
1970+
zend_argument_value_error(3, "must be a single character");
19711971
RETURN_THROWS();
19721972
} else if (delimiter_str_len > 1) {
19731973
php_error_docref(NULL, E_NOTICE, "delimiter must be a single character");
@@ -1979,7 +1979,7 @@ PHP_FUNCTION(fgetcsv)
19791979

19801980
if (enclosure_str != NULL) {
19811981
if (enclosure_str_len < 1) {
1982-
zend_value_error("enclosure must be a character");
1982+
zend_argument_value_error(4, "must be a single character");
19831983
RETURN_THROWS();
19841984
} else if (enclosure_str_len > 1) {
19851985
php_error_docref(NULL, E_NOTICE, "enclosure must be a single character");
@@ -2004,7 +2004,7 @@ PHP_FUNCTION(fgetcsv)
20042004
if (len_zv != NULL && Z_TYPE_P(len_zv) != IS_NULL) {
20052005
len = zval_get_long(len_zv);
20062006
if (len < 0) {
2007-
zend_value_error("Length parameter may not be negative");
2007+
zend_argument_value_error(2, "must be a greater than or equal to 0");
20082008
RETURN_THROWS();
20092009
} else if (len == 0) {
20102010
len = -1;

0 commit comments

Comments
 (0)