summaryrefslogtreecommitdiff
path: root/Zend/zend_API.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-09-08 12:12:26 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-09-08 15:23:23 +0200
commit7e339a335e87d9c8d0b6994039220890284df63e (patch)
tree4f4445f74094e6c614e1f536024be68f20518d37 /Zend/zend_API.c
parent2386f655d8181456c66241fd8ceb008bd995a31c (diff)
downloadphp-git-7e339a335e87d9c8d0b6994039220890284df63e.tar.gz
Make null byte error a ValueError
Currently we treat paths with null bytes as a TypeError, which is incorrect, and rather inconsistent, as we treat empty paths as ValueError. We do this because the error is generated by zpp and it's easier to always throw TypeError there. This changes the zpp implementation to throw a TypeError only if the type is actually wrong and throw ValueError for null bytes. The error message is also split accordingly, to be more precise. Closes GH-6094.
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r--Zend/zend_API.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index cc31a81a1c..a8aedeb964 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -254,6 +254,12 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t n
return;
}
+ if ((expected_type == Z_EXPECTED_PATH || expected_type == Z_EXPECTED_PATH_OR_NULL)
+ && Z_TYPE_P(arg) == IS_STRING) {
+ zend_argument_value_error(num, "must not contain any null bytes");
+ return;
+ }
+
zend_argument_type_error(num, "must be %s, %s given", expected_error[expected_type], zend_zval_type_name(arg));
}
/* }}} */
@@ -668,10 +674,12 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
char **p = va_arg(*va, char **);
size_t *pl = va_arg(*va, size_t *);
if (!zend_parse_arg_path(arg, p, pl, check_null)) {
- zend_spprintf(error, 0, "a valid path%s, %s given",
- check_null ? " or null" : "", zend_zval_type_name(arg)
- );
- return "";
+ if (Z_TYPE_P(arg) == IS_STRING) {
+ zend_spprintf(error, 0, "must not contain any null bytes");
+ return "";
+ } else {
+ return check_null ? "?string" : "string";
+ }
}
}
break;
@@ -680,10 +688,12 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
{
zend_string **str = va_arg(*va, zend_string **);
if (!zend_parse_arg_path_str(arg, str, check_null)) {
- zend_spprintf(error, 0, "a valid path%s, %s given",
- check_null ? " or null" : "", zend_zval_type_name(arg)
- );
- return "";
+ if (Z_TYPE_P(arg) == IS_STRING) {
+ zend_spprintf(error, 0, "must not contain any null bytes");
+ return "";
+ } else {
+ return check_null ? "?string" : "string";
+ }
}
}
break;
@@ -762,7 +772,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
if (!zend_parse_arg_object(arg, p, ce, check_null)) {
if (ce) {
if (check_null) {
- zend_spprintf(error, 0, "of type ?%s, %s given", ZSTR_VAL(ce->name), zend_zval_type_name(arg));
+ zend_spprintf(error, 0, "must be of type ?%s, %s given", ZSTR_VAL(ce->name), zend_zval_type_name(arg));
return "";
} else {
return ZSTR_VAL(ce->name);
@@ -795,14 +805,14 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
}
if (ce_base) {
if ((!*pce || !instanceof_function(*pce, ce_base))) {
- zend_spprintf(error, 0, "a class name derived from %s%s, %s given",
+ zend_spprintf(error, 0, "must be a class name derived from %s%s, %s given",
ZSTR_VAL(ce_base->name), check_null ? " or null" : "", Z_STRVAL_P(arg));
*pce = NULL;
return "";
}
}
if (!*pce) {
- zend_spprintf(error, 0, "a valid class name%s, %s given",
+ zend_spprintf(error, 0, "must be a valid class name%s, %s given",
check_null ? " or null" : "", Z_STRVAL_P(arg));
return "";
}
@@ -833,7 +843,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
}
if (is_callable_error) {
- zend_spprintf(error, 0, "a valid callback%s, %s", check_null ? " or null" : "", is_callable_error);
+ zend_spprintf(error, 0, "must be a valid callback%s, %s", check_null ? " or null" : "", is_callable_error);
efree(is_callable_error);
return "";
} else {
@@ -874,7 +884,11 @@ static zend_result zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, cons
}
if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
if (error) {
- zend_argument_type_error(arg_num, "must be %s", error);
+ if (strcmp(error, "must not contain any null bytes") == 0) {
+ zend_argument_value_error(arg_num, "%s", error);
+ } else {
+ zend_argument_type_error(arg_num, "%s", error);
+ }
efree(error);
} else {
zend_argument_type_error(arg_num, "must be of type %s, %s given", expected_type, zend_zval_type_name(arg));