The ast node flag constants ZEND_DIM_ALTERNATIVE_SYNTAX and
ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR node have identical values (1<<1),
causing a deprecation notice to be incorrectly emitted before the fatal error
for unsupported syntax.
Fixes GH-9263
Explicitly check for AST_VAR/AST_DIM kind for future compatibility
`AST_PROP`/`AST_METHOD_CALL` and nullsafe variants can also be found in
encapsulated strings - currently they have no flags but they may have flags in
the future. This also clarifies that this deprecation warning can only happen
for AST_VAR/AST_DIM nodes for certain `attr` values.
There are two main motivations to this:
a) The logic for handling internal and userland observation can be unified.
b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
RFC: https://wiki.php.net/rfc/dnf_types
This allows to combine union and intersection types together in the following form (A&B)|(X&Y)|T but not of the form (X|A)&(Y|B) or (X|A)&(Y|B)|T.
* Improve union type parsing
Co-authored-by: Sara Golemon <pollita@php.net>
This does a compile time transformation of ``iterable`` into ``Traversable|array`` which simplifies some of the LSP variance handling.
The arginfo generation script from stubs is updated to produce a union type when it encounters the type ``iterable``
Extension functions which do not regenerate the arginfo, or write them manually are still supported by mimicking the compile time transformation while registering the function.
Type Reflection is preserved for single ``iterable`` (and ``?iterable``) to produce a ReflectionNamedType with name ``iterable``, however usage of ``iterable`` in union types will be converted to ``array|Traversable``
Abstract functions are now handled in the INIT stage, they do not
affect DO opcodes anymore.
Also add a check for another precondition, namely that the function
is not a trampoline.
* ext/oci8: use zend_string_equals()
Eliminate duplicate code.
* main/php_variables: use zend_string_equals_literal()
Eliminate duplicate code.
* Zend/zend_string: add zend_string_equals_cstr()
Allows eliminating duplicate code.
* Zend, ext/{opcache,standard}, main/output: use zend_string_equals_cstr()
Eliminate duplicate code.
* Zend/zend_string: add zend_string_starts_with()
* ext/{opcache,phar,spl,standard}: use zend_string_starts_with()
This adds missing length checks to several callers, e.g. in
cache_script_in_shared_memory(). This is important when the
zend_string is shorter than the string parameter, when memcmp()
happens to check backwards; this can result in an out-of-bounds memory
access.
Previously, code such as subclasses of SplFixedArray would check for method
overrides when instantiating the objects.
This optimization was mentioned as a followup to GH-6552
Strangely, uses of eval and 'php -a' (or loading a file without opcache after a namespaced constant was declared)
will not treat non-FQ true/false/null as magic keywords, while compiled php required from a file would do that.
This may confuse people learning the language, and result in code loaded with
eval() behaving differently from the same snippet in a file loaded by require.
```
Interactive shell
php > define('foo\true', 'test');
php > namespace foo { var_dump(true); }
string(4) "test"
```
This will make the same session instead properly emit `bool(true);` like it
already would if running those statements in files when opcache was used.
(cherry picked from commit 4c48fd22d7)
Traits do not support interfaces, so we should not implement
Stringable on them.
Also check the __toString() return type in the same way other
magic methods do, otherwise we would now miss the check in the
trait case.
- for packed arrays we store just an array of zvals without keys.
- the elements of packed array are accessible throuf as ht->arPacked[i]
instead of ht->arData[i]
- in addition to general ZEND_HASH_FOREACH_* macros, we introduced similar
familied for packed (ZEND_HASH_PACKED_FORECH_*) and real hashes
(ZEND_HASH_MAP_FOREACH_*)
- introduced an additional family of macros to access elements of array
(packed or real hashes) ZEND_ARRAY_ELEMET_SIZE, ZEND_ARRAY_ELEMET_EX,
ZEND_ARRAY_ELEMET, ZEND_ARRAY_NEXT_ELEMENT, ZEND_ARRAY_PREV_ELEMENT
- zend_hash_minmax() prototype was changed to compare only values
Because of smaller data set, this patch may show performance improvement
on some apps and benchmarks that use packed arrays. (~1% on PHP-Parser)
TODO:
- sapi/phpdbg needs special support for packed arrays (WATCH_ON_BUCKET).
- zend_hash_sort_ex() may require converting packed arrays to hash.
For $ary[idx] op= $ary we should evaluate the RHS operand first,
otherwise we may create a reference-free recursive array. Use the
same handling we do for the normal $ary[idx] = $ary case.
Fixes oss-fuzz #40287.
For FETCH_DIM_W etc encode the context it is being used in
(dim, obj, ref or incdec) so we can throw an appropriate error
message for invalid string offset use, in a way that does not
require inspecting neighboring opcodes. The implementation is
similar to the flags used for FETCH_OBJ.
This means that we do not have to be careful about preserving
following opcodes during optimization.
Closes GH-7599.
list_is_keyed() did not take into account that there may be
AST_UNPACK elements. These would error lateron anyway, but still
produce an invalid access here.