Commit:    8d748e5de519867d9b6ce40e3ea28a209b07768f
Author:    Gustavo André dos Santos Lopes <cataphr...@php.net>         Mon, 23 
Apr 2012 22:09:38 +0100
Parents:   c8865e3b84c9a3d08811b3b8f954defcd8fb621d
Branches:  PHP-5.3 PHP-5.4 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=8d748e5de519867d9b6ce40e3ea28a209b07768f

Log:
Fixed bug #61764: 'I' unpacks n as signed if n > 2^31-1 on LP64

Also fixed possible invalid read on big endian LP64.

Bugs:
https://bugs.php.net/61764

Changed paths:
  M  NEWS
  M  ext/standard/pack.c
  M  ext/standard/tests/strings/bug38770.phpt
  A  ext/standard/tests/strings/bug61764.phpt


Diff:
diff --git a/NEWS b/NEWS
index a483909..b8193c9 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ PHP                                                             
           NEWS
 ?? ??? 2012, PHP 5.3.12
 
 - Core:
+  . Fixed bug #61764 ('I' unpacks n as signed if n > 2^31-1 on LP64). (Gustavo)
   . Fixed bug #54197 ([PATH=] sections incompatibility with user_ini.filename
    set to null). (Anatoliy)
 
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 5ad1ecf..5d3c8a8 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -759,16 +759,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 417794c..1821639 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 0000000..dc44f25
--- /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
+)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to