php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47564 [PATCH] unpacking unsigned long 32bit bit endian returns wrong result
Submitted: 2009-03-04 16:43 UTC Modified: 2009-05-12 12:37 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: laacz at laacz dot lv Assigned:
Status: Closed Package: Strings related
PHP Version: 5.2.9 OS: FreeBSD 6.1-STABLE (amd64)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: laacz at laacz dot lv
New email:
PHP Version: OS:

 

 [2009-03-04 16:43 UTC] laacz at laacz dot lv
Description:
------------
Unpacking unsigned long (32bit; always big endian; "N") on 64bit 
system returns 64bit signed int instead of 32bit.

You can do & 0xffffffff on unpacked value, and get desired result, 
but that's still a bug.

Reproduce code:
---------------
<?php
list(,$command_id) =  unpack('N', chr(0x80) . chr(0x00) . chr(0x00) . chr(0x09));
echo hexdec(dechex($command_id)) . "\n0x" . dechex($command_id) . "\n";
?>



Expected result:
----------------
2147483657
0x80000009





Actual result:
--------------
1.8446744071562E+19
0xffffffff80000009





Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-10 10:46 UTC] vivekanandan8 at yahoo dot com
Hi,
   Generally the Zend engine holds any variable as  zval which holds the integer as long data type only. 

32 bit Platform: long         => 4 byte = 32 bit 
64 bit Platform: long         => 8 byte = 64 bit
64 bit Platform: unsigned int => 4 byte = 32 bit

Hence in the 64 bit platform, we have to convert from long to unsigned int only in 64 bit Platform.
Hence in php source  php5.3-200903301230/ext/standard/pack.c
In PHP_FUNCTION(unpack) place, add this convertion immediate
after  php_unpack function as folows. 

v |= php_unpack(&input[inputpos], 4, issigned, map);
if (sizeof(long) > 4) {	v = (unsigned int) v; }


I tested in both 32 & 64 bit platform ,it works fine , please close this Bug
Regards,
vivekanandan
 [2009-04-10 11:07 UTC] vivekanandan8 at yahoo dot com
Hi,
    Regarding the bug fix, This is tested in Version PHP 5.3 and works fine,for any one needs full source code :   
http://www.gnudeveloper.com/software/php/pack.c

Regards,
vivekanandan.
 [2009-04-14 14:12 UTC] vivekanandan8 at yahoo dot com
Hi,
   for signed long also work properly,please use code below. 

v |= php_unpack(&input[inputpos], 4, issigned, map);
if (sizeof(long) > 4) {
   if( type == 'l' ) {
      v = (signed int) v; 
   }else{ 
       v = (unsigned int) v;
   }
}

Full Source Code: 

http://www.gnudeveloper.com/software/php-5.3/pack.c


Regards,
vivekanandan.
 [2009-05-12 12:37 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC