php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32700 unpack() returns signed values when it shouldn't
Submitted: 2005-04-13 22:49 UTC Modified: 2005-04-14 00:48 UTC
From: ieure@php.net Assigned:
Status: Not a bug Package: Strings related
PHP Version: 4.3.10 OS: Linux
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: ieure@php.net
New email:
PHP Version: OS:

 

 [2005-04-13 22:49 UTC] ieure@php.net
Description:
------------
unpack() returns signed long values when the high bit is  
set, even though the unpack format is set to unsigned long.  
  
Workaround:  
  
$foo = unpack('N', $data);  
$foo = $foo << 1 >> 1;  
$foo += 0x80000000; 
   
   

Reproduce code:
---------------
// High bit is set.
$before = 0x80000002;
echo "Before: $before\n"; // Outputs '2147483650'
$int = pack('N', $before);
$res = unpack('N', $int);
$after = $res[1];
echo "After: $after\n"; // Outputs '-2147483646'


Expected result:
----------------
$before and $after should be the same number. 

Actual result:
--------------
$after is treated as signed, and does not equal $before.  
 
Script output: 
 
Before: 2147483650 
After: -2147483646 
 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-04-13 22:54 UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

PHP only supports signed integers.
 [2005-04-13 22:54 UTC] derick@php.net
try printf("%u") though to print it - that would work...
 [2005-04-13 23:01 UTC] ieure@php.net
While PHP may only support signed integers, the manual for 
pack() clearly states, regarding the 'N' format: 
 
"unsigned long (always 32 bit, big endian byte order)" 
 
But it returns a signed int when using this format, 
contrary to the documentation. 
 
There's obviously some sort of internal PHP state regarding 
the signedness of a particular value, since it's capable of 
correctly representing the unsigned value. It just seems 
that unpack() is doing something wrong here.
 [2005-04-13 23:07 UTC] derick@php.net
Yes, but echo will show the signed representatation. This is *not* a bug, use printf("%u") to show the unsigned version.
 [2005-04-13 23:14 UTC] ieure@php.net
It has nothing do with "echo showing the signed version." 
If that were the case, it would output the same (negative) 
number when you echo $before as well. 
 
It's PHP /using/ the signed version. For example:    
    
$test[$before] = 'It works!';    
if (isset($test[$after])) {    
    echo "It works!\n";   
} else {   
    echo "It doesn't work!\n";  
}  
  
$before and $after are /not/ the same value to PHP. Nothing 
to do with echo.
 [2005-04-13 23:58 UTC] sniper@php.net
RTFM.. (for pack() function)

 [2005-04-13 23:59 UTC] derick@php.net
And it's still not a bug.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 12:01:29 2024 UTC