php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #74417 long2ip() is documented to accept a string, but TypeError thrown with strings
Submitted: 2017-04-11 16:20 UTC Modified: 2017-08-22 21:28 UTC
Votes:3
Avg. Score:3.0 ± 1.6
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: vedad at kajtaz dot net Assigned: cmb (profile)
Status: Closed Package: Documentation problem
PHP Version: 7.1.3 OS: FreeBSD 11.0
Private report: No CVE-ID: None
 [2017-04-11 16:20 UTC] vedad at kajtaz dot net
Description:
------------
The long2ip() signature in documentation is:

string long2ip ( string $proper_address )

Yet, as of PHP 7.1 (unlike PHP 7.0) TypeError is thrown with strict_types=1 when a string is provided:

PHP Fatal error:  Uncaught TypeError: long2ip() expects parameter 1 to be integer, string given in ...

Related bug reports: #65017 and #71100

Test script:
---------------
declare(strict_types=1);
long2ip('2130706433');

Actual result:
--------------
PHP Fatal error:  Uncaught TypeError: long2ip() expects parameter 1 to be integer, string given in ...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-04-20 14:32 UTC] indan at nul dot nu
Same problem with a 32-bit version of PHP 7.1.4 on Windows.
The 64-bit version of PHP 7.1.4 on Linux does not have this problem, so maybe it is only a bug in the 32-bit version of PHP.

Probably introduced by commit:

http://git.php.net/?p=php-src.git;a=commit;h=9b148d31d3e19ce8c726ebbab3ba6a9a24979a2f

As far as I know, I don't have strict types enabled.
 [2017-04-21 08:18 UTC] indan at nul dot nu
The problem is that IP addresses in the high range (e.g. "192.168.0.1") result in a positive number which does not fit in an INT32_MAX. I don't see how this can be solved without added unsigned support to PHP, so I think the commit changing the argument from a string to an integer should be reverted.

Test code:

<?php
declare(strict_types=0);
error_reporting(E_ALL);

$n = (int)"3232242954"; // Will be truncated to INT32_MAX

echo "192.168.29.10 = " . gettype($n) . " = $n\n";
echo "Test 1: '" . long2ip($n) . "'\n";
echo "Test 2: '" . long2ip("3232242954") . "'\n";
echo "Test 3: '" . long2ip("173632452") . "'\n";

/*

Result:

192.168.29.10 = integer = 2147483647
Test 1: '127.255.255.255'
PHP Warning:  long2ip() expects parameter 1 to be integer, string given in t.php on line 7

Warning: long2ip() expects parameter 1 to be integer, string given in t.php on line 7
Test 2: ''
Test 3: '10.89.107.196'

*/
 [2017-04-21 14:57 UTC] vedad at kajtaz dot net
Note that the original bug report is based on a 64bit FreeBSD build.
 [2017-04-24 08:43 UTC] indan at nul dot nu
They changed the signature of long2ip(), but didn't update the documentation. This applies to all platforms.

The original bug report proposes to fix the documentation to match the implementation.

I propose to revert the change and keep the documentation as it is, because the change breaks old code on 32-bit PHP. However confusing the function name is, it always has been like this.

If the change is not reverted, please also update the migration guide and add this backward incompatible change to the list. Work around for 32-bit PHP code:

function string2ip($s)
{
	if ($s > PHP_INT_MAX)
		$s = 2 * PHP_INT_MIN + $s;
	return long2ip($s);
}
 [2017-08-12 01:57 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2017-08-12 01:57 UTC] laruence@php.net
I don't have 32bit env , just one question

what does ip2long behavior in this case?

ie: var_dump(ip2long("192.168.0.1"));
 [2017-08-12 02:10 UTC] ajf@php.net
This can be worked around:

$ sapi/cli/php -r "declare(strict_types=1); var_dump(long2ip((int)'2130706433'));"
string(9) "127.0.0.1"
 [2017-08-12 02:39 UTC] laruence@php.net
I got one 32bit box, and :

var_dump(ip2long("192.168.29.10"));

output:

int(-1062724342)

and :

var_dump(long2ip((-1062724342)));

output the correct value..

so in my opinion I don't think we should revert the fix here.
 [2017-08-15 09:48 UTC] indan at nul dot nu
To answer ajf:

You have to use signed numbers greater than 2^31:

php -r "declare(strict_types=1); var_dump(long2ip((int)'3232242954'));"
string(15) "127.255.255.255"

Instead of "192.168.29.10". So no, it can't be worked around.

To laruence:

If you don't revert the prototype change from string to int, 32-bit PHP's long2ip() will choke on signed 32-bit IP addresses in the high range. This means long2ip() is not compatible between 64 and 32 bit PHP. It's your choice and I'm fine with whatever you decide. However, at least update all PHP documentation, including the migration guide. This is a backward incompatible change breaking existing code which currently works fine with PHP 7.0 or earlier.

Anything that puts IP addresses into a database as unsigned numbers will hit this problem on 32 bit. But only one left using 32 bit are Windows virtual machines, so I understand if PHP doesn't care about 32 bit anymore.
 [2017-08-22 17:02 UTC] cmb@php.net
-Assigned To: laruence +Assigned To: cmb
 [2017-08-22 17:02 UTC] cmb@php.net
> So no, it can't be worked around.

Well, actually it can (albeit in a hackish way):

  php -r "declare(strict_types=1); var_dump(long2ip((int)(float)'3232242954'));"
 [2017-08-22 21:28 UTC] cmb@php.net
Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=342916
Log: Fix #74417: long2ip() is documented to accept a string
 [2017-08-22 21:28 UTC] cmb@php.net
-Status: Assigned +Status: Closed
 [2017-08-22 21:28 UTC] cmb@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.
 [2020-02-07 06:06 UTC] phpdocbot@php.net
Automatic comment on behalf of cmb
Revision: http://git.php.net/?p=doc/en.git;a=commit;h=db0432561cac9bdb78e192552c34cae99b2bd787
Log: Fix #74417: long2ip() is documented to accept a string
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 05:01:30 2024 UTC