Skip to content

Commit ecbecb6

Browse files
committed
Improve argument error messages of ext/standard
1 parent 6e40ec7 commit ecbecb6

20 files changed

+104
-79
lines changed

Zend/zend_API.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,32 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *erro
267267
}
268268
/* }}} */
269269

270+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_type_error(uint32_t arg_num, const char *format, ...) /* {{{ */
271+
{
272+
va_list va;
273+
char *message = NULL;
274+
275+
va_start(va, format);
276+
zend_vspprintf(&message, 0, format, va);
277+
zend_argument_error(zend_ce_type_error, arg_num, message, 0);
278+
efree(message);
279+
va_end(va);
280+
}
281+
/* }}} */
282+
283+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num, const char *format, ...) /* {{{ */
284+
{
285+
va_list va;
286+
char *message = NULL;
287+
288+
va_start(va, format);
289+
zend_vspprintf(&message, 0, format, va);
290+
zend_argument_error(zend_ce_value_error, arg_num, message, 0);
291+
efree(message);
292+
va_end(va);
293+
}
294+
/* }}} */
295+
270296
ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
271297
{
272298
zend_class_entry *ce_base = *pce;

Zend/zend_API.h

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

11601158
#define ZPP_ERROR_OK 0
11611159
#define ZPP_ERROR_FAILURE 1

ext/standard/array.c

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

12641264
if (Z_TYPE(args[0]) != IS_ARRAY) {
1265-
zend_type_error("When only one parameter is given, it must be an array");
1265+
zend_argument_type_error(1, "to be of type array, %s given", zend_zval_type_name(&args[0]));
12661266
RETURN_THROWS();
12671267
} else {
12681268
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 0)) != NULL) {
12691269
ZVAL_COPY_DEREF(return_value, result);
12701270
} else {
1271-
zend_value_error("Array must contain at least one element");
1271+
zend_argument_value_error(1, "to contain at least one element");
12721272
RETURN_THROWS();
12731273
}
12741274
}
@@ -1309,13 +1309,13 @@ PHP_FUNCTION(max)
13091309
zval *result;
13101310

13111311
if (Z_TYPE(args[0]) != IS_ARRAY) {
1312-
zend_type_error("When only one parameter is given, it must be an array");
1312+
zend_argument_type_error(1, "to be of type array, %s given", zend_zval_type_name(&args[0]));
13131313
RETURN_THROWS();
13141314
} else {
13151315
if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 1)) != NULL) {
13161316
ZVAL_COPY_DEREF(return_value, result);
13171317
} else {
1318-
zend_value_error("Array must contain at least one element");
1318+
zend_argument_value_error(1, "to contain at least one element");
13191319
RETURN_THROWS();
13201320
}
13211321
}
@@ -3789,7 +3789,7 @@ static zend_always_inline void php_array_replace_wrapper(INTERNAL_FUNCTION_PARAM
37893789
zval *arg = args + i;
37903790

37913791
if (Z_TYPE_P(arg) != IS_ARRAY) {
3792-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
3792+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(arg));
37933793
RETURN_THROWS();
37943794
}
37953795
}
@@ -3833,7 +3833,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
38333833
zval *arg = args + i;
38343834

38353835
if (Z_TYPE_P(arg) != IS_ARRAY) {
3836-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(arg));
3836+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(arg));
38373837
RETURN_THROWS();
38383838
}
38393839
count += zend_hash_num_elements(Z_ARRVAL_P(arg));
@@ -4725,7 +4725,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
47254725

47264726
for (i = 0; i < argc; i++) {
47274727
if (Z_TYPE(args[i]) != IS_ARRAY) {
4728-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
4728+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
47294729
RETURN_THROWS();
47304730
}
47314731
}
@@ -4890,7 +4890,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
48904890

48914891
for (i = 0; i < arr_argc; i++) {
48924892
if (Z_TYPE(args[i]) != IS_ARRAY) {
4893-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
4893+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
48944894
arr_argc = i; /* only free up to i - 1 */
48954895
goto out;
48964896
}
@@ -5130,7 +5130,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
51305130

51315131
for (i = 0; i < argc; i++) {
51325132
if (Z_TYPE(args[i]) != IS_ARRAY) {
5133-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5133+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
51345134
RETURN_THROWS();
51355135
}
51365136
}
@@ -5295,7 +5295,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
52955295

52965296
for (i = 0; i < arr_argc; i++) {
52975297
if (Z_TYPE(args[i]) != IS_ARRAY) {
5298-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5298+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
52995299
arr_argc = i; /* only free up to i - 1 */
53005300
goto out;
53015301
}
@@ -5472,15 +5472,15 @@ PHP_FUNCTION(array_diff)
54725472
ZEND_PARSE_PARAMETERS_END();
54735473

54745474
if (Z_TYPE(args[0]) != IS_ARRAY) {
5475-
zend_type_error("Expected parameter 1 to be an array, %s given", zend_zval_type_name(&args[0]));
5475+
zend_argument_type_error(1, "to be of type array, %s given", zend_zval_type_name(&args[0]));
54765476
RETURN_THROWS();
54775477
}
54785478

54795479
num = zend_hash_num_elements(Z_ARRVAL(args[0]));
54805480
if (num == 0) {
54815481
for (i = 1; i < argc; i++) {
54825482
if (Z_TYPE(args[i]) != IS_ARRAY) {
5483-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5483+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
54845484
RETURN_THROWS();
54855485
}
54865486
}
@@ -5497,7 +5497,7 @@ PHP_FUNCTION(array_diff)
54975497
if (!value) {
54985498
for (i = 1; i < argc; i++) {
54995499
if (Z_TYPE(args[i]) != IS_ARRAY) {
5500-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5500+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
55015501
RETURN_THROWS();
55025502
}
55035503
}
@@ -5508,7 +5508,7 @@ PHP_FUNCTION(array_diff)
55085508

55095509
for (i = 1; i < argc; i++) {
55105510
if (Z_TYPE(args[i]) != IS_ARRAY) {
5511-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5511+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
55125512
RETURN_THROWS();
55135513
}
55145514
if (!found) {
@@ -5538,7 +5538,7 @@ PHP_FUNCTION(array_diff)
55385538
num = 0;
55395539
for (i = 1; i < argc; i++) {
55405540
if (Z_TYPE(args[i]) != IS_ARRAY) {
5541-
zend_type_error("Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));
5541+
zend_argument_type_error(i + 1, "to be of type array, %s given", zend_zval_type_name(&args[i]));
55425542
RETURN_THROWS();
55435543
}
55445544
num += zend_hash_num_elements(Z_ARRVAL(args[i]));
@@ -5723,7 +5723,7 @@ PHP_FUNCTION(array_multisort)
57235723
sort_order = Z_LVAL_P(arg) == PHP_SORT_DESC ? PHP_SORT_DESC : PHP_SORT_ASC;
57245724
parse_state[MULTISORT_ORDER] = 0;
57255725
} else {
5726-
zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
5726+
zend_argument_type_error(i + 1, "to be an array or a sort flag that has not already been specified");
57275727
MULTISORT_ABORT;
57285728
}
57295729
break;
@@ -5739,19 +5739,19 @@ PHP_FUNCTION(array_multisort)
57395739
sort_type = (int)Z_LVAL_P(arg);
57405740
parse_state[MULTISORT_TYPE] = 0;
57415741
} else {
5742-
zend_type_error("Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
5742+
zend_argument_type_error(i + 1, "to be an array or a sort flag that has not already been specified");
57435743
MULTISORT_ABORT;
57445744
}
57455745
break;
57465746

57475747
default:
5748-
zend_type_error("Argument #%d is an unknown sort flag", i + 1);
5748+
zend_argument_value_error(i + 1, "to be a valid sort flag");
57495749
MULTISORT_ABORT;
57505750
break;
57515751

57525752
}
57535753
} else {
5754-
zend_type_error("Argument #%d is expected to be an array or a sort flag", i + 1);
5754+
zend_argument_type_error(i + 1, "to be an array or a sort flag");
57555755
MULTISORT_ABORT;
57565756
}
57575757
}
@@ -6187,7 +6187,7 @@ PHP_FUNCTION(array_map)
61876187
int ret;
61886188

61896189
if (Z_TYPE(arrays[0]) != IS_ARRAY) {
6190-
zend_type_error("Expected parameter 2 to be an array, %s given", zend_zval_type_name(&arrays[0]));
6190+
zend_argument_type_error(2, "to be of type array, %s given", zend_zval_type_name(&arrays[0]));
61916191
RETURN_THROWS();
61926192
}
61936193
maxlen = zend_hash_num_elements(Z_ARRVAL(arrays[0]));
@@ -6228,7 +6228,7 @@ PHP_FUNCTION(array_map)
62286228

62296229
for (i = 0; i < n_arrays; i++) {
62306230
if (Z_TYPE(arrays[i]) != IS_ARRAY) {
6231-
zend_type_error("Expected parameter %d to be an array, %s given", i + 2, zend_zval_type_name(&arrays[i]));
6231+
zend_argument_type_error(i + 2, "to be of type array, %s given", zend_zval_type_name(&arrays[i]));
62326232
efree(array_pos);
62336233
RETURN_THROWS();
62346234
}
@@ -6358,7 +6358,7 @@ PHP_FUNCTION(array_key_exists)
63586358
RETVAL_BOOL(zend_hash_index_exists(ht, Z_RES_HANDLE_P(key)));
63596359
break;
63606360
default:
6361-
zend_type_error("Illegal offset type");
6361+
zend_argument_type_error(1, "to be a valid array offset type");
63626362
break;
63636363
}
63646364
}

ext/standard/basic_functions.c

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

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

@@ -1957,7 +1957,7 @@ PHP_FUNCTION(usleep)
19571957
ZEND_PARSE_PARAMETERS_END();
19581958

19591959
if (num < 0) {
1960-
zend_value_error("Number of microseconds must be greater than or equal to 0");
1960+
zend_argument_value_error(1, "to be greater than or equal to 0");
19611961
RETURN_THROWS();
19621962
}
19631963
if (usleep((unsigned int)num) < 0) {
@@ -1984,11 +1984,11 @@ PHP_FUNCTION(time_nanosleep)
19841984
ZEND_PARSE_PARAMETERS_END();
19851985

19861986
if (tv_sec < 0) {
1987-
zend_value_error("The seconds value must be greater than 0");
1987+
zend_argument_value_error(1, "to be greater than or equal to 0");
19881988
RETURN_THROWS();
19891989
}
19901990
if (tv_nsec < 0) {
1991-
zend_value_error("The nanoseconds value must be greater than 0");
1991+
zend_argument_value_error(2, "to be greater than or equal to 0");
19921992
RETURN_THROWS();
19931993
}
19941994

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, "to not contain null bytes"); // TODO: ???
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, "to not contain 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, "to 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, "to 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, "to 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, "to 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, "to 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, "to 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, "to 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, "to be a greater than or equal to 0");
20082008
RETURN_THROWS();
20092009
} else if (len == 0) {
20102010
len = -1;

ext/standard/filestat.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */
353353
option = PHP_STREAM_META_GROUP_NAME;
354354
value = Z_STRVAL_P(group);
355355
} else {
356-
zend_type_error("chgrp() expects argument #2 ($group) to be of type string|int, %s given", zend_zval_type_name(group));
356+
zend_argument_type_error(2, "to be of type string|int, %s given", zend_zval_type_name(group));
357357
RETURN_THROWS();
358358
}
359359
if(wrapper->wops->stream_metadata(wrapper, filename, option, value, NULL)) {
@@ -382,7 +382,7 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */
382382
RETURN_FALSE;
383383
}
384384
} else {
385-
zend_type_error("chgrp() expects argument #2 ($group) to be of type string|int, %s given", zend_zval_type_name(group));
385+
zend_argument_type_error(2, "to be of type string|int, %s given", zend_zval_type_name(group));
386386
RETURN_THROWS();
387387
}
388388

ext/standard/math.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ PHP_FUNCTION(log)
623623
}
624624

625625
if (base <= 0.0) {
626-
zend_value_error("Base must be greater than 0");
626+
zend_argument_value_error(2, "to be greater than 0");
627627
RETURN_THROWS();
628628
}
629629

ext/standard/password.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ PHP_FUNCTION(password_hash)
669669
algo = php_password_algo_find_zval(zalgo);
670670
if (!algo) {
671671
zend_string *algostr = zval_get_string(zalgo);
672-
zend_value_error("Unknown password hashing algorithm: %s", ZSTR_VAL(algostr));
672+
zend_argument_value_error(2, "to be a valid password hashing algorithm, \"%s\" given", ZSTR_VAL(algostr));
673673
zend_string_release(algostr);
674674
RETURN_THROWS();
675675
}

0 commit comments

Comments
 (0)