From 524ce9041862159ed1bbaf29d387782c6f8d534c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 7 Jan 2022 15:04:36 +0100 Subject: [PATCH] fix GH-7899 Regression in unpack for negative int value --- NEWS | 3 +++ ext/standard/pack.c | 11 +++++++++-- ext/standard/tests/strings/pack64.phpt | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 812b1005ccb..cbcabd058ac 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS - pcntl: . Fixed pcntl_rfork build for DragonFlyBSD. (David Carlier) +- Standard: + . Fixed bug GH-7899 (Regression in unpack for negative int value). (Remi) + 06 Jan 2022, PHP 8.1.2RC1 - Core: diff --git a/ext/standard/pack.c b/ext/standard/pack.c index 46856874bc2..8736d291fb2 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -62,6 +62,7 @@ typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t); typedef ZEND_SET_ALIGNED(1, uint32_t unaligned_uint32_t); typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t); typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint); +typedef ZEND_SET_ALIGNED(1, int unaligned_int); /* Mapping of byte from char (8bit) to long for machine endian */ static int byte_map[1]; @@ -1043,8 +1044,14 @@ PHP_FUNCTION(unpack) case 'i': /* signed integer, machine size, machine endian */ case 'I': { /* unsigned integer, machine size, machine endian */ - unsigned int x = *((unaligned_uint*) &input[inputpos]); - zend_long v = (type == 'i') ? (int) x : x; + zend_long v; + if (type == 'i') { + int x = *((unaligned_int*) &input[inputpos]); + v = x; + } else { + unsigned int x = *((unaligned_uint*) &input[inputpos]); + v = x; + } ZVAL_LONG(&val, v); zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val); diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt index 753821f6542..84e69008284 100644 --- a/ext/standard/tests/strings/pack64.phpt +++ b/ext/standard/tests/strings/pack64.phpt @@ -31,6 +31,11 @@ print_r(unpack("q", pack("q", 0))); print_r(unpack("q", pack("q", 0x8000000000000002))); print_r(unpack("q", pack("q", -1))); print_r(unpack("q", pack("q", 0x8000000000000000))); + +print_r(unpack("i", pack("i", 2147483647))); // Max int32 +print_r(unpack("i", pack("i", -2147483647))); +print_r(unpack("i", pack("i", -2147483648))); // Min int32 +print_r(unpack("I", pack("I", 4294967295))); // Max uint32 ?> --EXPECT-- Array @@ -113,3 +118,19 @@ Array ( [1] => -9223372036854775808 ) +Array +( + [1] => 2147483647 +) +Array +( + [1] => -2147483647 +) +Array +( + [1] => -2147483648 +) +Array +( + [1] => 4294967295 +)