php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72100 implode() inserts garbage into resulting string when joins very big integer
Submitted: 2016-04-25 09:09 UTC Modified: 2016-04-26 07:30 UTC
From: mikhail dot galanin at yahoo dot com Assigned: ab (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.0.5 OS: SLES x86_64
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: mikhail dot galanin at yahoo dot com
New email:
PHP Version: OS:

 

 [2016-04-25 09:09 UTC] mikhail dot galanin at yahoo dot com
Description:
------------
In the implode() implementation, there's an optimisation that operates when input array contains long's. This optimisation relays on the fact that log10(num) returns digit number of string representation of "num". Even though mathematically it is correct there an issue when num consist of more than 14 nines (i.e. 99999999999999999). In this case the log10 is rounded up and actual result gets wrong.



Test script:
---------------
$a = [
        'INSERT IGNORE INTO ',
        'Table',
        (999999999999999999),
        PHP_INT_MIN,
        PHP_INT_MAX
];
$str = implode(' ', $a);
echo json_encode(["str" => $str]);


Expected result:
----------------
{"str":"INSERT IGNORE INTO Table 999999999999999999 -9223372036854775808 9223372036854775807"}


Actual result:
--------------
{"str":"INSERT IGNORE INTO \u0000 Table 999999999999999999 -9223372036854775808 9223372036854775807"}


Patches

implode-log10-bug-fix02 (last revision 2016-04-25 09:12 UTC by mikhail dot galanin at yahoo dot com)
implode-log10-bug-fix01 (last revision 2016-04-25 09:11 UTC by mikhail dot galanin at yahoo dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-25 09:13 UTC] mikhail dot galanin at yahoo dot com
Here is .phpt for the issue:

--TEST--
Test implode() function, problems with big numbers
--SKIPIF--
<?php
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only");
?>
--FILE--
<?php
/* Prototype  : string vsprintf(string $format , array $args)
 * Description: Return a formatted string
 * Source code: ext/standard/formatted_print.c
*/

/* very long number */
var_dump( implode(" ", ["hello long", 999999999999999999, PHP_INT_MAX] ) );

var_dump( implode(" ", ["hello negative long", -999999999999999999, PHP_INT_MIN] ) );

var_dump( implode(" ", ["hello small long", -101, -100, -99, -90, -11, -10, -9, -1, 0, 1, 2, 9, 10, 11, 90, 99, 100, 101] ) );

echo "Done\n";

?>
--EXPECTF--
string(49) "hello long 999999999999999999 9223372036854775807"
string(60) "hello negative long -999999999999999999 -9223372036854775808"
string(76) "hello small long -101 -100 -99 -90 -11 -10 -9 -1 0 1 2 9 10 11 90 99 100 101"
Done
 [2016-04-26 07:26 UTC] pajoye@php.net
It seems to be unrelated to big numbers.

shorter script:


$a1 = ['INSERT IGNORE INTO', 'Table', 999999999999999999, PHP_INT_MIN, PHP_INT_MAX];
$a2 = ['INSERT IGNORE INTO', 'Table', 1, 2, 3];
$str1 = implode(' ', $a1);
$str2 = implode(' ', $a1);
var_dump($str1, $str2);

It keeps the ending \0 for the 1st string,

"INSERT IGNORE INTO<bh:00> Ta" (little literal hexdump).
 [2016-04-26 07:30 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: ab
 [2016-04-26 07:30 UTC] pajoye@php.net
err It is big number related. I was checking two times the same script.

Assigning to Anatol, he knows that area well :)
 [2016-04-26 10:06 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8f0ceb97cff0defa74294c5580e93386897b4933
Log: Fixed bug #72100 (implode() inserts garbage into resulting string when joins very big integer). (Mikhail Galanin)
 [2016-04-26 10:06 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2016-07-20 11:31 UTC] davey@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8f0ceb97cff0defa74294c5580e93386897b4933
Log: Fixed bug #72100 (implode() inserts garbage into resulting string when joins very big integer). (Mikhail Galanin)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC