Skip to content

Commit 2ffa70b

Browse files
committed
Slightly clean up is_callable implementation
And adjust an error message to line up with the error message used for $callable() in zend_execute.c.
1 parent f3c5d1a commit 2ffa70b

File tree

8 files changed

+48
-60
lines changed

8 files changed

+48
-60
lines changed

Zend/zend_API.c

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3727,63 +3727,51 @@ ZEND_API bool zend_is_callable_at_frame(
37273727

37283728
case IS_ARRAY:
37293729
{
3730-
zval *method = NULL;
3731-
zval *obj = NULL;
3732-
3733-
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
3734-
obj = zend_hash_index_find(Z_ARRVAL_P(callable), 0);
3735-
method = zend_hash_index_find(Z_ARRVAL_P(callable), 1);
3730+
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) != 2) {
3731+
if (error) *error = estrdup("array callback must have exactly two members");
3732+
return 0;
37363733
}
37373734

3738-
do {
3739-
if (obj == NULL || method == NULL) {
3740-
break;
3741-
}
3742-
3743-
ZVAL_DEREF(method);
3744-
if (Z_TYPE_P(method) != IS_STRING) {
3745-
break;
3746-
}
3747-
3748-
ZVAL_DEREF(obj);
3749-
if (Z_TYPE_P(obj) == IS_STRING) {
3750-
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3751-
return 1;
3752-
}
3753-
3754-
if (!zend_is_callable_check_class(Z_STR_P(obj), get_scope(frame), frame, fcc, &strict_class, error)) {
3755-
return 0;
3756-
}
3757-
3758-
} else if (Z_TYPE_P(obj) == IS_OBJECT) {
3735+
zval *obj = zend_hash_index_find(Z_ARRVAL_P(callable), 0);
3736+
zval *method = zend_hash_index_find(Z_ARRVAL_P(callable), 1);
3737+
if (!obj || !method) {
3738+
if (error) *error = estrdup("array callback has to contain indices 0 and 1");
3739+
return 0;
3740+
}
37593741

3760-
fcc->calling_scope = Z_OBJCE_P(obj); /* TBFixed: what if it's overloaded? */
3742+
ZVAL_DEREF(obj);
3743+
if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
3744+
if (error) *error = estrdup("first array member is not a valid class name or object");
3745+
return 0;
3746+
}
37613747

3762-
fcc->object = Z_OBJ_P(obj);
3748+
ZVAL_DEREF(method);
3749+
if (Z_TYPE_P(method) != IS_STRING) {
3750+
if (error) *error = estrdup("second array member is not a valid method");
3751+
return 0;
3752+
}
37633753

3764-
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3765-
fcc->called_scope = fcc->calling_scope;
3766-
return 1;
3767-
}
3768-
} else {
3769-
break;
3754+
if (Z_TYPE_P(obj) == IS_STRING) {
3755+
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3756+
return 1;
37703757
}
37713758

3772-
callable = method;
3773-
goto check_func;
3774-
3775-
} while (0);
3776-
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
3777-
if (!obj || (!Z_ISREF_P(obj)?
3778-
(Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) :
3779-
(Z_TYPE_P(Z_REFVAL_P(obj)) != IS_STRING && Z_TYPE_P(Z_REFVAL_P(obj)) != IS_OBJECT))) {
3780-
if (error) *error = estrdup("first array member is not a valid class name or object");
3781-
} else {
3782-
if (error) *error = estrdup("second array member is not a valid method");
3759+
if (!zend_is_callable_check_class(Z_STR_P(obj), get_scope(frame), frame, fcc, &strict_class, error)) {
3760+
return 0;
37833761
}
37843762
} else {
3785-
if (error) *error = estrdup("array must have exactly two members");
3763+
ZEND_ASSERT(Z_TYPE_P(obj) == IS_OBJECT);
3764+
fcc->calling_scope = Z_OBJCE_P(obj); /* TBFixed: what if it's overloaded? */
3765+
fcc->object = Z_OBJ_P(obj);
3766+
3767+
if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
3768+
fcc->called_scope = fcc->calling_scope;
3769+
return 1;
3770+
}
37863771
}
3772+
3773+
callable = method;
3774+
goto check_func;
37873775
}
37883776
return 0;
37893777
case IS_OBJECT:

ext/spl/tests/CallbackFilterIteratorTest-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ try {
4545
CallbackFilterIterator::__construct() expects exactly 2 arguments, 0 given
4646
CallbackFilterIterator::__construct() expects exactly 2 arguments, 1 given
4747
CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, no array or string given
48-
CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, array must have exactly two members
48+
CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, array callback must have exactly two members
4949
some message

ext/standard/tests/array/array_diff_uassoc_error.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ try {
4545
*** Testing array_diff_uassoc() : error conditions ***
4646

4747
-- Testing array_diff_uassoc() function with more than expected no. of arguments --
48-
array_diff_uassoc(): Argument #4 must be a valid callback, array must have exactly two members
49-
array_diff_uassoc(): Argument #6 must be a valid callback, array must have exactly two members
48+
array_diff_uassoc(): Argument #4 must be a valid callback, array callback must have exactly two members
49+
array_diff_uassoc(): Argument #6 must be a valid callback, array callback must have exactly two members
5050

5151
-- Testing array_diff_uassoc() function with less than expected no. of arguments --
52-
array_diff_uassoc(): Argument #2 must be a valid callback, array must have exactly two members
52+
array_diff_uassoc(): Argument #2 must be a valid callback, array callback must have exactly two members

ext/standard/tests/array/array_map_object1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ array_map(): Argument #1 ($callback) must be a valid callback or null, cannot ac
140140

141141
-- class without members --
142142
EmptyClass
143-
array_map(): Argument #1 ($callback) must be a valid callback or null, array must have exactly two members
143+
array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members
144144

145145
-- abstract class --
146146
ChildClass::emptyFunction

ext/standard/tests/array/array_map_variation14.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,5 @@ array(2) {
120120
-- with empty string --
121121
array_map(): Argument #1 ($callback) must be a valid callback or null, function "" not found or invalid function name
122122
-- with empty array --
123-
array_map(): Argument #1 ($callback) must be a valid callback or null, array must have exactly two members
123+
array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members
124124
Done

ext/standard/tests/array/array_map_variation17.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ array_map(): Argument #1 ($callback) must be a valid callback or null, function
121121
array_map(): Argument #1 ($callback) must be a valid callback or null, function "" not found or invalid function name
122122

123123
-- Iteration 16 --
124-
array_map(): Argument #1 ($callback) must be a valid callback or null, array must have exactly two members
124+
array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members
125125

126126
-- Iteration 17 --
127127
array_map(): Argument #1 ($callback) must be a valid callback or null, first array member is not a valid class name or object

tests/output/ob_start_basic_006.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ checkAndClean();
7373
--EXPECTF--
7474
---> Test arrays:
7575

76-
Warning: ob_start(): array must have exactly two members in %s on line %d
76+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
7777

7878
Notice: ob_start(): Failed to create buffer in %s on line %d
7979
bool(false)
@@ -89,23 +89,23 @@ Array
8989
(
9090
)
9191

92-
Warning: ob_start(): array must have exactly two members in %s on line %d
92+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
9393

9494
Notice: ob_start(): Failed to create buffer in %s on line %d
9595
bool(false)
9696
Array
9797
(
9898
)
9999

100-
Warning: ob_start(): array must have exactly two members in %s on line %d
100+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
101101

102102
Notice: ob_start(): Failed to create buffer in %s on line %d
103103
bool(false)
104104
Array
105105
(
106106
)
107107

108-
Warning: ob_start(): array must have exactly two members in %s on line %d
108+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
109109

110110
Notice: ob_start(): Failed to create buffer in %s on line %d
111111
bool(false)
@@ -125,7 +125,7 @@ Array
125125
)
126126

127127

128-
Warning: ob_start(): array must have exactly two members in %s on line %d
128+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
129129

130130
Notice: ob_start(): Failed to create buffer in %s on line %d
131131
bool(false)

tests/output/ob_start_error_003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ var_dump(ob_start(array($c)));
1414
echo "done"
1515
?>
1616
--EXPECTF--
17-
Warning: ob_start(): array must have exactly two members in %s on line %d
17+
Warning: ob_start(): array callback must have exactly two members in %s on line %d
1818

1919
Notice: ob_start(): Failed to create buffer in %s on line %d
2020
bool(false)

0 commit comments

Comments
 (0)