php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72248 Optimization erroneously enforces strict types in call_user_func
Submitted: 2016-05-20 13:47 UTC Modified: 2018-08-20 16:01 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: bwoebi@php.net Assigned:
Status: Verified Package: Scripting Engine problem
PHP Version: 7.0.6 OS: Irrelevant
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bwoebi@php.net
New email:
PHP Version: OS:

 

 [2016-05-20 13:47 UTC] bwoebi@php.net
Description:
------------
Due to our call_user_func() optimizations (which by the way also removes the additional internal stack frame in the stacktrace...; which ultimately causes the misbehavior), call_user_func[_array]() calls apply, when optimized, the strict_type mode of the caller, which they shouldn't.

In general, PHP functions count internally as weakly typed and this behavior shall be always the same.

Test script:
---------------
// first script (works as expected, with namespace)
<?php declare(strict_types=1); namespace a; var_dump(call_user_func("strlen", 1));'

// second script (bad behavior, without namespace)
<?php declare(strict_types=1); var_dump(call_user_func("strlen", 1));'

Expected result:
----------------
// first script
int(1)

// second script
int(1)

Actual result:
--------------
// first script
int(1)

// second script
Fatal error: Uncaught TypeError: strlen() expects parameter 1 to be string, integer given in Command line code:1
Stack trace:
#0 Command line code(1): strlen(1)
#1 {main}
  thrown in Command line code on line 1


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-20 08:41 UTC] sam at mousa dot nl
This does not only apply to PHP internal functions, this code has the same behavior:
Test scripts:

<?php declare(strict_types=1); namespace a; var_dump(
    call_user_func(function(string $test) {
        return $test;
    }, 5)
);

<?php declare(strict_types=1); var_dump(
    call_user_func(function(string $test) {
        return $test;
    }, 5)
);

However in this scenario the desired behavior is different. Since we have strict types on user code I assume we would always want an error, even in namespaces.
 [2018-08-20 14:11 UTC] cmb@php.net
-Summary: Optimization erroneously enforces strict types in call_user_func +Summary: Optimization doesn't enforce strict types in call_user_func -Status: Open +Status: Verified
 [2018-08-20 14:11 UTC] cmb@php.net
From the PHP manual[1]:

| Strict typing applies to function calls made from within the
| file with strict typing enabled, not to the functions declared
| within that file.

So the behavior of the non-namespaced code is correct, but the
namespaced code behaves erroneously.

[1] <http://php.net/manual/en/functions.arguments.php>
 [2018-08-20 15:02 UTC] requinix@php.net
-Summary: Optimization doesn't enforce strict types in call_user_func +Summary: Optimization erroneously enforces strict types in call_user_func
 [2018-08-20 15:02 UTC] requinix@php.net
> So the behavior of the non-namespaced code is correct, but the namespaced code behaves erroneously.
That's backwards. The bug is as reported.

Function calls made from within PHP do not use strict typing. call_user_func("strlen") should work as if strlen is being called from within call_user_func's stack frame and thus not use strict typing, however c_u_f used when not in a namespace is optimized into the equivalent function call - the second script compiles into a literal strlen(1) call - which is why strict_types kicked in.

Optimization or not, it should work just like a userland implementation of

<?php
// declare(strict_types=0);
function call_user_func_userland($function, ...$args) {
  return $function(...$args);
}
?>
 [2018-08-20 16:01 UTC] cmb@php.net
> That's backwards. The bug is as reported.

I stand corrected.  Thanks!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC