Commit 1854a426fce for php.net
commit 1854a426fce08a490ba4849cf5c6d72eeceb378d
Author: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com>
Date: Tue Aug 25 12:17:18 2026 +0200
UPGRADING: document the unpack() element name BC break (#23446)
diff --git a/UPGRADING b/UPGRADING
index cecec6dbe8d..4a5d055a57c 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -289,6 +289,13 @@ PHP 8.6 UPGRADE NOTES
- file_exists()
- lstat()
- stat()
+ . unpack() now reads a "<" or ">" immediately following a format code as an
+ endianness modifier rather than as the first character of the element name.
+ Formats such as "s<value" now produce the key "value" instead of "<value",
+ and "C>name" raises a ValueError because the C format code accepts no
+ endianness modifier. A name starting with these characters is unaffected
+ when a repeater precedes it, as in "s1<value".
+ RFC: https://wiki.php.net/rfc/pack-unpack-endianness-signed-integers-support
- Sysvshm:
. shm_attach() now raises a ValueError when the $key argument is outside the
diff --git a/ext/standard/tests/strings/unpack_endian_modifier_names.phpt b/ext/standard/tests/strings/unpack_endian_modifier_names.phpt
new file mode 100644
index 00000000000..46ee1a2f145
--- /dev/null
+++ b/ext/standard/tests/strings/unpack_endian_modifier_names.phpt
@@ -0,0 +1,51 @@
+--TEST--
+unpack() endianness modifiers and element names
+--FILE--
+<?php
+
+var_dump(unpack("s<value", "\x02\x01"));
+var_dump(unpack("s>value", "\x01\x02"));
+
+var_dump(unpack("s<2name", "\x02\x01\x04\x03"));
+var_dump(unpack("s<*name", "\x02\x01\x04\x03"));
+
+var_dump(unpack("v1<value", "\x02\x01"));
+var_dump(unpack("n2>name", "\x01\x02\x03\x04"));
+var_dump(unpack("C1>name", "\x01"));
+
+?>
+--EXPECT--
+array(1) {
+ ["value"]=>
+ int(258)
+}
+array(1) {
+ ["value"]=>
+ int(258)
+}
+array(2) {
+ ["name1"]=>
+ int(258)
+ ["name2"]=>
+ int(772)
+}
+array(2) {
+ ["name1"]=>
+ int(258)
+ ["name2"]=>
+ int(772)
+}
+array(1) {
+ ["<value"]=>
+ int(258)
+}
+array(2) {
+ [">name1"]=>
+ int(258)
+ [">name2"]=>
+ int(772)
+}
+array(1) {
+ [">name"]=>
+ int(1)
+}
diff --git a/ext/standard/tests/strings/unpack_endian_modifier_names_error.phpt b/ext/standard/tests/strings/unpack_endian_modifier_names_error.phpt
new file mode 100644
index 00000000000..e5f872735c1
--- /dev/null
+++ b/ext/standard/tests/strings/unpack_endian_modifier_names_error.phpt
@@ -0,0 +1,20 @@
+--TEST--
+unpack() element names starting with an endianness modifier on a format code that rejects it
+--FILE--
+<?php
+
+foreach (["C>name", "@>name", "n<name", "V>name"] as $fmt) {
+ try {
+ unpack($fmt, "\x01\x02\x03\x04\x05\x06\x07\x08");
+ echo "FAIL: Expected ValueError for unpack('$fmt', ...)\n";
+ } catch (ValueError $e) {
+ echo "unpack('$fmt'): " . $e->getMessage() . "\n";
+ }
+}
+
+?>
+--EXPECT--
+unpack('C>name'): Endianness modifier is not supported for format code 'C'
+unpack('@>name'): Endianness modifier is not supported for format code '@'
+unpack('n<name'): Endianness modifier '<' cannot be applied to format code 'n' which already has inherent endianness
+unpack('V>name'): Endianness modifier '>' cannot be applied to format code 'V' which already has inherent endianness