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
Have you experienced this issue?
Rate the importance of this bug to you:

 [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

Add a Patch

Pull Requests

Add a Pull Request

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: Thu Apr 25 13:01:30 2024 UTC