1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix filter_var with callback and explicit REQUIRE_SCALAR

For some reason, FILTER_CALLBACK disables the FILTER_REQUIRE_SCALAR flag that is
normally set by default. While surprising, this is not something we can change.

However, even specifying FILTER_REQUIRE_SCALAR explicitly does not corrently set
this flag. This is because FILTER_CALLBACK zeroes the flags after they have been
populated from the parameters.

We reverse the checks to make explicitly specifying the flag behave as expected.

Closes GH-12203
This commit is contained in:
Ilija Tovilo
2023-09-13 19:01:53 +02:00
parent 45e60e585e
commit c2fb10d2d2
3 changed files with 29 additions and 8 deletions

3
NEWS
View File

@@ -20,6 +20,9 @@ PHP NEWS
- DOM:
. Fix memory leak when setting an invalid DOMDocument encoding. (nielsdos)
- Filter:
. Fix explicit FILTER_REQUIRE_SCALAR with FILTER_CALLBACK (ilutov)
- Iconv:
. Fixed build for NetBSD which still uses the old iconv signature.
(David Carlier)

View File

@@ -551,14 +551,6 @@ static void php_filter_call(
filter = zval_get_long(option);
}
if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
filter_flags = zval_get_long(option);
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
filter_flags |= FILTER_REQUIRE_SCALAR;
}
}
if ((option = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL) {
if (filter != FILTER_CALLBACK) {
if (Z_TYPE_P(option) == IS_ARRAY) {
@@ -569,6 +561,14 @@ static void php_filter_call(
filter_flags = 0;
}
}
if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
filter_flags = zval_get_long(option);
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
filter_flags |= FILTER_REQUIRE_SCALAR;
}
}
}
if (Z_TYPE_P(filtered) == IS_ARRAY) {

View File

@@ -0,0 +1,18 @@
--TEST--
FILTER_CALLBACK with explicit FILTER_REQUIRE_SCALAR
--EXTENSIONS--
filter
--FILE--
<?php
function test($var) {
$callback = function ($var) {
return $var;
};
return filter_var($var, FILTER_CALLBACK, ['options' => $callback, 'flags' => FILTER_REQUIRE_SCALAR]);
}
var_dump(test('test'));
var_dump(test(['test']));
?>
--EXPECT--
string(4) "test"
bool(false)