Skip to content

Commit c2fb10d

Browse files
committedSep 14, 2023
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
1 parent 45e60e5 commit c2fb10d

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed
 

‎NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ PHP NEWS
2020
- DOM:
2121
. Fix memory leak when setting an invalid DOMDocument encoding. (nielsdos)
2222

23+
- Filter:
24+
. Fix explicit FILTER_REQUIRE_SCALAR with FILTER_CALLBACK (ilutov)
25+
2326
- Iconv:
2427
. Fixed build for NetBSD which still uses the old iconv signature.
2528
(David Carlier)

‎ext/filter/filter.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -551,14 +551,6 @@ static void php_filter_call(
551551
filter = zval_get_long(option);
552552
}
553553

554-
if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
555-
filter_flags = zval_get_long(option);
556-
557-
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
558-
filter_flags |= FILTER_REQUIRE_SCALAR;
559-
}
560-
}
561-
562554
if ((option = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL) {
563555
if (filter != FILTER_CALLBACK) {
564556
if (Z_TYPE_P(option) == IS_ARRAY) {
@@ -569,6 +561,14 @@ static void php_filter_call(
569561
filter_flags = 0;
570562
}
571563
}
564+
565+
if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) {
566+
filter_flags = zval_get_long(option);
567+
568+
if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) {
569+
filter_flags |= FILTER_REQUIRE_SCALAR;
570+
}
571+
}
572572
}
573573

574574
if (Z_TYPE_P(filtered) == IS_ARRAY) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
FILTER_CALLBACK with explicit FILTER_REQUIRE_SCALAR
3+
--EXTENSIONS--
4+
filter
5+
--FILE--
6+
<?php
7+
function test($var) {
8+
$callback = function ($var) {
9+
return $var;
10+
};
11+
return filter_var($var, FILTER_CALLBACK, ['options' => $callback, 'flags' => FILTER_REQUIRE_SCALAR]);
12+
}
13+
var_dump(test('test'));
14+
var_dump(test(['test']));
15+
?>
16+
--EXPECT--
17+
string(4) "test"
18+
bool(false)

0 commit comments

Comments
 (0)