Skip to content

Commit ec4c51f

Browse files
Merge branch 'master' into array-chunk-fill
2 parents 5e2e4c4 + 3057132 commit ec4c51f

152 files changed

Lines changed: 2665 additions & 147 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,20 @@ locations.
211211
└─ gd/
212212
├─ libgd/ # Bundled and modified GD library https://github.com/libgd/libgd
213213
└─ ...
214+
└─ hash/
215+
├─ xxhash/ # Bundled xxHash library https://github.com/Cyan4973/xxHash
216+
└─ ...
217+
└─ lexbor/
218+
├─ lexbor/ # Bundled and modified Lexbor library https://github.com/lexbor/lexbor
219+
└─ ...
214220
└─ mbstring/
215221
├─ libmbfl/ # Forked and maintained in php-src
216222
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
217223
└─ ...
218224
└─ opcache/
219225
└─ jit/
220-
└─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir
226+
├─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir
227+
└─ ...
221228
└─ pcre/
222229
├─ pcre2lib/ # https://www.pcre.org/
223230
└─ ...
@@ -230,10 +237,14 @@ locations.
230237
├─ credits_ext.h # Generated by `scripts/dev/credits`
231238
├─ credits_sapi.h # Generated by `scripts/dev/credits`
232239
├─ html_tables.h # Generated by `ext/standard/html_tables/html_table_gen.php`
240+
├─ libavifinfo/ # Bundled libavifinfo https://aomedia.googlesource.com/libavifinfo
233241
└─ ...
234242
└─ tokenizer/
235243
├─ tokenizer_data.c # Generated by `ext/tokenizer/tokenizer_data_gen.sh`
236244
└─ ...
245+
└─ uri/
246+
├─ uriparser/ # Bundled uriparser https://github.com/uriparser/uriparser
247+
└─ ...
237248
└─ zend_test # For testing internal APIs. Not needed for regular builds.
238249
└─ ...
239250
└─ zip/ # Bundled https://github.com/pierrejoye/php_zip
@@ -247,6 +258,8 @@ locations.
247258
└─ sapi/ # PHP SAPI modules
248259
└─ cli/
249260
├─ mime_type_map.h # Generated by `sapi/cli/generate_mime_type_map.php`
261+
├─ php_http_parser.[ch] # Forked from https://github.com/nodejs/http-parser
262+
├─ ps_title.c # Adopted from https://github.com/postgres/postgres/blob/master/src/backend/utils/misc/ps_status.c
250263
└─ ...
251264
└─ ...
252265
├─ scripts/ # php-config, phpize and internal development scripts

NEWS

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,43 @@ PHP NEWS
66
. Fixed bug GH-23242 (PHP development server does not support Expect
77
100-continue flow control). (Sjoerd Langkemper)
88

9+
- DOM:
10+
. Fixed NamedNodeMap::getNamedItemNS() with an empty URI not matching
11+
the null namespace in spec-following mode. (Ilia Alshanetsky)
12+
. Fixed stale getElementsByClassName() and other node list caches after
13+
className/classList writes and attribute removals. (Ilia Alshanetsky)
14+
15+
- Hash:
16+
. Fixed hash_file() reporting argument #1 ($algo) instead of argument #2
17+
($filename) when the filename contains null bytes. (lacatoire)
18+
919
- Intl:
20+
. Fixed grapheme_strpos() and grapheme_strrpos() with an empty needle
21+
returning UTF-16 offsets instead of grapheme offsets. (Ilia Alshanetsky)
22+
. Fixed a memory leak when dumping IntlCalendar instances. (Ilia Alshanetsky)
23+
. Fixed Collator::sortWithSortKeys() allocating fixed 2MiB buffers
24+
regardless of array size. (Ilia Alshanetsky)
1025
. Fixed a memory leak when iterating IntlBreakIterator::getPartsIterator()
1126
results. (iliaal)
1227
. Fixed a leak in Locale::getKeywords() when a keyword value cannot be
1328
read. (iliaal)
1429
. Fixed a use-after-free when IntlRuleBasedBreakIterator is constructed
1530
from compiled rules. (iliaal)
31+
. Fixed Spoofchecker methods not recording the ICU error code when an ICU
32+
call fails. (Ilia Alshanetsky)
33+
. Fixed idn_to_ascii() and idn_to_utf8() reporting argument #2 ($flags)
34+
instead of argument #3 ($variant) for an invalid IDNA variant, and the
35+
domain length error message printing a literal "d" instead of the limit.
36+
(lacatoire)
37+
38+
- MBString:
39+
. Fixed mb_ereg_replace() emitting a NUL or out-of-bounds bytes in the
40+
replacement when a \k<name> backref has no closing delimiter.
41+
(Ilia Alshanetsky)
42+
43+
- PCNTL:
44+
. Fixed the declared signature of pcntl_signal(), whose $restart_syscalls
45+
argument accepts null and defaults to it. (lacatoire)
1646

1747
- PDO_PGSQL:
1848
. Added Pdo\Pgsql::ATTR_CHUNK_SIZE to fetch a result set in chunks of the
@@ -28,6 +58,15 @@ PHP NEWS
2858
. Fixed bug GH-23477 (Memory leak on duplicate native Phar manifest entries).
2959
(Weilin Du)
3060

61+
- Sockets:
62+
. Fixed socket_set_option() with SO_ATTACH_REUSEPORT_CBPF and a zero value,
63+
which detached the classic BPF filter instead of the reuseport program.
64+
(David Carlier)
65+
66+
- SOAP:
67+
. Fixed WSDL cache corruption when a soap:header defines headerfaults.
68+
(Ilia Alshanetsky)
69+
3170
- Standard:
3271
. Fixed a segfault when a stream filter callback unsets StreamBucket::$data
3372
before re-attaching the bucket. (iliaal)
@@ -39,6 +78,10 @@ PHP NEWS
3978
. Improved performance of array_chunk() when not preserving keys.
4079
(mehmetcansahin)
4180

81+
- SimpleXML:
82+
. Fixed writing to a dimension of the object returned by attributes() not
83+
creating the attribute. (Ilia Alshanetsky)
84+
4285

4386
27 Aug 2026, PHP 8.6.0beta2
4487

@@ -139,7 +182,7 @@ PHP NEWS
139182
. It is now possible to use the AES192, AES192C, AES256, and AES256C as
140183
SNMPv3 security protocols if the underlying library supports them.
141184
(eskyuu)
142-
. It is now possible to reset the MIB tree using the new snmp_read_mib()
185+
. It is now possible to reset the MIB tree using the new snmp_init_mib()
143186
function. (eskyuu)
144187
. Additional MIB parsing and output control functionality has been exposed
145188
via the snmp_set_mib_option(), snmp_set_output_option(),
@@ -622,6 +665,8 @@ PHP NEWS
622665
. Deprecate returning values from __construct() and __destruct(). (timwolla)
623666
. base_convert, bindex, hexdec and octdec now raise a notice when they cannot
624667
precisely convert the given number. (Sjoerd Langkemper)
668+
. Added error_include_args INI option to make the display of function
669+
arguments consistent in error output. (Calvin Buckley)
625670

626671
- BCMath:
627672
. Added NUL-byte validation to BCMath functions. (jorgsowa)

UPGRADING

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ PHP 8.6 UPGRADE NOTES
133133
unchanged. Previously, NUL bytes were silently accepted: for cookie_path
134134
and cookie_domain this caused the SAPI to drop the Set-Cookie header; for
135135
cache_limiter the value was silently truncated at the NUL byte.
136-
. A ValueError is not thrown if $name is a string containing NUL bytes in
136+
. A ValueError is thrown if $name is a string containing NUL bytes in
137137
session_module_name().
138138
. session_encode() now returns an empty string instead of false for empty
139139
sessions. It only returns false now when the session data could not be
@@ -199,6 +199,16 @@ PHP 8.6 UPGRADE NOTES
199199
rules" message. Code that compares the exact message may need to be
200200
updated.
201201

202+
- Sockets:
203+
. socket_set_option() with SO_ATTACH_REUSEPORT_CBPF now requires an int
204+
$value and a $level of SOL_SOCKET. Any other value type throws a TypeError
205+
instead of being coerced, and any other level raises a warning and returns
206+
false.
207+
. socket_set_option() with SO_ATTACH_REUSEPORT_CBPF and a $value of 0 now
208+
detaches the reuseport filter through SO_DETACH_REUSEPORT_BPF. It
209+
previously used SO_DETACH_BPF, an alias of SO_DETACH_FILTER, which left the
210+
reuseport program attached.
211+
202212
- Sodium:
203213
. The password-hashing functions sodium_crypto_pwhash(),
204214
sodium_crypto_pwhash_str(),
@@ -309,6 +319,9 @@ PHP 8.6 UPGRADE NOTES
309319
when the "remove_all_path" option is not of type bool, or when the
310320
"comp_method", "comp_flags", or "enc_method" options are not of type int
311321
(numeric strings are coerced), instead of emitting a warning.
322+
. Serializing or unserializing a ZipArchive now throws an Exception. A
323+
subclass can override __serialize() and __unserialize() to round-trip
324+
through ZipArchive::closeString() and ZipArchive::openString().
312325

313326
- Zlib:
314327
. deflate_init() now raises a TypeError when the value for option "level",
@@ -484,10 +497,10 @@ PHP 8.6 UPGRADE NOTES
484497
RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection
485498
. Added Uri\Rfc3986\Uri::getHostType() and Uri\WhatWg\Url::getHostType().
486499
RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection
487-
. Added Uri\Rfc3986\UriBuilder.
488-
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
489-
. Added Uri\WhatWg\UrlBuilder.
500+
. Added Uri\Rfc3986\UriBuilder and Uri\WhatWg\UrlBuilder.
490501
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
502+
. Added Uri\url_percent_encode().
503+
RFC: https://wiki.php.net/rfc/uri_followup#percent-encoding_support
491504

492505
========================================
493506
3. Changes in SAPI modules
@@ -629,6 +642,12 @@ PHP 8.6 UPGRADE NOTES
629642
5. Changed Functions
630643
========================================
631644

645+
- Filter:
646+
. filter_var_array() return type has been narrowed from array|false|null to
647+
array|false. The function always establishes an array before filtering, so
648+
null was never returned. filter_input_array() is unaffected: it still
649+
returns null when the requested superglobal does not exist.
650+
632651
- GMP:
633652
. gmp_fact() now throws a ValueError if $num does not fit into an unsigned
634653
long.
@@ -639,6 +658,10 @@ PHP 8.6 UPGRADE NOTES
639658
. gmp_powm() modulo-by-zero now raises a DivisionByZeroError whose message
640659
includes the function name and argument index ($modulus).
641660

661+
- LDAP:
662+
. ldap_free_result() return type has been narrowed from bool to true. The
663+
function already always returned true.
664+
642665
- MySQLi:
643666
. The return structure of mysqli_get_charset() no longer contains the
644667
undocumented "comment" element. The value of "charsetnr" is now set to a
@@ -800,7 +823,7 @@ PHP 8.6 UPGRADE NOTES
800823
. StreamPollHandle
801824

802825
- URI:
803-
. Uri\Rfc3986\UriBuilder
826+
. Uri\Rfc3986\UriBuilder and Uri\WhatWg\UrlBuilder
804827
RFC: https://wiki.php.net/rfc/uri_followup#uri_building
805828

806829
========================================
@@ -860,6 +883,29 @@ PHP 8.6 UPGRADE NOTES
860883
. EAI_ALLDONE.
861884
. EAI_INTR.
862885
. EAI_IDN_ENCODE.
886+
. SO_DETACH_REUSEPORT_BPF (Linux only).
887+
888+
- Sodium:
889+
. SODIUM_CRYPTO_IPCRYPT_BYTES.
890+
. SODIUM_CRYPTO_IPCRYPT_KEYBYTES.
891+
. SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES.
892+
. SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES.
893+
. SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES.
894+
. SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES.
895+
. SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES.
896+
. SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES.
897+
. SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES.
898+
. SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES.
899+
. SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES.
900+
. SODIUM_CRYPTO_IPCRYPT_PFX_BYTES.
901+
. SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES.
902+
. SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES.
903+
. SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES.
904+
. SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES.
905+
. SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES.
906+
. SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES.
907+
. SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES.
908+
. SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES.
863909

864910
- Standard:
865911
. ARRAY_FILTER_USE_VALUE.
@@ -871,6 +917,15 @@ PHP 8.6 UPGRADE NOTES
871917
11. Changes to INI File Handling
872918
========================================
873919

920+
- Core:
921+
. The error_include_args INI option has been added to make the display of
922+
function arguments consistent in errors; it is off by default. Previously,
923+
some functions shown a parameter in the error that was up to each call to
924+
the internal error function. Now, all parameters as were actually passed to
925+
the function will be displayed. This uses the same infrastructure as stack
926+
traces, so i.e. sensitive parameters will not be displayed, and strings
927+
will be truncated according to zend.exception_string_param_max_len.
928+
874929
- Mbstring:
875930
. The mbstring.detect_order INI directive now updates the internal detection
876931
order when changed at runtime via ini_set(). Previously, runtime changes
@@ -940,6 +995,9 @@ PHP 8.6 UPGRADE NOTES
940995
. Made splitText() faster and consume less memory.
941996

942997
- GD:
998+
. imagebmp(), imagewbmp(), imagegd(), and imagegd2() now buffer output when
999+
writing to PHP streams, significantly improving performance when writing
1000+
images to files.
9431001
. Improved performance of imagegrabscreen() and imagegrabwindow() on
9441002
Windows.
9451003

@@ -960,6 +1018,7 @@ PHP 8.6 UPGRADE NOTES
9601018

9611019
- Standard:
9621020
. Improved performance of array_chunk() when not preserving keys.
1021+
. Improved performance of sorting single-element arrays.
9631022
. Improved performance of array_fill_keys().
9641023
. Improved performance of array_intersect().
9651024
. Improved performance of array_map() with multiple arrays passed.

Zend/Optimizer/zend_func_infos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static const func_info_t func_infos[] = {
9595
F1("finfo_buffer", MAY_BE_STRING|MAY_BE_FALSE),
9696
F1("mime_content_type", MAY_BE_STRING|MAY_BE_FALSE),
9797
F1("filter_input_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_FALSE|MAY_BE_NULL),
98-
F1("filter_var_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_FALSE|MAY_BE_NULL),
98+
F1("filter_var_array", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_FALSE),
9999
F1("filter_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
100100
F1("ftp_raw", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL),
101101
F1("ftp_nlist", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),

Zend/tests/is_a_string.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
is_a() with $allow_string false and a string
3+
--FILE--
4+
<?php
5+
6+
class Demo {}
7+
8+
var_dump(is_a(Demo::class, Demo::class, true));
9+
var_dump(is_a(Demo::class, Demo::class, false));
10+
11+
?>
12+
--EXPECTF--
13+
bool(true)
14+
15+
Deprecated: Calling is_a() with a string when $allow_string is false in %s on line %d
16+
bool(false)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
is_subclass_of() with $allow_string false and a string
3+
--FILE--
4+
<?php
5+
6+
class Demo {}
7+
8+
class Child extends Demo {}
9+
10+
var_dump(is_subclass_of(Child::class, Demo::class, true));
11+
var_dump(is_subclass_of(Child::class, Demo::class, false));
12+
13+
?>
14+
--EXPECTF--
15+
bool(true)
16+
17+
Deprecated: Calling is_subclass_of() with a string when $allow_string is false in %s on line %d
18+
bool(false)

Zend/zend.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,13 +1487,14 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14871487
info->lineno = error_lineno;
14881488
info->filename = zend_string_copy(error_filename);
14891489
info->message = zend_string_copy(message);
1490-
EG(errors).size++;
1491-
if (EG(errors).size > EG(errors).capacity) {
1490+
uint32_t new_size = EG(errors).size + 1;
1491+
if (new_size > EG(errors).capacity) {
14921492
uint32_t capacity = EG(errors).capacity ? EG(errors).capacity + (EG(errors).capacity >> 1) : 2;
14931493
EG(errors).errors = erealloc(EG(errors).errors, sizeof(zend_error_info *) * capacity);
14941494
EG(errors).capacity = capacity;
14951495
}
1496-
EG(errors).errors[EG(errors).size - 1] = info;
1496+
EG(errors).errors[EG(errors).size] = info;
1497+
EG(errors).size = new_size;
14971498

14981499
/* Do not process non-fatal recorded error */
14991500
if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) {

Zend/zend_alloc.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,20 @@ static zend_always_inline void *zend_mm_realloc_heap(zend_mm_heap *heap, void *p
18411841
/* Huge Runs (again) */
18421842
/*********************/
18431843

1844+
/* Huge block metadata is allocated from the very heap it describes, so a heap
1845+
* overflow can reach it. size ends up as a munmap() length, where a corrupted
1846+
* value would unmap unrelated mappings, so bound it before use: a live block is
1847+
* page aligned and is still accounted for in real_size. */
1848+
static zend_always_inline void zend_mm_check_huge_block_size(const zend_mm_heap *heap, size_t size)
1849+
{
1850+
ZEND_MM_CHECK(size != 0 && ZEND_MM_ALIGNED_OFFSET(size, REAL_PAGE_SIZE) == 0, "zend_mm_heap corrupted");
1851+
#if ZEND_MM_STAT || ZEND_MM_LIMIT
1852+
ZEND_MM_CHECK(size <= heap->real_size, "zend_mm_heap corrupted");
1853+
#else
1854+
(void)heap;
1855+
#endif
1856+
}
1857+
18441858
#if ZEND_DEBUG
18451859
static void zend_mm_add_huge_block(zend_mm_heap *heap, void *ptr, size_t size, size_t dbg_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
18461860
#else
@@ -1890,6 +1904,7 @@ static size_t zend_mm_get_huge_block_size(zend_mm_heap *heap, void *ptr ZEND_FIL
18901904
zend_mm_huge_list *list = heap->huge_list;
18911905
while (list != NULL) {
18921906
if (list->ptr == ptr) {
1907+
zend_mm_check_huge_block_size(heap, list->size);
18931908
return list->size;
18941909
}
18951910
list = list->next;
@@ -2000,6 +2015,7 @@ static void zend_mm_free_huge(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZE
20002015

20012016
ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE) == 0, "zend_mm_heap corrupted");
20022017
size = zend_mm_del_huge_block(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2018+
zend_mm_check_huge_block_size(heap, size);
20032019
zend_mm_chunk_free(heap, ptr, size);
20042020
#if ZEND_MM_STAT || ZEND_MM_LIMIT
20052021
heap->real_size -= size;
@@ -2492,6 +2508,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
24922508
while (list) {
24932509
zend_mm_huge_list *q = list;
24942510
list = list->next;
2511+
zend_mm_check_huge_block_size(heap, q->size);
24952512
zend_mm_chunk_free(heap, q->ptr, q->size);
24962513
}
24972514

0 commit comments

Comments
 (0)