This goes in the reverse direction of 4463acb951.
After looking around a bit, it seems that we already check for
Z_ISERROR_P() on the get_property_ptr_ptr return value in other places.
So do this in zend_fetch_property_address() as well, and also make
sure that EG(error_zval) is indeed returned on exception in
get_property_ptr_ptr.
In particular, this fixes the duplicate exceptions that we used to
get because first get_property_ptr_ptr threw one and then
read_property throws the same exception again.
Relying on setting ERROR if an exception happened during the
property address fetch is both a bit fragile and may pessimize
other codepaths that will check for exceptions in the VM. Adding
an extra exception check instead, which should also allow us to
drop the use of ERROR in this area in master.
Avoid need of insertion NOP opcoes between unrelated SMART BRANCH instruction and following JMPZ/JMPNZ.
Now instead of checking the opcode of following instruction, the same information is encoded into SMART BRANH result_type.
After fixing the int->double coercion case, this is already verified
at compile-time, so there is no need to redo this type check on
every call.
Only perform the type check every time for the case of AST default
values.
Previously if the "non well formed" notice was converted into an
exception we'd still end up executing the function.
Also drop the now unnecessary EG(exception) checks in the engine.
Additionally remote a bogus exception in zend_is_callable: It
should only be writing to error, but not directly throwing.
Make sure the initialize the result of FETCH_OBJ_UNSET operations.
I'm using a NULL value rather than ERROR here, because the latter
no longer exists in master.
Usually it will already fail when opening, but reads can also
fail since PHP 7.4, in which case we still need to place the
file handle in open_files to make sure the destructor will run
on it.
* get_parent_class() argument is optional
* Mark array_filter() $callback as optional
* The $base of gmp_strval() is optional
* DateTime constructor also accepts zero arguments
* hash_update_file() stream context is optional
* xmlwriter_write_dtd_entity() $isparam argument is optional
This originally manifested as a leak in oss-fuzz #18000. The following
is a reduced test case:
<?php
[
5 => 1,
"foo" > 1,
" " => "" == 0
];
<<<BAR
$x
BAR;
Because this particular error condition did not return T_ERROR,
EG(exception) was set while performing binary operation constant
evaluation, which checks exceptions for cast failures.
Instead of adding this indirect test case, I'm adding an assertion
that the lexer has to return T_ERROR if EG(exception) is set.
I'm going for a very conservative fix here, where the previous
logic is restored for the case where an object is passed to
method_exists(). We might want to check against EG(scope) instead,
but this seems like a safer choice.
This means that behavior in PHP 7.4 changes only for
method_exists('C', 'privateMethodNotOnC'), which should be sensible.