Skip to content

Commit abadbf3

Browse files
committed
Make zpp failures always throw, independent of strict_types
Previously zend_parse_parameters (and FastZPP) would handle invalid arguments depending on strict_types: With strict_types=1, a TypeError is thrown, with strict_types=0 a warning is thrown and (usually) NULL is returned. Additionally, some functions (constructors always and other methods sometimes) opt-it to throwing regardless of strict_types. This commit changes zpp to always generate an Error exception in PHP 8. Even with some of the zpp variation tests removed in php#3783, this is going to need a lot of test updates, as many tests are also testing zpp failures. I haven't really started on this yet.
1 parent a2343d1 commit abadbf3

File tree

11 files changed

+52
-216
lines changed

11 files changed

+52
-216
lines changed

Zend/tests/004.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ strncmp() tests
33
--FILE--
44
<?php
55

6-
var_dump(strncmp("", ""));
76
var_dump(strncmp("", "", 100));
87
var_dump(strncmp("aef", "dfsgbdf", -1));
98
var_dump(strncmp("fghjkl", "qwer", 0));
@@ -13,8 +12,6 @@ var_dump(strncmp("qwerty", "qwerty123", 7));
1312
echo "Done\n";
1413
?>
1514
--EXPECTF--
16-
Warning: strncmp() expects exactly 3 parameters, 2 given in %s on line %d
17-
NULL
1815
int(0)
1916

2017
Warning: Length must be greater than or equal to 0 in %s on line %d

Zend/tests/005.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ strcasecmp() tests
33
--FILE--
44
<?php
55

6-
var_dump(strcasecmp(""));
76
var_dump(strcasecmp("", ""));
87
var_dump(strcasecmp("aef", "dfsgbdf"));
98
var_dump(strcasecmp("qwe", "qwer"));
@@ -15,8 +14,6 @@ var_dump(strcasecmp("01", "01"));
1514
echo "Done\n";
1615
?>
1716
--EXPECTF--
18-
Warning: strcasecmp() expects exactly 2 parameters, 1 given in %s on line %d
19-
NULL
2017
int(0)
2118
int(-3)
2219
int(-1)

Zend/tests/006.phpt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ strncasecmp() tests
33
--FILE--
44
<?php
55

6-
var_dump(strncasecmp(""));
76
var_dump(strncasecmp("", "", -1));
87
var_dump(strncasecmp("aef", "dfsgbdf", 0));
98
var_dump(strncasecmp("aef", "dfsgbdf", 10));
@@ -16,9 +15,6 @@ var_dump(strncasecmp("01", "01", 1000));
1615
echo "Done\n";
1716
?>
1817
--EXPECTF--
19-
Warning: strncasecmp() expects exactly 3 parameters, 1 given in %s on line %d
20-
NULL
21-
2218
Warning: Length must be greater than or equal to 0 in %s on line %d
2319
bool(false)
2420
int(0)

Zend/tests/008.phpt

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ define() tests
33
--FILE--
44
<?php
55

6-
var_dump(define());
7-
var_dump(define("TRUE"));
8-
var_dump(define("TRUE", 1));
9-
var_dump(define("TRUE", 1, array(1)));
6+
try {
7+
var_dump(define(array(1,2,3,4,5), 1));
8+
} catch (TypeError $e) {
9+
echo "TypeError: ", $e->getMessage(), "\n";
10+
}
1011

11-
var_dump(define(array(1,2,3,4,5), 1));
12+
var_dump(define("TRUE", 1));
1213
var_dump(define(" ", 1));
1314
var_dump(define("[[[", 2));
1415
var_dump(define("test const", 3));
@@ -24,20 +25,10 @@ var_dump(constant("test const"));
2425
echo "Done\n";
2526
?>
2627
--EXPECTF--
27-
Warning: define() expects at least 2 parameters, 0 given in %s on line %d
28-
NULL
29-
30-
Warning: define() expects at least 2 parameters, 1 given in %s on line %d
31-
NULL
28+
TypeError: define() expects parameter 1 to be string, array given
3229

3330
Notice: Constant TRUE already defined in %s on line %d
3431
bool(false)
35-
36-
Warning: define() expects parameter 3 to be bool, array given in %s on line %d
37-
NULL
38-
39-
Warning: define() expects parameter 1 to be string, array given in %s on line %d
40-
NULL
4132
bool(true)
4233
bool(true)
4334
bool(true)

Zend/zend.c

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,35 +1528,14 @@ ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
15281528
va_end(va);
15291529
} /* }}} */
15301530

1531-
ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
1531+
ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) /* {{{ */
15321532
{
15331533
va_list va;
15341534
char *message = NULL;
15351535

15361536
va_start(va, format);
15371537
zend_vspprintf(&message, 0, format, va);
1538-
if (throw_exception) {
1539-
zend_throw_exception(zend_ce_type_error, message, 0);
1540-
} else {
1541-
zend_error(E_WARNING, "%s", message);
1542-
}
1543-
efree(message);
1544-
1545-
va_end(va);
1546-
} /* }}} */
1547-
1548-
ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
1549-
{
1550-
va_list va;
1551-
char *message = NULL;
1552-
1553-
va_start(va, format);
1554-
zend_vspprintf(&message, 0, format, va);
1555-
if (throw_exception) {
1556-
zend_throw_exception(zend_ce_argument_count_error, message, 0);
1557-
} else {
1558-
zend_error(E_WARNING, "%s", message);
1559-
}
1538+
zend_throw_exception(zend_ce_argument_count_error, message, 0);
15601539
efree(message);
15611540

15621541
va_end(va);

Zend/zend.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ extern ZEND_API void (*zend_post_shutdown_cb)(void);
303303
ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
304304
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
305305
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
306-
ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
307-
ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
306+
ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
308307

309308
ZEND_COLD void zenderror(const char *error);
310309

Zend/zend_API.c

Lines changed: 11 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ZEND_API ZEND_COLD void zend_wrong_param_count(void) /* {{{ */
9090
const char *space;
9191
const char *class_name = get_active_class_name(&space);
9292

93-
zend_internal_argument_count_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
93+
zend_argument_count_error("Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
9494
}
9595
/* }}} */
9696

@@ -167,34 +167,13 @@ ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */
167167
}
168168
/* }}} */
169169

170-
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_error(void) /* {{{ */
171-
{
172-
int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
173-
zend_function *active_function = EG(current_execute_data)->func;
174-
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
175-
176-
zend_internal_argument_count_error(
177-
ZEND_ARG_USES_STRICT_TYPES(),
178-
"%s%s%s() expects %s %d parameter%s, %d given",
179-
class_name, \
180-
class_name[0] ? "::" : "", \
181-
ZSTR_VAL(active_function->common.function_name),
182-
"exactly",
183-
0,
184-
"s",
185-
num_args);
186-
return FAILURE;
187-
}
188-
/* }}} */
189-
190170
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void) /* {{{ */
191171
{
192172
int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
193173
zend_function *active_function = EG(current_execute_data)->func;
194174
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
195175

196-
zend_internal_argument_count_error(
197-
1,
176+
zend_argument_count_error(
198177
"%s%s%s() expects %s %d parameter%s, %d given",
199178
class_name, \
200179
class_name[0] ? "::" : "", \
@@ -207,33 +186,13 @@ ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void)
207186
}
208187
/* }}} */
209188

210-
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int min_num_args, int max_num_args) /* {{{ */
211-
{
212-
int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
213-
zend_function *active_function = EG(current_execute_data)->func;
214-
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
215-
216-
zend_internal_argument_count_error(
217-
ZEND_ARG_USES_STRICT_TYPES(),
218-
"%s%s%s() expects %s %d parameter%s, %d given",
219-
class_name, \
220-
class_name[0] ? "::" : "", \
221-
ZSTR_VAL(active_function->common.function_name),
222-
min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
223-
num_args < min_num_args ? min_num_args : max_num_args,
224-
(num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
225-
num_args);
226-
}
227-
/* }}} */
228-
229189
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int min_num_args, int max_num_args) /* {{{ */
230190
{
231191
int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
232192
zend_function *active_function = EG(current_execute_data)->func;
233193
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
234194

235-
zend_internal_argument_count_error(
236-
1,
195+
zend_argument_count_error(
237196
"%s%s%s() expects %s %d parameter%s, %d given",
238197
class_name, \
239198
class_name[0] ? "::" : "", \
@@ -245,20 +204,6 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int
245204
}
246205
/* }}} */
247206

248-
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
249-
{
250-
const char *space;
251-
const char *class_name = get_active_class_name(&space);
252-
static const char * const expected_error[] = {
253-
Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR)
254-
NULL
255-
};
256-
257-
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
258-
class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
259-
}
260-
/* }}} */
261-
262207
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
263208
{
264209
const char *space;
@@ -268,48 +213,27 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int nu
268213
NULL
269214
};
270215

271-
zend_internal_type_error(1, "%s%s%s() expects parameter %d to be %s, %s given",
216+
zend_type_error("%s%s%s() expects parameter %d to be %s, %s given",
272217
class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
273218
}
274219
/* }}} */
275220

276-
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg) /* {{{ */
277-
{
278-
const char *space;
279-
const char *class_name = get_active_class_name(&space);
280-
281-
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
282-
class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
283-
}
284-
/* }}} */
285-
286221
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_exception(int num, char *name, zval *arg) /* {{{ */
287222
{
288223
const char *space;
289224
const char *class_name = get_active_class_name(&space);
290225

291-
zend_internal_type_error(1, "%s%s%s() expects parameter %d to be %s, %s given",
226+
zend_type_error("%s%s%s() expects parameter %d to be %s, %s given",
292227
class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
293228
}
294229
/* }}} */
295230

296-
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error) /* {{{ */
297-
{
298-
const char *space;
299-
const char *class_name = get_active_class_name(&space);
300-
301-
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
302-
class_name, space, get_active_function_name(), num, error);
303-
efree(error);
304-
}
305-
/* }}} */
306-
307231
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_exception(int num, char *error) /* {{{ */
308232
{
309233
const char *space;
310234
const char *class_name = get_active_class_name(&space);
311235

312-
zend_internal_type_error(1, "%s%s%s() expects parameter %d to be a valid callback, %s",
236+
zend_type_error("%s%s%s() expects parameter %d to be a valid callback, %s",
313237
class_name, space, get_active_function_name(), num, error);
314238
efree(error);
315239
}
@@ -330,7 +254,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pc
330254
const char *space;
331255
const char *class_name = get_active_class_name(&space);
332256

333-
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
257+
zend_type_error("%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
334258
class_name, space, get_active_function_name(), num,
335259
ZSTR_VAL(ce_base->name), Z_STRVAL_P(arg));
336260
*pce = NULL;
@@ -341,7 +265,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pc
341265
const char *space;
342266
const char *class_name = get_active_class_name(&space);
343267

344-
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
268+
zend_type_error("%s%s%s() expects parameter %d to be a valid class name, '%s' given",
345269
class_name, space, get_active_function_name(), num,
346270
Z_STRVAL_P(arg));
347271
return 0;
@@ -803,16 +727,13 @@ static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec
803727
if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
804728
const char *space;
805729
const char *class_name = get_active_class_name(&space);
806-
zend_bool throw_exception =
807-
ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
808730

809731
if (error) {
810-
zend_internal_type_error(throw_exception, "%s%s%s() expects parameter %d %s",
732+
zend_type_error("%s%s%s() expects parameter %d %s",
811733
class_name, space, get_active_function_name(), arg_num, error);
812734
efree(error);
813735
} else {
814-
zend_internal_type_error(throw_exception,
815-
"%s%s%s() expects parameter %d to be %s, %s given",
736+
zend_type_error("%s%s%s() expects parameter %d to be %s, %s given",
816737
class_name, space, get_active_function_name(), arg_num, expected_type,
817738
zend_zval_type_name(arg));
818739
}
@@ -919,8 +840,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
919840
if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
920841
zend_function *active_function = EG(current_execute_data)->func;
921842
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
922-
zend_bool throw_exception = ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
923-
zend_internal_argument_count_error(throw_exception, "%s%s%s() expects %s %d parameter%s, %d given",
843+
zend_argument_count_error("%s%s%s() expects %s %d parameter%s, %d given",
924844
class_name,
925845
class_name[0] ? "::" : "",
926846
ZSTR_VAL(active_function->common.function_name),

0 commit comments

Comments
 (0)