The reason this breaks is because of a type mismatch.
The following line uses fields of the timeval struct which are both 8 bytes on
Alpine 32-bit, which results in a computed value of also 8 bytes:
https://github.com/php/php-src/blob/b09ed9a0f25cda8c9eea9d140c01587cd50b4aa8/sapi/fpm/fpm/fpm_status.c#L611
However, it is passed to a format string which expects 4 bytes
(`unsigned long` and thus the `%lu` format specifier is 4 bytes on Alpine 32-bit),
resulting in argument corruption.
Since the value is generally small, truncating to 4 bytes is sufficient to fix this.
Closes GH-17286.
A bunch of different issues:
1) The referenced value is copied without incrementing the refcount.
The reason the refcount isn't incremented is because otherwise
the array modifications would violate the RC1 constraints.
Solve this by copying the reference itself instead and always
read the referenced value.
2) No type checks on the array data, so malicious scripts could
cause type confusion bugs.
3) Potential overflow when the arrays resize and we access ctag.
Closes GH-17205.
EX(opline) / opline can be stale if the IP is not stored, like in this
case on a trace enter. We always need to make sure that the opline is up
to date to make sure we don't use stale data.
Closes GH-17260.
This was a bug in both libxml and PHP.
We follow up with the same change as done in GNOME/libxml@b3871dd138.
Changing away from `xmlOutputBufferCreateFilenameDefault` is not
possible yet because this is a stable branch and would break BC.
Closes GH-17254.
The FFI call return values follow widening rules.
We must widen to `ffi_arg` in the case we're handling a return value for types shorter than the machine width.
From http://www.chiark.greenend.org.uk/doc/libffi-dev/html/The-Closure-API.html:
> In most cases, ret points to an object of exactly the size of the type specified when cif was constructed.
> However, integral types narrower than the system register size are widened.
> In these cases your program may assume that ret points to an ffi_arg object.
If we don't do this, we get wrong values when reading the return values.
Closes GH-17255.
Co-authored-by: Dmitry Stogov <dmitry@zend.com>
The issue that BMP RLE occasionally swallowed some pixels[1] had been
fixed long ago in libgd, but apparently it has been overlooked to port
it to our bundled libgd.
We also introduce the test helper `test_image_equals_image()` which
compares in-memory images for equality.
[1] <https://github.com/libgd/libgd/issues/276>
Closes GH-17250.
This bug happens because of a nested `SHM_UNPROTECT()` sequence.
In particular:
```
unprotect memory at ext/opcache/ZendAccelerator.c:2127
protect memory at ext/opcache/ZendAccelerator.c:2160
unprotect memory at ext/opcache/ZendAccelerator.c:2164
unprotect memory at ext/opcache/jit/zend_jit_trace.c:7464
^^^ Nested
protect memory at ext/opcache/jit/zend_jit_trace.c:7591
^^^ Problem is here: it should not protect again due to the nested unprotect
protect memory at ext/opcache/ZendAccelerator.c:2191
^^^ This one should actually protect, not the previous one
```
The reason this nesting happen is because:
1. We try to include the script, this eventually calls `cache_script_in_shared_memory`
2. `zend_optimize_script` will eventually run SCCP as part of the DFA pass.
3. SCCP will try to replace constants, but can also run destructors when a partial array is destructed here:
https://github.com/php/php-src/blob/4e9cde758eadf30cc4d596d6398c2c34c64197b4/Zend/Optimizer/sccp.c#L2387-L2389
In this case, this destruction invokes the GC which invokes the tracing JIT,
leading to the nested unprotects.
This patch disables the GC to prevent invoking user code, as user code
is not supposed to run during the optimizer pipeline.
Closes GH-17249.
Co-authored-by: Dmitry Stogov <dmitry@zend.com>
NULL checks for the glob stream are inconsistently applied. To solve
this generally, factor it out to a helper function so it's less likely
to be forgotten in the future.
Closes GH-17231.
The error handling is incomplete on argument cleanup.
1. The fci is not cleared which means that zend_free_trampoline() is
never called.
2. The cleaning for extra named arguments was missing, resulting in
memory leak.
Closes GH-17219.
When observer is enabled, we normally add an extra temporary to all
functions, to store the previously observed frame. However, this is done in
zend_observer_post_startup() so it doesn't happen to dl'ed() functions.
One possible fix would be to move that from zend_observer_post_startup()
to zend_register_functions(), but this would be too early: Observer may
not be enabled when zend_register_functions() is called, and may still be
enabled later.
However, when zend_register_functions() is called at run-time (during dl()),
we know definitively whether observer is enabled.
Here I update zend_register_functions() to add a temporary to dl'ed()
functions when observer is enabled.
Fixes: GH-17211
Closes: GH-17220
* PHP-8.3:
NEWS for GH-17168
ext/gettext/config.m4: symlink en_US.UTF-8 test bits to en_US for musl
ext/gettext/tests: fix libintl return values under musl
ext/gettext/gettext.c: handle NULLs from bindtextdomain()
`glob(3)` doesn't know the virtual CWD of PHP, so we need to pass an
absolute path for ZTS builds. In lack of a reusable routine, we copy
the code from `glob()` and adapt as needed.
Closes GH-17074.
Because the properties table contains both a numeric index and a string
index that map to 0 in a symbol table, this causes an assertion failure.
Looking at the manual page of get_object_vars(), it seems that only real
properties must be included. Given that SplFixedArray's elements are not
accessible like properties, they should be excluded. This restores PHP
8.3 behaviour. The reason that this didn't cause problems on 8.3 is
because it used a different handler (get_properties).
Closes GH-17206.
If a bucket previously had a non-interned string, and is now replaced
with an interned string, then the type flags still incorrectly state
it's a non-interned string. This leads to the refcount being edited for
interned strings, which in turn can lead to a crash when protect_memory
is set.
Closes GH-17207.
ZEND_FETCH_DIM_FUNC_ARG should also be repeated on undefined access,
consistent to how ZEND_FETCH_DIM_R is handled. The opcode was just
missing from the assertion list.
Closes GH-17148.
Co-authored-by: Dmitry Stogov <dmitry@zend.com>