summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/pack.c6
-rw-r--r--ext/standard/tests/strings/bug38770.phpt6
-rw-r--r--ext/standard/tests/strings/bug61764.phpt15
3 files changed, 18 insertions, 9 deletions
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 3cd6ee7c50..a21d41bda7 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -815,16 +815,14 @@ PHP_FUNCTION(unpack)
case 'i':
case 'I': {
- long v = 0;
+ long v;
int issigned = 0;
if (type == 'i') {
issigned = input[inputpos + (machine_little_endian ? (sizeof(int) - 1) : 0)] & 0x80;
- } else if (sizeof(long) > 4 && (input[inputpos + machine_endian_long_map[3]] & 0x80) == 0x80) {
- v = ~INT_MAX;
}
- v |= php_unpack(&input[inputpos], sizeof(int), issigned, int_map);
+ v = php_unpack(&input[inputpos], sizeof(int), issigned, int_map);
add_assoc_long(return_value, n, v);
break;
}
diff --git a/ext/standard/tests/strings/bug38770.phpt b/ext/standard/tests/strings/bug38770.phpt
index 417794cd25..1821639aca 100644
--- a/ext/standard/tests/strings/bug38770.phpt
+++ b/ext/standard/tests/strings/bug38770.phpt
@@ -7,7 +7,7 @@ if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only");
--FILE--
<?php
-foreach (array('N','I','l') as $v) {
+foreach (array('N','l') as $v) {
print_r(unpack($v, pack($v, -30000)));
}
@@ -22,8 +22,4 @@ Array
(
[1] => -30000
)
-Array
-(
- [1] => -30000
-)
Done
diff --git a/ext/standard/tests/strings/bug61764.phpt b/ext/standard/tests/strings/bug61764.phpt
new file mode 100644
index 0000000000..dc44f25b3f
--- /dev/null
+++ b/ext/standard/tests/strings/bug61764.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #61764: 'I' unpacks n as signed if n > 2^31-1 on LP64
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only");
+--FILE--
+<?php
+//expected -30000 mod 2^32 = 4294937296, and not -30000
+//because we can represent 4294937296 with our PHP int type
+print_r(unpack('I', pack('L', -30000)));
+--EXPECT--
+Array
+(
+ [1] => 4294937296
+)