php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42510 unpack('V') sign-extends result on x86-64
Submitted: 2007-09-01 17:22 UTC Modified: 2008-11-10 01:00 UTC
Votes:3
Avg. Score:4.0 ± 0.8
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: jr-php2 at quo dot to Assigned: iliaa (profile)
Status: No Feedback Package: Strings related
PHP Version: 5.2.4 OS: Linux x86-64
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: jr-php2 at quo dot to
New email:
PHP Version: OS:

 

 [2007-09-01 17:22 UTC] jr-php2 at quo dot to
Description:
------------
On x86-64, unpack('V') sign-extends from 32-bit to 64-bit. In other words, it can return a negative number.
Since 'V' specifies an *unsigned* 32-bit value, this is incorrect; the upper 32 bits of the 64-bit result should always be zero.

This behavior makes unpack() inconsistent with other functions like ip2long() and crc32() which never return negative numbers on 64-bit PHP.

Reproduce code:
---------------
$u = unpack('Vresult', chr(200).chr(200).chr(200).chr(200));
echo "unpack = ", $u['result'], "\n";
echo "ip2long = ", ip2long('200.200.200.200'), "\n";

Expected result:
----------------
unpack = -926365496
ip2long = 3368601800

Actual result:
--------------
unpack = 3368601800
ip2long = 3368601800

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-09-01 17:26 UTC] jr-php2 at quo dot to
Sorry, I mixed up the expected and actual results.

It should say:

Expected result:
----------------
unpack = 3368601800
ip2long = 3368601800

Actual result:
--------------
unpack = -926365496
ip2long = 3368601800
 [2007-09-01 20:33 UTC] jr-php2 at quo dot to
Okay, looking at the unpack() code, it appears that:

- 'l' and 'L' are both treated as signed, even though 'l' is documented as signed and 'L' is documented as unsigned.

- 'N' and 'V' are treated as signed, even though both are documented as unsigned.

So who's right here, the code or the documentation?
 [2007-09-02 20:06 UTC] jr-php2 at quo dot to
Digging deeper, it looks like 'V' and 'N' used to work as documented until bug #38770 was "fixed in CVS".

Isn't #38770 a bogus report, though? Since 'N' is documented as being unsigned, isn't the user wrong to expect it to return a negative result?
 [2007-09-03 08:14 UTC] jani@php.net
Are you actually using PHP 5.2.4? (the bug you claim to be bogus was fixed already in 5.2.1..why didn't you report it earlier?!)
 [2007-09-03 16:39 UTC] jr-php2 at quo dot to
> Are you actually using PHP 5.2.4?

Yes.

> (the bug you claim to be bogus was fixed already in 5.2.1..

Maybe I wasn't clear: I'm suggesting that the bug report *and* the fix that went into 5.2.1 are bogus.

Result with PHP 5.2.0 (matches my "expected result"):

unpack = 3368601800
ip2long = 3368601800

Result with PHP 5.2.1-5.2.4:

unpack = -926365496
ip2long = 3368601800

> why didn't you report it earlier?!)

I didn't notice the problem until now.
 [2007-09-04 10:43 UTC] jani@php.net
Assigned to Ilia who fixed bug #38770


 [2008-01-23 00:19 UTC] shodan at shodan dot ru
This bug also happens with unpack("N") with PHP versions 5.2.2 to 5.2.5 on x64 systems:

[shodan@pulsar tmp]$ cat 1.php
<?php

$s = "\x8a\x4a\xef\x23";
list(,$i) = unpack ( "N*", $s );
var_dump($i);

?>
[shodan@pulsar tmp]$ ~/bin/php525 1.php
int(-1974800605)

Note that it did not happen on 5.1.x series:

[shodan@pulsar tmp]$ php 1.php
int(2320166691)
[shodan@pulsar tmp]$ php --version
PHP 5.1.6 (cli) (built: Jun 17 2007 11:37:40)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
[shodan@pulsar tmp]$
 [2008-11-02 13:00 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2008-11-10 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 13 04:01:26 2024 UTC