Commit d3f361c3b7f for php.net
commit d3f361c3b7ff7d9fd428f9ee5112885898cb4e43
Merge: 1b091dcf375 416985389d0
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date: Tue Jul 28 11:50:34 2026 +0200
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
Add NEWS entries
Fix GHSA-vc5h-9ppw-p5f3: phar circular symlink crash
Fix SQL injection in ext-pgsql via E'...' backslash breakout
libgd patch for CVE-2026-9672
diff --cc NEWS
index 1dc666e361b,875982a3eb9..54dea5289ff
--- a/NEWS
+++ b/NEWS
@@@ -1,198 -1,26 +1,211 @@@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- ?? ??? ????, PHP 8.4.24
-?? ??? ????, PHP 8.3.33
++?? ??? ????, PHP 8.4.25
- Date:
. Fixed leak on double DatePeriod::__construct() call. (ilutov)
+- DOM:
+ . Fixed bug GH-22825 (DOMElement::setAttribute() fails silently when the DTD
+ declares a default value for the attribute). (iliaal)
+ . Fixed bug GH-22447 (UAF at dom_objects_free_storage when setting an
+ attribute node that collides by local name with a namespaced
+ attribute). (David Carlier)
+
+- MBString:
+ . Fixed bug GH-22779 (mb_strrpos() returns the wrong position for a negative
+ offset in a non-UTF-8 encoding). (Eyüp Can Akman)
+
+- PCRE:
+ . Fixed bug GH-21134 (Crash with \C + UTF-8). Using \C in UTF-8 patterns is
+ now forbidden. (Arnaud)
+
+- Sockets:
+ . Fixed various memory related issues in ext/sockets. (David Carlier)
+
+- Streams:
+ . Fixed bug GH-15836 (Use-after-free when a user stream filter accesses
+ $this->stream during the close flush). (iliaal)
+
+30 Jul 2026, PHP 8.4.24
+
++- BCMath:
++ . Fixed GHSA-x692-q9x7-8c3f (Out-of-bounds write in bccomp()).
++ (CVE-2026-17544) (Recep Asan)
++
+- Calendar:
+ . Fixed bug GH-22602 (gregoriantojd() and juliantojd() integer overflow with
+ INT_MAX year). (arshidkv12)
+
+- Date:
+ . Update timelib to 2022.17. (Derick)
+ . Fixed bug GH-19803 (Parsing a string with a single white space does create
+ an error). (Derick)
+ . Fixed Unix timestamps in February of the year 0 are misparsed with
+ @-notation. (LukasGelbmann)
+ . Fixed bug GH-11310 (__debugInfo does nothing on userland classes extending
+ Date classes). (Derick)
+
+- DBA:
+ . Fixed OOB read on malformed length field in dba flatfile handler. (alhudz)
+
+- DOM:
+ . Fixed bug GH-22570 (Stack overflow when serializing a deeply nested
+ Dom\XMLDocument). (iliaal)
+
+- Exif:
+ . Fixed bug GH-11020 (exif_read_data() emits a spurious "Illegal IFD size"
+ warning when an IFD is not followed by a next-IFD offset). (Eyüp Can Akman)
+
+ - GD:
+ . Upgrade libgd. (CVE-2026-9672) (Pierre Joye)
+
+- Hash:
+ . Fixed bug GH-18173 (ext/hash relies on implementation-defined malloc
+ alignment). (iliaal)
+
+- Intl:
+ . Fixed Locale::lookup() and locale_lookup() to return NULL instead of the
+ fallback locale when a language tag cannot be canonicalized. (Weilin Du)
+ . Fixed memory leaks when calling Collator::__construct() or
+ Spoofchecker::__construct() twice. (Weilin Du)
+ . Fixed IntlChar methods leaving stale global error state after successful
+ calls. (Xuyang Zhang)
+
+- ODBC:
+ . Fixed bug GH-22668 (Heap buffer over-read when a column value exceeds the
+ driver-reported display size). (iliaal)
+
+- OpenSSL:
+ . Fixed timeout for supplemental read at end of a blocking stream in SSL
+ stream wrapper. (ilutov)
+
+- PDO_ODBC:
+ . Fixed bug GH-20726 (Crash with ODBC connection pooling when the DSN
+ carries no credentials). (iliaal)
+ . Fixed bug GH-22667 (Heap buffer over-read when a column value exceeds the
+ driver-reported display size). (iliaal)
+ . Fixed bug GH-22666 (Heap buffer overflow when an output parameter value is
+ longer than the declared maxlen). (iliaal)
+ . Fixed bug GH-22665 (Out-of-bounds write when the ODBC driver reports a
+ diagnostic message length beyond the error buffer). (iliaal)
+
+ - PGSQL:
+ . Fixed GHSA-7qpv-r5mr-78m4 (SQL injection via E'...' backslash breakout).
+ (CVE-2026-17543) (ilutov)
+
- Phar:
+ . Fixed inconsistent handling of the magic ".phar" directory. Paths such as
+ "/.phar" remain protected, while non-magic paths that merely start with
+ ".phar" are handled consistently across file and directory creation,
+ copying, ArrayAccess, stream lookup, directory iteration and extraction.
+ (Weilin Du)
+ . Fixed GHSA-vc5h-9ppw-p5f3 (Crash via recursive symlinks). (CVE-2026-7260)
+ (Jakub Zelenka)
-02 Jul 2026, PHP 8.3.32
+- PHPDBG:
+ . Fixed bug GH-17387 (Trivial crash in phpdbg lexer). (iliaal)
+ . Fixed fleaked lowercased lookup keys in phpdbg_resolve_opline_break.
+ (jorgsowa)
+ . Fixed off-by-one in phpdbg_safe_class_lookup() causing class lookups to
+ always fail during phpdbg's signal-safe interruption path. (jorgsowa)
+
+- Reflection:
+ . Fixed bug GH-22324 (Ignore leading namespace separator in
+ ReflectionParameter::__construct()). (jorgsowa)
+ . Fixed bug GH-22441 (ReflectionClass::hasProperty() and getProperty() ignore
+ dynamic properties shadowing a private parent property). (iliaal)
+ . Fixed bug GH-22658 (ReflectionConstant::__toString() with a string value
+ with null bytes truncates output). (DanielEScherzer)
+ . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes).
+ (DanielEScherzer)
+
+- Session:
+ . Fixed bug GH-21314 (Different session garbage collector behavior between
+ PHP 8.3 and PHP 8.5). (jorgsowa)
+
+- SPL:
+ . Fix class_parents for classes with leading slash in non-autoload mode.
+ (jorgsowa)
+ . Ignore leading back-slash in class_parents(), class_implements(), and
+ class_uses(). (jorgsowa)
+ . Fixed bug GH-16217 (SplFileObject::fputcsv() on an uninitialized object
+ segfaults). (iliaal)
+
+- Standard:
+ . Fixed bug GH-22360 (convert.base64-encode corruption on
+ incremental flush). (David Carlier)
+ . Fixed bug GH-22395 (base_convert() outputs at most 64 characters).
+ (Weilin Du)
+ . Fixed integer overflow in getimagesize() and getimagesizefromstring()
+ when parsing an IFF chunk with a size of INT_MAX. (David Carlier, Weilin Du)
+ . Fixed bug GH-22678 (Use-after-free in array_multisort() when the comparator
+ mutates the array being sorted). (azchin, iliaal)
- Streams:
- . Fixed bug GH-21468 (Segfault in file_get_contents w/ a https URL
- and a proxy set). (CVE-2026-12184) (ndossche)
+ . Fixed bug GH-22617 (persistent stream keys truncated at null bytes, causing
+ distinct abstract unix domain sockets to share a resource). (David Carlier)
+
+- Zip:
+ . Fixed bug GH-22649 (ZipArchive::setCommentName() and setCommentIndex()
+ could crash after overwriting an entry and resetting its inherited
+ unchanged comment). (Weilin Du)
+ . Fixed bug GH-21705 (ZipArchive::getFromIndex() ignores
+ ZipArchive::FL_UNCHANGED for deleted entries). (Weilin Du)
+
+02 Jul 2026, PHP 8.4.23
+
+- Core:
+ . Fixed bug GH-22280 (Incorrect compile error for goto to label preceding
+ try/finally block). (Pratik Bhujel)
+ . Fixed bug GH-22290 (AST pretty printing does not correctly handle strings
+ containing NUL). (iliaal)
+
+- BCMath:
+ . Fixed issues with oversized allocations and signed overflow in bcround()
+ and BcMath\Number::round(). (edorian)
+
+- Date:
+ . Fix incorrect recurrence check of DatePeriod::createFromISO8601String().
+ (ndossche)
+
+- DOM:
+ . Fix GH-22219 (Dom\XMLDocument::schemaValidate fails to resolve
+ xs:QName with prefix from imported schema). (David Carlier)
+
+- Exif:
+ . Read correct value for single and double tags. (ndossche)
+
+- GD:
+ . Fixed bug GH-22121 (Double free in gdImageSetStyle() after
+ overflow-triggered early return). (iliaal)
+ . Fixed bug GH-19666 (imageconvolution() unexpected nan filter value).
+ (David Carlier)
+ . Fixed bug GH-19739 (imageellipse/imagefilledellipse overflow).
+ (David Carlier)
+ . Fixed bug GH-19730 (imageaffine overflow).
+ (David Carlier)
+
+- Intl:
+ . Fix incorrect argument positions for uninitialized calendar arguments in
+ IntlCalendar::equals(), ::before(), ::after(), and ::isEquivalentTo(), and
+ for invalid start/end arguments in transliterator_transliterate().
+ (Weilin Du)
+ . Fixed IntlTimeZone::getDisplayName() to synchronize object error state
+ for invalid display types. (Weilin Du)
+ . Fixed Spoofchecker restriction-level APIs to only be exposed with ICU 53
+ and later. (Graham Campbell)
+
+- mysqli:
+ . Fix stmt->query leak in mysqli_execute_query() validation errors.
+ (David Carlier)
+
+- Opcache:
+ . Fixed bug GH-20469 (Unsafe inheritance cache replay with reentrant
+ autoloading). (Levi Morrison)
+ . Fixed bug GH-22158 (Tracing JIT dispatches the observer begin handler
+ through the wrong run_time_cache slot on megamorphic calls). (ptondereau,
+ iliaal)
- OpenSSL:
. Fixed bug GH-22187 (Memory corruption (zend_mm_heap corrupted) in
diff --cc ext/pgsql/tests/10pg_convert_9.phpt
index d733b888fe0,fb36e5801c8..2ef325dbc97
--- a/ext/pgsql/tests/10pg_convert_9.phpt
+++ b/ext/pgsql/tests/10pg_convert_9.phpt
@@@ -51,15 -50,11 +53,19 @@@ try
} catch (\TypeError $e) {
echo $e->getMessage(), \PHP_EOL;
}
+
+ /* standard_conforming_strings = 1 */
+ pg_query($db, "SET standard_conforming_strings = 1");
+ var_dump(pg_convert($db, $table_name, ['str' => "\\' OR 1=1"]));
?>
+--CLEAN--
+<?php
+include('inc/config.inc');
+$table_name = "table_10pg_convert_9";
+
+$db = pg_connect($conn_str);
+pg_query($db, "DROP TABLE IF EXISTS {$table_name}");
+?>
--EXPECT--
array(3) {
[""num""]=>
diff --cc ext/pgsql/tests/12pg_insert_9.phpt
index b986d14e15d,699426c89b2..7782c93ef7a
--- a/ext/pgsql/tests/12pg_insert_9.phpt
+++ b/ext/pgsql/tests/12pg_insert_9.phpt
@@@ -56,17 -53,9 +56,17 @@@ try
echo "Ok\n";
?>
+--CLEAN--
+<?php
+include('inc/config.inc');
+$table_name = "table_12pg_insert_9";
+
+$db = pg_connect($conn_str);
+pg_query($db, "DROP TABLE IF EXISTS {$table_name}");
+?>
--EXPECTF--
- INSERT INTO "table_12pg_insert_9" ("num","str","bin") VALUES (1234,E'AAA',E'\\x424242');
-INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES (1234,'AAA','\\x424242');
-INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES ('1234','AAA','BBB');
++INSERT INTO "table_12pg_insert_9" ("num","str","bin") VALUES (1234,'AAA','\\x424242');
+INSERT INTO "table_12pg_insert_9" ("num","str","bin") VALUES ('1234','AAA','BBB');
object(PgSql\Result)#%d (0) {
}
Array of values must be an associative array with string keys
diff --cc ext/pgsql/tests/14pg_update_9.phpt
index 602019c2fb6,64493075490..6bcea512150
--- a/ext/pgsql/tests/14pg_update_9.phpt
+++ b/ext/pgsql/tests/14pg_update_9.phpt
@@@ -30,15 -25,7 +30,15 @@@ echo pg_update($db, $table_name, $field
echo "Ok\n";
?>
+--CLEAN--
+<?php
+include('inc/config.inc');
+$table_name = "table_14pg_update_9";
+
+$db = pg_connect($conn_str);
+pg_query($db, "DROP TABLE IF EXISTS {$table_name}");
+?>
--EXPECT--
- UPDATE "table_14pg_update_9" SET "num"=1234,"str"=E'ABC',"bin"=E'\\x58595a' WHERE "num"=1234;
-UPDATE "php_pgsql_test" SET "num"=1234,"str"='ABC',"bin"='\\x58595a' WHERE "num"=1234;
-UPDATE "php_pgsql_test" SET "num"='1234',"str"='ABC',"bin"='XYZ' WHERE "num"='1234';
++UPDATE "table_14pg_update_9" SET "num"=1234,"str"='ABC',"bin"='\\x58595a' WHERE "num"=1234;
+UPDATE "table_14pg_update_9" SET "num"='1234',"str"='ABC',"bin"='XYZ' WHERE "num"='1234';
Ok
diff --cc ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt
index 00000000000,88b37a8432f..93f6376bb1c
mode 000000,100644..100644
--- a/ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt
+++ b/ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt
@@@ -1,0 -1,58 +1,58 @@@
+ --TEST--
+ GHSA-7qpv-r5mr-78m4: SQL injection via E'...' backslash breakout
+ --CREDITS--
+ expatch.llc
+ --EXTENSIONS--
+ pgsql
+ --SKIPIF--
-<?php include("skipif.inc"); ?>
++<?php include("inc/skipif.inc"); ?>
+ --FILE--
+ <?php
-include 'config.inc';
++include 'inc/config.inc';
+
+ $db = pg_connect($conn_str);
+
+ pg_query($db, "SET standard_conforming_strings = 1");
+
+ pg_query($db, "DROP TABLE IF EXISTS ghsa_7qpv_r5mr_78m4");
+ pg_query($db, "CREATE TABLE ghsa_7qpv_r5mr_78m4 (id serial primary key, name text, admin boolean)");
+ pg_query($db, "INSERT INTO ghsa_7qpv_r5mr_78m4 (name, admin) VALUES ('alice', false), ('bob', false)");
+
+ $params = ['name' => "zzz' OR 1=1 --"];
+ echo pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n";
+ printf("returned: %d\n\n", count(pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params)));
+
+ $params = ['name' => "zzz\\' OR 1=1 --"];
+ echo pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n";
+ printf("returned: %d\n\n", count(pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params)));
+
+ $params = ['name' => "john\\', true) --", 'admin' => 'false'];
+ echo pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n";
+ pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params);
+ var_dump(pg_select($db, 'ghsa_7qpv_r5mr_78m4', ['id' => 3])[0]['admin']);
+ echo "\n";
+
+ $params = ['name' => "jake\\', true) --", 'admin' => 'f'];
+ echo pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_ESCAPE|PGSQL_DML_STRING) . "\n";
+ pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_EXEC|PGSQL_DML_ESCAPE);
+ var_dump(pg_select($db, 'ghsa_7qpv_r5mr_78m4', ['id' => 4])[0]['admin']);
+
+ ?>
+ --EXPECT--
+ SELECT * FROM "ghsa_7qpv_r5mr_78m4" WHERE "name"='zzz'' OR 1=1 --';
+ returned: 0
+
+ SELECT * FROM "ghsa_7qpv_r5mr_78m4" WHERE "name"='zzz\'' OR 1=1 --';
+ returned: 0
+
+ INSERT INTO "ghsa_7qpv_r5mr_78m4" ("name","admin") VALUES ('john\'', true) --','f');
+ string(1) "f"
+
+ INSERT INTO "ghsa_7qpv_r5mr_78m4" ("name","admin") VALUES ('jake\'', true) --','f');
+ string(1) "f"
+ --CLEAN--
+ <?php
-include('config.inc');
++include('inc/config.inc');
+ $db = pg_connect($conn_str);
+ pg_query($db, "DROP TABLE IF EXISTS ghsa_7qpv_r5mr_78m4");
+ ?>
diff --cc ext/pgsql/tests/bug68638.phpt
index 957e9a33abf,2a1025cad8d..267423a2226
--- a/ext/pgsql/tests/bug68638.phpt
+++ b/ext/pgsql/tests/bug68638.phpt
@@@ -30,18 -30,11 +30,18 @@@ while ($row = pg_fetch_assoc($rs))
var_dump($row);
}
-pg_query($conn, "DROP TABLE $table");
+?>
+--CLEAN--
+<?php
+require_once('inc/config.inc');
+$conn = pg_connect($conn_str);
+$table='test_68638';
+
+pg_query($conn, "DROP TABLE IF EXISTS $table");
?>
--EXPECT--
- string(52) "UPDATE "test_68638" SET "value"=E'inf' WHERE "id"=1;"
+ string(51) "UPDATE "test_68638" SET "value"='inf' WHERE "id"=1;"
array(2) {
["id"]=>
string(1) "1"
diff --cc ext/phar/util.c
index 2c896c6f658,4df7060c1d3..d3bdf3d52a7
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@@ -91,18 -109,8 +112,16 @@@ phar_entry_info *phar_get_link_source(p
return NULL;
}
}
- return entry;
}
- /* }}} */
+static php_stream *phar_get_entrypufp(const phar_entry_info *entry)
+{
+ if (!entry->is_persistent) {
+ return entry->phar->ufp;
+ }
+ return PHAR_G(cached_fp)[entry->phar->phar_pos].ufp;
+}
+
/* retrieve a phar_entry_info's current file pointer for reading contents */
php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */
{