-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix #63217: Constant numeric strings become integers when used as ArrayAccess offset #2607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@hikari-no-yume was the optimised branch the better implementation or is this the correct approach? |
@rtheunissen I may be remembering wrong, but I think I failed to make a properly-working optimisation. |
It would be ideal to somehow retain the optimisation that fixing the bug would otherwise remove, but I haven't thought of a good way to do that yet. |
@hikari-no-yume Was the existing optimisation that caused this bug simply to remove the need to use |
@rtheunissen By performing |
If this implementation fixes the bug, passes the tests, and doesn't affect performance much, it would be good to have this under 7.2 and be optimised in a minor patch later on. |
Yeah. Potentially a more specific optimisation could be done in Zend Optimizer. |
@nikic what were the changes you were referring to in |
@rtheunissen What needs be handled are cases like https://github.com/rtheunissen/php-src/blob/e67dd43f66832170575bd148b5087a95d402f105/ext/opcache/Optimizer/zend_inference.c#L1977. Currently the code assumes that if the array key is a constant string, then this string is non-numeric. The following test case might reproduce the issue by incorrectly eliding a return type check, but I did not test. It's easiest to just check if the inference results are correct using opcache.opt_debug_level. <?php
function test() : string {
$array = [];
$array["10"] = 42;
foreach ($array as $k => $v) {
return $k;
}
}
test(); |
@rtheunissen It technically fixes the problem, but in a non-optimal way. It would be preferable to add a check whether or not the constant operand is numeric, rather than just assuming that it is. (This might be something you might want to do in general with a flag on the opline to also avoid the numeric string check at runtime in the VM as well). Furthermore iirc there are a couple of other places where basically the same check is done in zend_inference, so there are probably some more code changes necessary. |
@nikic something like that Andrea tried here? rtheunissen@40e393e |
If we can technically fix the problem, even if it's not in an optimal way, shouldn't that be a solid place to start with a 7.2.0 for example? 7.2.1 can see the optimal solution implemented. I doubt that the current patch's direction will affect performance enough to be a deal-breaker. I'll do some benchmarks similar to what @hikari-no-yume did in the initial request. |
See #3351 |
See:
This PR is an extension and re-opening of #1649 in an attempt to fix this as part of 7.2. I've rebased on master and updated some tests that are failing. @nikic mentioned in #1649 that further changes are necessary but I'm not sure what they are or why they are necessary.
This patch does not affect the array or string API and behaviour at all - only
ArrayAccess
.