Parent interfaces are copied into the interface list during
inheritance, so there's no need to perform a recursive check.
Only exception are instanceof checks performed during inheritance
itself. However, we already have unlinked_instanceof for this
purpose, it just needs to be taught to handle this case.
Closes GH-4857.
instanceof_class does not need to check for a NULL pointer in the
first iteration -- passing NULL to this function is illegal.
instanceof_interface does not need to use instanceof_class(), it
only has to check whether the CEs match exactly. There is no way
for an interface to appear inside "parent", it will always be in
"interfaces" only.
The instanceof_interface_only() function was dead code (always
returned zero).
Clarify that the last parameter indicates whether the passed CE
is interface or class and rewrite the code in terms of assertions.
Noticed while working on union types: We do not load argument and
return types during type checks, but we do load property types.
I'm normalizing the behavior towards the existing status quo (not
loading), though we may consider loading everywhere (all types,
and instanceof) in order to properly support class aliases.
Property types are invariant, but may still have to load classes in
order to check for class aliases. This class loading should follow
the same rules as all other variance checks, rather than just
loading unconditionally.
This change integrates property type invariance checks into the
variance system as a new obligation type, and prevent early binding
if the type check cannot be performed.
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.
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.
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.
Not NULLing the static_variables pointer for shadow methods during
static var shutdown would be a way to avoid this leak, but unless
there's evidence that inherited private methods with static vars are
actually a common use-case, I don't think we should keep this kind
of fragile edge-case optimization.
Fixes OSS-Fuzz #17875.
Resources used as array keys are generally handled by throwing a
notice and converting the resource to the resource handle. The only
exception is the [$resource => null] syntax, where this was treated
as an illegal offset type instead. However, this also only happened
for VM evaluations, the AST evaluator did handle resources correctly.