php_array_data_shuffle() first compacts the holes of a packed array and
only then updates nNumUsed. When the engine threw in between, the stale
tail slots were still counted, so the moved values were released twice
when the copied array was destroyed. Update nNumUsed right after the
compaction.
Closes GH-24553.
parse_ip_address_ex() and php_network_parse_network_address_with_port()
read the port with atoi() and did not check its range, so a port above
65535 or below 0 silently wrapped to another port. Reject such ports.
bug69521.phpt relied on this wrapping (port 74321), use an ephemeral
port instead.
Close GH-24621
PHP 8.2 made case-insensitive comparisons ASCII-only, but ksort() and
krsort() with SORT_STRING | SORT_FLAG_CASE and substr_compare() with
case_insensitive=true still used the locale-sensitive _l variants.
These call tolower() and depend on LC_CTYPE.
Use zend_binary_strcasecmp() and zend_binary_strncasecmp(), consistent
with sort() and strncasecmp(), so these comparisons also use ASCII case
folding regardless of the current locale.
Fixes#24552
Co-authored-by: Jon Surrell <sirreal@users.noreply.github.com>
Closes#24558
Deeply nested arrays and objects can exhaust the native stack because
php_var_export_ex() recursively exports their contents without checking
Zend's stack limit.
Check the native stack limit and throw a catchable Error when it is reached.
Propagate failures from recursive object property exports while releasing
temporary values, property tables, and recursion guards on the failure path.
Add regression coverage for deeply nested arrays and objects with a reduced
stack limit. This fixes only the var_export() part of GH-24605; print_r() and
unserialize() remain outside this change's scope.
Closes#24671
var_hash is never null. It is dereferenced elsewhere in the function, so
this function would already crash if it were null. Remove null check and
add assertion.
Entity names are letters and digits. Scan them and stop at the first other
byte instead of searching for a ';' up to 32 bytes ahead and hashing whatever
is in between. Also skip memchr() when the next byte is already '&'.
Output is unchanged. html_entity_decode() on 4 KB inputs:
only '&' 3.5x faster
only entities 1.1x faster
jQuery source 1.1-1.4x faster
jQuery minified 1.4-1.7x faster
HTML pages, Markdown same
"¶m=value" URLs in text up to 1.07x slower
On Solaris/illumos /proc/self/fd entries are not symlinks, so readlink()
fails with EINVAL.
Co-authored-by: David Carlier <devnexen@gmail.com>
Closes GH-24571.
location_len == 0 was used to mean that no buffer was allocated yet, but an empty Location header allocates a 1-byte buffer and leaves location_len at 0. A second Location header then allocated a new buffer and leaked the first. Check the pointer instead.
Closes GH-24512.
Since 2f7b01b86c, `zend_is_callable()` fills in an error string even when it fails because an exception is already pending, so `php_stream_call_error_handler()` threw a TypeError over the StreamException (or whatever the user error handler threw) for any `Class::method` handler. It now only throws when nothing is pending, the same way curl already does.
The same commit made `zend_parse_arg()` leak that error string when it bails out on a pending exception, so it's freed there now too.
Fixes GH-24491
Only close syslog at request shutdown when PHP has opened it, so embedded
hosts retain their syslog connection across requests that do not use it.
When syslog() is called before openlog(), explicitly open the connection
using syslog.ident and syslog.facility, as error_log=syslog already does.
This tracks the connection for request cleanup and changes the implicit
syslog() identity and facility to the configured PHP values.
Add a regression test checking that a connection opened by syslog() is
closed before the next request.
Closes#24310
The test keeps a header larger than 4 GiB alive while sapi_header_op()
duplicates it, so its peak memory usage exceeds 8 GiB. The 6 GiB FreeBSD
CI VM can kill either the test process (Termsig=9) or a test worker.
Skip the test on FreeBSD, following ext/bz2/tests/gh20807.phpt. Run it in
isolation with --CONFLICTS-- all so other tests do not add to its memory
pressure on the remaining platforms.
The new line/NUL check uses a uint32_t index to scan a header whose length
is size_t. For header lines of 4 GiB or more, the index wraps around and
the request never finishes. This also affects session_start() when a
cookie path, domain or session ID produces a header of that size.
Use size_t for the index so it can reach the full header length. Add a
resource-heavy regression test using header() directly, with a newline
after 4 GiB to verify that header validation completes and emits the
usual warning. The test requires a 64-bit platform and runs only when
RUN_RESOURCE_HEAVY_TESTS is enabled and SKIP_SLOW_TESTS is unset.
Closes#24540
The dechunk filter created for Transfer-Encoding: chunked is only appended to the stream's read filters when a stream comes back. When a later header line fails to parse, the stream is closed and the filter was never freed. Free it when there is no stream to own it.
Closes GH-24513.