Commit Graph

18510 Commits

Author SHA1 Message Date
David CARLIER
75e9980054
zend stack: prepare zend_call_stack_get implementation for OpenBSD. (#11578) 2023-07-07 18:03:07 +01:00
Niels Dossche
0b2e6bc2b0 Cache d_type in directory entry 2023-07-07 18:02:32 +02:00
Arnaud Le Blanc
72a163aa90
Add stack limit check in zend_eval_const_expr() (#11424) 2023-07-07 14:18:15 +02:00
Ilija Tovilo
11aee73572
Fix incorrect handling of unwind and graceful exit exceptions
These exceptions should not invoke the user error handler, and not cause bailing
of the request.

Fixes GH-11601
Closes GH-11608
2023-07-07 08:15:17 +02:00
Ilija Tovilo
dbbcbcb5b5
Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix use-of-uninitialized-value with ??= on assert
2023-07-06 09:39:46 +02:00
Ilija Tovilo
ac3ff5bb7a
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix use-of-uninitialized-value with ??= on assert
2023-07-06 09:39:05 +02:00
Ilija Tovilo
84a2e48050
Fix use-of-uninitialized-value with ??= on assert
Normally, PHP evaluates all expressions in offsets (property or array), as well
as the right hand side of assignments before actually fetching the offsets. This
is well explained in this blog post.

https://www.npopov.com/2017/04/14/PHP-7-Virtual-machine.html#writes-and-memory-safety

For ??= we have a bit of a problem in that the rhs must only be evaluated if the
lhs is null or undefined. Thus, we have to first compile the lhs with BP_VAR_IS,
conditionally run the rhs and then re-fetch the lhs with BP_VAR_W to to make
sure the offsets are valid if they have been invalidated.

However, we don't want to just re-evaluate the entire lhs because it may contain
side-effects, as in $array[$x++] ??= 42;. In this case, we don't want to
re-evaluate $x++ because it would result in writing to a different offset than
was previously tested. The same goes for function calls, like
$array[foo()] ??= 42;, where the second call to foo() might result in a
different value. PHP behaves correctly in these cases. This is implemented by
memoizing sub-expressions in the lhs of ??= and reusing them when compiling the
lhs for the second time. This is done for any expression that isn't a variable,
i.e. anything that can (potentially) be written to.

Unfortunately, this also means that function calls are considered writable due
to their return-by-reference semantics, and will thus not be memoized. The
expression foo()['bar'] ??= 42; will invoke foo() twice. Even worse,
foo(bar()) ??= 42; will call both foo() and bar() twice, but
foo(bar() + 1) ??= 42; will only call foo() twice. This is likely not by design,
and was just overlooked in the implementation. The RFC does not specify how
function calls in the lhs of the coalesce assignment behaves. This should
probably be improved in the future.

Now, the problem this commit actually fixes is that ??= may memoize expressions
inside assert() function calls that may not actually execute. This is not only
an issue when using the VAR in the second expression (which would usually also
be skipped) but also when freeing the VAR. For this reason, it is not safe to
memoize assert() sub-expressions.

There are two possible solutions:

1. Don't memoize any sub-expressions of assert(), meaning they will execute
   twice.
2. Throw a compile error.

Option 2 is not quite simple, because we can't disallow all memoization inside
assert(), as that would break assertions like assert($array[foo()] ??= 'bar');.
Code like this is highly unlikely (and dubious) but possible. In this case, we
would need to make sure that a memoized value could not be used across the
assert boundary it was created in. The complexity for this is not worthwhile. So
we opt for option 1 and disable memoization immediately inside assert().

Fixes GH-11580
Closes GH-11581
2023-07-06 09:38:41 +02:00
Ilija Tovilo
80873d28b1
Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix trailing if element JMP lineno
2023-07-05 21:04:45 +02:00
Ilija Tovilo
a5e89c5686
Fix trailing if element JMP lineno
Having this lineno on the same last compiled element can lead to an incorrectly
covered line number.

if (true) {
    if (false) {
        echo 'Never executed';
    }
} else {
}

The echo will be reported as covered because the JMP from the if (true) branch
to the end of the else branch has the same lineno as the echo.

This is lacking a test because zend_dump.c does not have access to
ctx->debug_level and I don't think it's worth adjusting all the cases.

Closes GH-11598
2023-07-05 21:04:11 +02:00
George Peter Banyard
a342138e17
Revert "Use binary safe case compare in new zend_string API"
This reverts commit eb5cc1372c.

A) I'm using the function incorectly
B) Somehow the function is undefined although it's used in other zend_string APIs
2023-07-05 18:13:04 +01:00
George Peter Banyard
eb5cc1372c
Use binary safe case compare in new zend_string API 2023-07-05 18:04:45 +01:00
Ilija Tovilo
ad1b70d67e
Revert "Revert "Remove name field from the zend_constant struct (#10954)""
This reverts commit 9f4bd3040d.
2023-07-04 16:42:40 +02:00
Ilija Tovilo
7b355e8d34
Revert "Merge branch 'PHP-8.2'"
This reverts commit 45a3f178dc, reversing
changes made to b2a54bc6af.
2023-07-04 09:18:49 +02:00
Ilija Tovilo
ef4f08832c
Revert "Fix GH-9967 Add support for generating custom function, class const, and property attributes in stubs"
This reverts commit d7ab0ff0c8.
2023-07-04 09:11:14 +02:00
Máté Kocsis
9f4bd3040d
Revert "Remove name field from the zend_constant struct (#10954)"
This reverts commit f42992f580.

Fix GH-11423
2023-07-03 15:16:24 +02:00
Máté Kocsis
45a3f178dc
Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix GH-9967 Add support for generating custom function, class const, and property attributes in stubs

Closes GH-10170
2023-07-03 11:17:08 +02:00
Máté Kocsis
d7ab0ff0c8
Fix GH-9967 Add support for generating custom function, class const, and property attributes in stubs 2023-07-03 08:32:58 +02:00
Máté Kocsis
3906bccc00 Add support for typed class constants in stubs 2023-07-01 11:50:04 +02:00
Tim Düsterhus
49ef6e209d
RFC: Add #[Override] attribute (#9836)
* Add #[Override] attribute

* Move #[\Override] tests into Zend/tests/attributes/override/

* Check `check_only` before removing `ZEND_ACC_OVERRIDE`

* NEWS/UPGRADING for #[\Override]
2023-06-29 20:23:53 +02:00
Ilija Tovilo
ee4ebab5a9
[skip ci] Improve inheritance checked comment
zend_can_early_bind() might have already detected that the methods are
incompatible. In that case the class is still early bound, but must compile
error when inheritance is performed. Thus it is only safe to skip compatibility
checks when zend_can_early_bind() has succeeded.
2023-06-29 09:35:42 +02:00
Ilija Tovilo
5723fa2275
[skip ci] Document do_inheritance_check_on_method_ex() check_only and check params
These are quite confusingly named.
2023-06-29 09:18:59 +02:00
Ilija Tovilo
68ef3938f4
Fix missing "Optional parameter before required" deprecation on union null type
The check would only work for the ?type syntax, but not  type|null. Switch to a
check during type compilation instead.

Fixes GH-11488
Closes GH-11497
2023-06-28 20:45:43 +02:00
Ilija Tovilo
a94216dcb7
Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix mis-compilation of by-reference nullsafe operator
2023-06-28 20:37:25 +02:00
Ilija Tovilo
54dfa86728
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix mis-compilation of by-reference nullsafe operator
2023-06-28 20:36:30 +02:00
Ilija Tovilo
dc73b73f8b
Fix mis-compilation of by-reference nullsafe operator
Fixes oss-fuzz #60011
Closes GH-11540

Co-authored-by: Dmitry Stogov <dmitry@zend.com>
Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
2023-06-28 20:35:29 +02:00
nielsdos
3c872661c1 Fix GH-11507: String concatenation performance regression in 8.3
When the code was moved to solve the uaf for memory overflow, this
caused the refcount to be higher than one in some self-concatenation
scenarios. This in turn causes quadratic time performance problems when
these concatenations happen in a loop.

Closes GH-11508.
2023-06-22 23:42:25 +02:00
Patrick Allaert
973e9b2eec
Fixes "GC_BENCH" is not defined in extensions including zend_gc.h
Compilation warning encountered:

include/php/Zend/zend_gc.h:49:5: warning: "GC_BENCH" is not defined, evaluates to 0 [-Wundef]
   49 | #if GC_BENCH
      |     ^~~~~~~~
2023-06-22 17:40:15 +02:00
Ilija Tovilo
fae42c8bd8
Fix assertion violation for invalid class const objects in const expressions (#11458)
Fixes oss-fuzz #59764
2023-06-21 14:59:05 +02:00
Sergey Panteleev
884a53f39a
PHP-8.2 is now for PHP 8.2.9-dev 2023-06-20 17:25:30 +03:00
Patrick Allaert
6c4b1e0417
PHP-8.1 is now for PHP 8.1.22-dev 2023-06-20 16:07:05 +02:00
George Peter Banyard
ea8f934fe5
Zend: Expose zendi_try_get_long() function via a public API (#10175) 2023-06-19 14:07:46 +01:00
George Peter Banyard
80e90ad7ba
Add number or str ZPP macros 2023-06-18 13:09:03 +01:00
Ilija Tovilo
b3e33be443
Forward shutdown exceptions to user error handlers
Fixes GH-10695
Closes GH-110905
2023-06-15 17:11:22 +02:00
Niels Dossche
5c789806ef Fix GH-11406: segfault with unpacking and magic method closure
The magic method trampoline closure may be variadic. However, the
arg_info for the variadic argument was not set, resulting in a crash
both in reflection and in the VM.

Fix it by creating an arg_info containing a single element in case of
the variadic case. The variadic argument is the last one (and in this
case only one) in the arg_info array.

We make sure the argument info is equivalent to the argument info of
`$closure` of the following code snippet:
```
function foo(...$arguments) {}
$closure = foo(...);
```

Closes GH-11417.
2023-06-13 17:39:47 +02:00
Bob Weinand
95e6ce6ede Merge branch 'PHP-8.2' 2023-06-09 14:01:44 +02:00
Bob Weinand
709540ccdc Fix add/remove observer API with multiple observers installed
Depending on the order in which observers were installed, some observers might have been executed twice after removal of another observer. Also, adding an observer could produce a bogus pointer.
2023-06-09 14:00:53 +02:00
George Peter Banyard
d5ad75108e
More usage of known zend_str instead of C string (#11381) 2023-06-08 13:03:29 +01:00
Dmitry Stogov
962a777a37 Merge branch 'PHP-8.2'
* PHP-8.2:
  Keep consistent EG(current_execute_data) after return from generator (#11380)
2023-06-08 14:55:56 +03:00
Dmitry Stogov
42619b2378 Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Keep consistent EG(current_execute_data) after return from generator (#11380)
2023-06-08 14:55:43 +03:00
Dmitry Stogov
06d68738b7
Keep consistent EG(current_execute_data) after return from generator (#11380) 2023-06-08 14:55:18 +03:00
Niels Dossche
79d024ac0e
Allow final modifier when using a method from a trait (#11394)
Fixes GH-11388.

Following https://wiki.php.net/rfc/horizontalreuse which introduced traits,
this should be allowed.
The implementation was refactored in 3f8c729. That commit is the first time
the "final" check appears AFAICT, but no reason was given for why. That
commit seems to have landed in 5.4.11 and the NEWS for that version doesn't
seem to mention something relevant to the behaviour change.
This patch removes the restriction of the final modifier.

Closes GH-11394.
2023-06-07 23:53:21 +02:00
Florian Engelhardt
bde6f2a2f7
Fix initial array size in gc_status() (#11393)
Small fix for the initial array size to reflect the number of items that will be added.
2023-06-07 23:51:18 +02:00
George Peter Banyard
99fa740acb
Use common function for TypeError on illegal offset access (#10544)
This merges all usages of emitting an offset TypeError into a new ZEND_API function
zend_illegal_container_offset(const zend_string* container, const zval *offset, int type);

Where the container should represent the type on which the access is attempted (e.g. string, array)
The offset zval that is used, where the error message will display its type
The type of access, which should be a BP_VAR_* constant, to get special message for isset/empty/unset
2023-06-06 11:28:19 +01:00
Niels Dossche
61e1f8aaeb Let closure created from magic method accept named parameters
Implements GH-11348.

Closes GH-11364.
2023-06-05 20:03:09 +02:00
George Peter Banyard
9ce6980b4d
Use known zend_string pointer to check for equality instead of C strings (#11370)
* Compare __invoke magic method name with known zend_string pointer

* Compare __sleep/__wakeup magic method name with known zend_string pointer
2023-06-05 13:59:04 +01:00
George Peter Banyard
ce724d186d Assert zend_constant exist
If not the enum case does not exist and it is a programming error
2023-06-02 20:33:20 +01:00
George Peter Banyard
c5d7264149 Fix file descriptor check
Technically 0 is a valid file descriptor
2023-06-02 20:33:20 +01:00
Kirill Nesmeyanov
b495a916a4
Add string output escaping into zend dump (phpdbg + opcache debug) (#11337)
* Add string output escaping into zend dump (phpdbg + opcache debug)

* Use ZSTR_VAL macro instead direct string access

* Move "escaped_string" into local switch/case scope

* Add zend_string_release

* Add Z_STR_P macro instead direct string access

* Merge zend_string declaration and its assigment in one stmt
2023-05-29 16:45:00 +03:00
Ilija Tovilo
fbe6696d49 Revert "Use zend_ast_apply in zend_eval_const_expr (#11261)"
This reverts commit 1c733c8bbc.

Fixes GH-11320
2023-05-26 12:15:01 +02:00
Ilija Tovilo
8ed66b4347 Add tests for list() in assignment in array literals
Array literals will constant evaluate their elements. These can include
assignments, even though these are not valid constant expressions. The lhs of
assignments can be a list() element (or []) which is parsed as an array with a
special flag.
2023-05-26 12:15:01 +02:00