Commit graph

146 commits

Author SHA1 Message Date
Gina Peter Banyard
1c67b060c4 main: Add bailout tests for dir opening on user stream 2025-08-15 18:41:17 +02:00
Arnaud Le Blanc
32290b3529
Add opcache_preloading() internal function
Add a C function, opcache_preloading(), that returns true during
preloading. Extensions can use this to detect preloading, not only during
compilation/execution, but also in RINIT()/RSHUTDOWN().

Since opcache currently doesn't install any header, I'm adding a new one:
zend_accelerator_api.h. Header name is based on other files in ext/opcache.

Closes GH-19288
2025-08-06 18:21:19 +02:00
Gina Peter Banyard
fc6c49cbf4 ext/zend_test: Test zend_call_method_if_exists() 2025-07-30 12:02:41 +01:00
Niels Dossche
502c68264d
Merge branch 'PHP-8.4'
* PHP-8.4:
  pdo_odbc: Fix memory leak if WideCharToMultiByte() fails
  Fix memory leak on php_odbc_fetch_hash() failure
  Do not delete main chunk in zend_gc
2025-06-09 11:26:27 +02:00
Niels Dossche
5526301908
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  pdo_odbc: Fix memory leak if WideCharToMultiByte() fails
  Fix memory leak on php_odbc_fetch_hash() failure
  Do not delete main chunk in zend_gc
2025-06-09 11:25:41 +02:00
Daniil Gentili
9a9d98e02f
Do not delete main chunk in zend_gc
Closes GH-18756.

Co-authored-by: Arnaud Le Blanc <arnaud.lb@gmail.com>
2025-06-09 11:23:29 +02:00
DanielEScherzer
8f3cdf6236
gen_stub: Add support for attributes on constants in stubs (#18735)
Update to PHP-Parser 5.5.0 and add support for attributes on constants in
stubs. For now, I have only migrated over E_STRICT, once the support is in
place I'll do a larger migration of the existing deprecated constants.

In the process, fix the logic in `copy_zend_constant()` for copying attributes
when a constant is copied; just increase the reference count for the attributes
table rather than trying to duplicate the contents.
2025-06-05 14:46:46 -07:00
Tim Düsterhus
73c4e9f0b2
Merge branch 'PHP-8.4'
* PHP-8.4:
  gen_stub: Fix `ce_flags` generation for compatibility mode (#18507)
2025-05-09 13:33:58 +02:00
Tim Düsterhus
84f82d0a1c
gen_stub: Fix ce_flags generation for compatibility mode (#18507)
* gen_stub: Fix `ce_flags` generation for compatibility mode

Fixes php/php-src#18506

* gen_stub: Improve output for ce_flags compatibility
2025-05-09 13:33:09 +02:00
DanielEScherzer
3f03f7ed3d
[RFC] Add support for attributes on compile-time constants
https://wiki.php.net/rfc/attributes-on-constants
2025-04-29 11:53:09 -07:00
Tim Düsterhus
f14697416e
ext/standard: Remove #[\NoDiscard] from flock() (#18255)
Co-authored-by: Volker Dusch <volker@tideways-gmbh.com>
2025-04-08 14:23:03 +02:00
Tim Düsterhus
5544be7018
RFC: Marking return values as important (#[\NoDiscard]) (#17599)
RFC: https://wiki.php.net/rfc/marking_return_value_as_important

Co-authored-by: Volker Dusch <volker@tideways-gmbh.com>
2025-04-02 09:35:29 +02:00
Arnaud Le Blanc
cb245411b0
Add runtime-enabled heap debugging capabilities (#18172)
Debugging memory corruption issues in production can be difficult when it's not possible to use a debug build or ASAN/MSAN/Valgrind (e.g. for performance reasons).

This change makes it possible to enable some basic heap debugging helpers without rebuilding PHP. This is controlled by the environment variable ZEND_MM_DEBUG. The env var takes a comma-separated list of parameters:

- poison_free=byte: Override freed blocks with the specified byte value (represented as a number)
- poison_alloc=byte: Override newly allocated blocks with the specified byte value (represented as a number)
- padding=bytes: Pad allocated blocks with the specified amount of bytes (if non-zero, a value >= 16 is recommended to not break alignments) 
- check_freelists_on_shutdown=0|1: Enable checking freelist consistency [1] on shutdown

Example:

    ZEND_MM_DEBUG=poison_free=0xbe,poison_alloc=0xeb,padding=16,check_freelists_on_shutdown=1 php ...

This is implemented by installing custom handlers when ZEND_MM_DEBUG is set.

This has zero overhead when ZEND_MM_DEBUG is not set. When ZEND_MM_DEBUG is set, the overhead is about 8.5% on the Symfony Demo benchmark.

Goals:

 - Crash earlier after a memory corruption, to extract a useful backtrace
 - Be usable in production with reasonable overhead
 - Having zero overhead when not enabled

Non-goals:

 - Replace debug builds, valgrind, ASAN, MSAN or other sanitizers

[1] https://github.com/php/php-src/pull/14054

Co-authored-by: Tim Düsterhus <timwolla@googlemail.com>
2025-03-31 17:24:42 +02:00
Máté Kocsis
684ef016e1
Add support for using final properties in stubs (#17306) 2025-01-06 07:56:13 +01:00
Niels Dossche
bfd9e0cca3
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-16628: FPM logs are getting corrupted with this log statement
  Fix GH-16601: Memory leak in Reflection constructors
2024-11-02 19:38:54 +01:00
Niels Dossche
16cda10650
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-16628: FPM logs are getting corrupted with this log statement
  Fix GH-16601: Memory leak in Reflection constructors
2024-11-02 19:37:28 +01:00
Niels Dossche
e643129bbb
Fix GH-16628: FPM logs are getting corrupted with this log statement
zlog_buf_prefix() can return a larger length than what actually was
written due to its use of snprintf(). The code in
zlog_stream_prefix_ex() does not take this into account, other callers
do. What ends up happening then is that stream->length is set to the
length as if snprintf() was able to write all bytes, causing
stream->length to become larger than stream->buf.size, causing a
segfault.

In case the buffer was too small we try with a larger buffer up to a
limit of zlog_limit. This makes sure that the stream length will remain
bounded by the buffer size.

This also adds assertions to make the programmer intent clear and catch
this more easily in debug builds.

Closes GH-16680.
2024-11-02 19:36:20 +01:00
Niels Dossche
b24cc7386b
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
2024-10-07 17:18:32 +02:00
Niels Dossche
0338008852
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
2024-10-07 17:17:27 +02:00
Niels Dossche
e715dd0afb
Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
In the test, I have an internal `__call` function for `_ZendTestMagicCallForward` that calls the global function with name `$name` via `call_user_function`.
Note that observer writes the pointer to the previously observed frame in the last temporary of the new call frame (`*prev_observed_frame`).

The following happens:
First, we call `$test->callee`, this will be handled via a trampoline with T=2 for the two arguments. The call frame is allocated at this point. This call frame is not observed because it has `ZEND_ACC_CALL_VIA_TRAMPOLINE` set. Next we use `ZEND_CALL_TRAMPOLINE` to call the trampoline, this reuses the stack frame allocated earlier with T=2, but this time it is observed. The pointer to the previous frame is written outside of the call frame because `T` is too small (should be 3). We are now in the internal function `_ZendTestMagicCallForward::__call` where we call the global function `callee`. This will push a new call frame which will overlap `*prev_observed_frame`. This value gets overwritten by `zend_init_func_execute_data` when `EX(opline)` is set because `*prev_observed_frame` overlaps with `EX(opline)`. From now on, `*prev_observed_frame` is corrupted. When `zend_observer_fcall_end` is called this will result in reading wrong value `*prev_observed_frame` into `current_observed_frame`. This causes issues in `zend_observer_fcall_end_all` leading to the segfault we observe.

Despite function with `ZEND_ACC_CALL_VIA_TRAMPOLINE` not being observed, the reuse of call frames makes problems when `T` is not large enough.
To fix this, we make sure to add 1 to `T` if `ZEND_OBSERVER_ENABLED` is true.

Closes GH-16252.
2024-10-07 17:16:43 +02:00
Benjamin Eberlei
72c874691b
RFC: Add #[\Deprecated] Attribute (#11293)
see https://wiki.php.net/rfc/deprecated_attribute

Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com>
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
2024-07-02 09:44:25 +02:00
Arnaud Le Blanc
f7df238971
Merge branch 'PHP-8.3'
* PHP-8.3:
  [ci skip] NEWS for GH-14626
  [ci skip] NEWS for GH-14626
  Fix is_zend_ptr() for huge blocks (#14626)
2024-06-25 15:18:58 +02:00
Arnaud Le Blanc
bc57c77fa2
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  [ci skip] NEWS for GH-14626
  Fix is_zend_ptr() for huge blocks (#14626)
2024-06-25 15:15:46 +02:00
Arnaud Le Blanc
1ff277dee2
Fix is_zend_ptr() for huge blocks (#14626)
is_zend_ptr() expected zend_mm_heap.huge_list to be circular, but it's in fact NULL-terminated. It could crash when at least one huge block exists and the ptr did not belong to any block.
2024-06-25 15:14:00 +02:00
Tim Düsterhus
a1ea464069
gen_stub: Intern the parameter name string for named arguments in internal attributes (#14595)
This is necessary because `zend_get_attribute_object()` will use the persistent
string with the parameter name as the index for a newly created non-persistent
HashTable, which is not legal.

As parameter names are expected to be short-ish, reasonably common terms and
need to sit around in memory anyways, we might as well make them an interned
string, circumstepping the issue without needing to duplicate the parameter
name into a non-persistent string.
2024-06-19 08:06:50 +02:00
Niels Dossche
bcecbb59d3
Merge branch 'PHP-8.3'
* PHP-8.3:
  Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
2024-06-10 19:40:03 +02:00
Niels Dossche
ccdd1c4e67
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
2024-06-10 19:39:25 +02:00
Niels Dossche
bc558bf7a3
Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
Although the issue was demonstrated using Curl, the issue is purely in
the streams layer of PHP.

Full analysis is written in GH-11078 [1], but here is the brief version:
Here's what actually happens:
1) We're creating a FILE handle from a stream using the casting mechanism.
   This will create a cookie-based FILE handle using funopen.
2) We're reading stream data using fread from the userspace stream. This will
   temporarily set a buffer into a field _bf.base [2]. This buffer is now equal
   to the upload buffer that Curl allocated and note that that buffer is owned
   by Curl.
3) The fatal error occurs and we bail out from the fread function, notice how
   the reset code is never executed and so the buffer will still point to
   Curl's upload buffer instead of FILE's own buffer [3].
4) The resources are destroyed, this includes our opened stream and because the
   FILE handle is cached, it gets destroyed as well.
   In fact, the stream code calls through fclose on purpose in this case.
5) The fclose code frees the _bs.base buffer [4].
   However, this is not the buffer that FILE owns but the one that Curl owns
   because it isn't reset properly due to the bailout!
6) The objects are getting destroyed, and so the curl free logic is invoked.
   When Curl tries to gracefully clean up, it tries to free the buffer.
   But that buffer is actually already freed mistakingly by the C library!

This also explains why we can't reproduce it on Linux: this bizarre buffer
swapping only happens on macOS and BSD, not on Linux.

To solve this, we switch to an unbuffered mode for cookie-based FILEs.
This avoids any stateful problems related to buffers especially when the
bailout mechanism triggers. As streams have their own buffering
mechanism, I don't expect this to impact performance.

[1] https://github.com/php/php-src/issues/11078#issuecomment-2155616843
[2] 5e566be7a7/stdio/FreeBSD/fread.c (L102-L103)
[3] 5e566be7a7/stdio/FreeBSD/fread.c (L117)
[4] 5e566be7a7/stdio/FreeBSD/fclose.c (L66-L67)

Closes GH-14524.
2024-06-10 19:38:21 +02:00
Gina Peter Banyard
51379d66ec
Zend: Add object_init_with_constructor() API (#14440)
This will instantiate the object and execute its constructor with the given parameters.
2024-06-06 21:21:16 +01:00
Niels Dossche
889f308e01
Merge branch 'PHP-8.3'
* PHP-8.3:
  Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
2024-05-14 19:56:05 +02:00
Niels Dossche
0e98a05a3d
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
2024-05-14 19:52:19 +02:00
Niels Dossche
ebd1a36670
Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
Some modules may reset _fmode, which causes mangling of line endings.
Always be explicit like we do in other places where the native open call
is used.

Closes GH-14218.
2024-05-14 19:49:22 +02:00
Tim Düsterhus
b5ffac7f6a
Add ReflectionClassConstant::isDeprecated() (#14086)
This is in preparation for php/php-src#11293 and for consistency with
ReflectionConstant::isDeprecated() that was added in php/php-src#13669.
2024-04-30 17:26:27 +02:00
Máté Kocsis
f2e199e878
Implement "support doc comments for internal classes and functions" (#13266)
Fixes #13130
2024-02-25 08:41:31 +01:00
Ilija Tovilo
b7a468cd06
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix leak of call->extra_named_params on internal __call
2023-12-01 16:50:49 +01:00
Ilija Tovilo
f203edd3c5
Fix leak of call->extra_named_params on internal __call
Fixes GH-12835
Closes GH-12836
2023-12-01 16:49:16 +01:00
Niels Dossche
e6fef2944b Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-12633: sqlite3_defensive.phpt fails with sqlite 3.44.0
  Fix GH-12628: The gh11374 test fails on Alpinelinux
2023-11-10 00:12:47 +01:00
Niels Dossche
fbda6b50a3 Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Fix GH-12633: sqlite3_defensive.phpt fails with sqlite 3.44.0
  Fix GH-12628: The gh11374 test fails on Alpinelinux
2023-11-10 00:08:09 +01:00
Niels Dossche
78fba9cb80 Fix GH-12628: The gh11374 test fails on Alpinelinux
Closes GH-12636.
2023-11-10 00:01:22 +01:00
Máté Kocsis
98e8e277b5
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Fix GH-12558 Escape \N in generated stubs
2023-10-31 10:09:22 +01:00
Máté Kocsis
d4e40dc0e1
Fix GH-12558 Escape \N in generated stubs (#12562) 2023-10-31 10:06:56 +01:00
Remi Collet
13d3564a51
Fix #12063 convert PHP single-quote to C double-quote string 2023-08-28 14:48:49 +02:00
Máté Kocsis
c934e24197 Fix GH-9967 Add support for generating custom function, class const, and property attributes in stubs 2023-08-26 21:35:31 +02:00
ju1ius
3e0e7e3f90
releases property attributes of internal classes (#11980)
* adds test case for internal class property attribute

* releases property attributes of internal classes
2023-08-24 16:07:00 +02:00
ju1ius
7f1c3bf09b
Adds support for DNF types in internal functions and properties (#11969)
Note that this does not add support for items generated by gen_stubs,
only for items registered dynamically via the Zend API.

Closes GH-10120
2023-08-19 00:11:06 +01:00
George Peter Banyard
82972f448f Merge branch 'PHP-8.2'
* PHP-8.2:
  Fix various bugs related to DNF types
2023-08-15 17:01:51 +01:00
George Peter Banyard
02a80c5b82 Fix various bugs related to DNF types
- GH-11958: DNF types in trait properties do not get bound properly
 - GH-11883: Memory leak in zend_type_release() for non-arena allocated DNF types
 - Internal trait bound to userland class would not be arena allocated
 - Property DNF types were not properly deep copied during lazy loading

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
Co-authored-by: ju1ius <jules.bernable@gmail.com>
2023-08-15 15:34:33 +01:00
George Peter Banyard
65a02f482f
ext/zend_test: Move object handler test objects to their own file (#11852) 2023-08-02 18:52:55 +01:00
Ben Ramsey
3d5f239474
Merge branch 'PHP-8.2' 2023-07-31 20:15:51 -05:00
Ben Ramsey
7ecb284926
Merge branch 'PHP-8.1' into PHP-8.2 2023-07-31 20:06:37 -05:00