Conversation
2d17f00 to
504482c
Compare
|
Given I've created the 3 fixed tickets, I did a purely mechanical/LLM review using the model that reported the issues: All 👍 |
|
As briefly discussed privately: Evaluation of the fix unearthed two more issues. Attaching them here as @bukka will address them in the scope of this PR as well: Model output below, collapsed to now blow up the discussion Model output
|
504482c to
52e7e44
Compare
8e9a94a to
20ca2fe
Compare
Good find.
Fixed in 46fc222
Fixed in d26d1db . This one was quite tricky and required quite a bit of refactoring as that part wasn't thought through. Found couple of related problems with it. Also found another recursion edge case that is fixed in 20ca2fe |
|
can a test be added along those lines ? --TEST--
Stream errors: the error handler is not re-entered by its own stream errors
--FILE--
<?php
$calls = 0;
$stream = null;
$ctx = stream_context_create(['stream' => [
'error_mode' => StreamErrorMode::Silent,
'error_handler' => static function (array $errors) use (&$calls, &$stream): void {
if (++$calls > 5) {
return;
}
fwrite($stream, 'x');
},
]]);
$stream = fopen(__FILE__, 'r', false, $ctx);
fwrite($stream, 'x');
fclose($stream);
var_dump($calls);
?>
--EXPECT--
int(1) |
| Stream errors: recursive error handler is stopped by the stack limit | ||
| --SKIPIF-- | ||
| <?php | ||
| if (ini_get('zend.max_allowed_stack_size') === false) { |
There was a problem hiding this comment.
this might be appropriate too
if (getenv('SKIP_ASAN')) {
die('skip ASAN needs different stack limit setting due to more stack space usage');
}There was a problem hiding this comment.
The test is working on ASAN so why?
There was a problem hiding this comment.
true :) was just extra precaution in case we update clang and it suddenly fails.
There was a problem hiding this comment.
are you saying there are some changes in clang so it's already failing in some version? I'm fine to skip it if there are some known cases where this can fail ofc
There was a problem hiding this comment.
just saying it can happen, but you know what ;we can always fix this test later after all :)
I don't think we should suppress magically stream setting if it's in error handler. This is really up to user to deal with it and there is recursion limit exactly because of this. Anyone who does this, must know what they are doing because they need to explicitly pass the same stream and then they use it. So if they do this, they will expect recursion to happen so I would prefer not to change this. In other words I don't want to change the current behaviour to match your example so it's unrelated to this PR (master will recurse as well so it's not something this PR would change). |
|
alright, just one thing to confirm, since d26d1db the depth limit never kicks in here, end() pops the op before calling the handler so the depth never grows, right ? |
|
Ah yeah, I was slightly imprecise in the previous comment. By recursion limit I meant that stack recursion protection that we have for some time (8.3 IIRC). There is another operation depth limit here which is mainly for user wrapper where the operation is not finished. That commit excluded handler call from it because I think it makes more sense as the operation is sort of done. |
20ca2fe to
f288d81
Compare
|
in my side, nothing to add, now I see the pclose test it s all good. |
…n end The operation can live in the reallocatable overflow array, so it must not be touched after user code has run. Handlers also run with the operation stack hidden, so errors they raise are reported immediately instead of being attached to an enclosing operation.
When the depth limit refuses a begin, the matching end popped an unrelated operation and desynchronized the stack.
f288d81 to
4f7928f
Compare
It fixes stream errors issues reported in GH-23259 , GH-23264 and GH-23262 . Those are mostly edge cases.