Commit graph

2939 commits

Author SHA1 Message Date
Dmitry Stogov
7e080183f4 Fix crush after compilation of nullsafe operator introduced in 307e476e86
Now we flush only delayed opcodes realted to this nullsafe operator.

Fixes oss-fuzz #42152
2021-12-09 18:15:47 +03:00
Ilija Tovilo
051b3967a9
Merge branch 'PHP-8.1'
* PHP-8.1:
  Improve final/abstract methods in interfaces error messages
2021-12-05 23:48:26 +01:00
Ilija Tovilo
b991ce9c1e
Improve final/abstract methods in interfaces error messages
Closes #81683
Closes GH-7722
2021-12-05 23:10:07 +01:00
Ilija Tovilo
66af53cab8
Merge branch 'PHP-8.1' 2021-12-05 18:33:10 +01:00
Ilija Tovilo
dab6226cbe
Fix invalid opcode for ??= on $GLOBALS
Closes #81684
Closes GH-7717
2021-12-05 18:25:02 +01:00
Tyson Andre
024d5f4b63 Cache method overrides of ArrayAccess in zend_class_entry
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
2021-12-04 11:35:38 -05:00
Dmitry Stogov
dbde68f31e Merge branch 'PHP-8.1'
* PHP-8.1:
  Fixed bug #81216 (Nullsafe operator leaks dynamic property name)
2021-12-04 18:05:15 +03:00
Dmitry Stogov
307e476e86 Fixed bug #81216 (Nullsafe operator leaks dynamic property name)
Fixes oss-fuzz #38542
2021-12-04 18:04:24 +03:00
Nikita Popov
4a455c1484 Merge branch 'PHP-8.1'
* PHP-8.1:
  Allow constant folding bw_not on string
2021-11-11 09:50:25 +01:00
Nikita Popov
4df15e8245 Allow constant folding bw_not on string
This will not actually error.
2021-11-11 09:49:48 +01:00
Tyson Andre
2b1b384d9a Fix inconsistency in true/false/null constant resolution when opcache is not used (#7441)
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)
2021-11-09 10:43:56 +01:00
Nikita Popov
2d38f701e0 Merge branch 'PHP-8.1'
* PHP-8.1:
  Don't implement Stringable on traits
2021-11-05 09:48:33 +01:00
Nikita Popov
4bdb271894 Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Don't implement Stringable on traits
2021-11-05 09:48:28 +01:00
Nikita Popov
d478ae73b1 Don't implement Stringable on traits
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.
2021-11-05 09:42:58 +01:00
Dmitry Stogov
90b7bde615 Use more compact representation for packed arrays.
- 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.
2021-11-03 15:18:26 +03:00
Nikita Popov
a899dc9d17 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fix self-assign evaluation order for ASSIGN_DIM_OP
2021-11-01 09:52:19 +01:00
Nikita Popov
55aadc647b Fix self-assign evaluation order for ASSIGN_DIM_OP
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.
2021-11-01 09:50:22 +01:00
Nikita Popov
16e9e666ba Encode string offset error reason in extended_value
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.
2021-10-21 09:52:09 +02:00
Dmitry Stogov
ddaf64b56c Avoid non-immutable map_ptr indirection 2021-10-14 12:16:18 +03:00
Nikita Popov
780db4ea42 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fix incorrect access of AST_UNPACK
2021-10-12 17:17:49 +02:00
Nikita Popov
f555544faf Fix incorrect access of AST_UNPACK
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.
2021-10-12 17:16:58 +02:00
Dmitry Stogov
084c9faf4d Merge branch 'PHP-8.1'
* PHP-8.1:
  Fixed assign coalesce. "$a[0] ??= $a" should evaluate the right $a first.
2021-10-05 20:34:57 +03:00
Dmitry Stogov
80aaeb9696 Fixed assign coalesce. "$a[0] ??= $a" should evaluate the right $a first. 2021-10-05 20:34:09 +03:00
Dmitry Stogov
69fb20f106 Fixed assign coalesce. "$a[0] ??= $a" should evaluate the right $a first. 2021-10-05 20:23:56 +03:00
Kamil Tekiela
10f102d790
Fix 'can not' in error messages 2021-10-05 09:51:58 +01:00
codinghuang
5bda4cd25a Support specifying start position in compile_string
Add additional zend_compile_position argument, which can be either
AT_SHEBANG, AT_OPEN_TAG or AFTER_OPEN_TAG. The previous behavior
corresponds to AFTER_OPEN_TAG.

Closes GH-7462.
2021-09-30 10:21:33 +02:00
Nikita Popov
c19977d054 Fix delayed early binding with optimization
It's possible for delayed early binding opcodes to get optimized
away if they are "unreachable". However, we still need to attempt
early binding for them. (In some cases we also corrupt the early
binding list outright during optimization, which is how I got here.)

Fix this by storing information about delayed early binding
independently of DECLARE_CLASS_DELAYED opcodes, so early binding is
performed even after the opcode has been dropped.
2021-09-29 18:00:20 +02:00
Nikita Popov
a7ae4926b0 Merge branch 'PHP-8.1'
* PHP-8.1:
  Convert exception during delayed autoload to fatal error
  The PHP-8.1 branch is now for 8.1.0RC4
2021-09-29 10:05:45 +02:00
Nikita Popov
c8fa477064 Convert exception during delayed autoload to fatal error
Same as with other exceptions during inheritance, convert those
thrown during delayed class loading into fatal errors. We can't
properly deal with such exceptions, as inheritance cannot be
gracefully aborted at this point.

Fixes oss-fuzz #39405.
2021-09-29 10:03:23 +02:00
Nikita Popov
1c178569b4 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fixed bug #81465
2021-09-23 14:31:40 +02:00
Nikita Popov
a942b284e6 Fixed bug #81465
Make the error message for enum cases more technically correct.
2021-09-23 14:29:27 +02:00
Nikita Popov
2157d11ddc Merge branch 'PHP-8.1'
* PHP-8.1:
  Don't treat expression exit as terminator
2021-09-23 10:26:34 +02:00
Nikita Popov
c9762be566 Don't treat expression exit as terminator
Same as with throw expressions, this may remove later temporary
consuming instructions and thus eliminate live ranges, resulting
in a memory leak. We make use of the same hack and don't consider
exit a terminator if used in an expression context.
2021-09-23 10:26:07 +02:00
Nikita Popov
19888a69b4 Initialize UNUSED operands to sentinel value
This makes it more likely that unintentional uses of UNUSED
operands will result in crash rather than some hard to detect
corruption of the call frame.
2021-09-15 14:31:17 +02:00
Tyson Andre
4c48fd22d7
Fix inconsistency in true/false/null constant resolution when opcache is not used (#7441)
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.
2021-09-03 08:42:36 -04:00
Nikita Popov
fa032764db Initialize method_lcname to suppress maybe-uninitialized warning 2021-08-26 14:15:39 +02:00
Nikita Popov
07984435ae Mark private compiler functions as static 2021-08-26 11:29:44 +02:00
Nikita Popov
315f40942b
Always use CE_CACHE, remove TYPE_HAS_CE (#7336)
Currently, CE_CACHE on strings is only used with opcache interned strings. This
patch extends usage to non-opcache interned strings as well. This means that
most type strings can now make use of CE_CACHE even if opcache is not loaded,
which allows us to remove TYPE_HAS_CE kind, and fix some discrepancies
depending on whether a type stores a resolved or non-resolved name.

There are two cases where CE_CACHE will not be used:

 * When opcache is not used and a permanent interned string (that is not an
   internal class name) is used as a type name during the request. In this case
   we can't allocate a map_ptr index for the permanent string, as it would be
   not be in the permanent map_ptr index space.
 * When opcache is used but the script is not cached (e.g. eval'd code or
   opcache full). If opcache is used, we can't allocate additional map_ptr
   indexes at runtime, because they may conflict with indexes allocated by
   opcache.

In these two cases we would end up not using CE caching for property types
(argument/return types still have the separate cache slot).
2021-08-11 10:28:52 +02:00
Nikita Popov
e011952576
Preload unlinked classes, remove preload autoload (#7311)
Currently, classes that can't be linked get moved back into the original script
and are not preloaded. As such classes may be referenced from functions that
did get preloaded, there is a preload autoload mechanism to load them at
runtime.

Since PHP 8.1, we can safely preload unlinked classes, which will then go
through usual lazy loading. This means that we no longer need the preload
autoload mechanism. However, we need to be careful not to modify any hash
table buckets in-place, and should create new buckets for lazy loaded classes.
2021-07-28 14:27:58 +02:00
Nikita Popov
380e705fc2 Use consistent line numbers for early binding errors
Non-early-bound classes report inheritance errors at the first line
of the class, if no better line information is available (we should
really store line numbers for properties at least...) Early bound
classes report it at the last line of the class instead.

Make the error reporting consistent by always reporting at the
first line.
2021-07-28 12:35:20 +02:00
Nikita Popov
dcf5e5bbf0 Reuse part of the class binding logic
This part of DECLARE_CLASS and DECLARE_CLASS_DELAYED is the
same.
2021-07-27 16:54:45 +02:00
Nikita Popov
b35418402f Allocate map_ptr for mutable_data during preloading
We need to discard objects in the class constants if they happened
to be evaluated during preloading. To allow doing so, we need to
use mutable_data, which will place the evaluated constants into
a separate table.
2021-07-27 11:16:38 +02:00
Máté Kocsis
3babe9576e
Validate that promoted readonly properties have a type 2021-07-25 13:13:19 +02:00
Nikita Popov
c4f4f1ece7 Share zval_make_interned_string() helper
The same function was defined in zend_compile.c and zend_API.c.
2021-07-23 16:10:34 +02:00
Nikita Popov
3eb97a4566 Always use separate static_members_table
When running without opcache, static_members_table is shared with
default_static_members_table. This is visible in reflection output,
because ReflectionProperty::getDefaultValue() will return the
current value, rather than the default value.

Address this by never sharing the table, which matches the behavior
we already see under opcache.

Fixes bug #80821.

Closes GH-7299.
2021-07-23 09:29:32 +02:00
Nikita Popov
11b990f848 Forbid multiple readonly modifiers
Same as for other modifiers.
2021-07-21 12:19:06 +02:00
Levi Morrison
ae8647d9d3
Remove leading underscore for _zend_hash_find_known_hash (#7260)
Convert zend_hash_find_ex(..., 1) to zend_hash_find_known_hash(...)
Convert zend_hash_find_ex(..., 0) to zend_hash_find(...)

Also add serializable changes to UPGRADING.INTERNALS summary
2021-07-20 17:07:17 -06:00
Nikita Popov
6780aaa532 Implement readonly properties
Add support for readonly properties, for which only a single
initializing assignment from the declaring scope is allowed.

RFC: https://wiki.php.net/rfc/readonly_properties_v2

Closes GH-7089.
2021-07-20 12:05:46 +02:00
Nikita Popov
814a932734 Add ZEND_ACC_NOT_SERIALIZABLE flag
This prevents serialization and unserialization of a class and its
children in a way that does not depend on the zend_class_serialize_deny
and zend_class_unserialize_deny handlers that will be going away
in PHP 9 together with the Serializable interface.

In stubs, `@not-serializable` can be used to set this flag.

This patch only uses the new flag for a handful of Zend classes,
converting the remainder is left for later.

Closes GH-7249.
Fixes bug #81111.
2021-07-19 15:59:11 +02:00
George Peter Banyard
9e1c961110 Fix intersection types being nullable via implicit forced nullability 2021-07-17 11:14:58 +02:00