php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64695 JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e
Submitted: 2013-04-23 04:15 UTC Modified: 2016-01-27 18:48 UTC
Votes:26
Avg. Score:4.7 ± 0.7
Reproduced:25 of 25 (100.0%)
Same Version:4 (16.0%)
Same OS:4 (16.0%)
From: keith at openx dot com Assigned: bukka (profile)
Status: Closed Package: JSON related
PHP Version: 5.3.24 OS: CentOS/OSX
Private report: No CVE-ID: None
 [2013-04-23 04:15 UTC] keith at openx dot com
Description:
------------
So, it looks like that when you call json_encode with the JSON_NUMERIC_CHECK 
option on strings that have all numbers except for one letter 'e' PHP throws a 
warning:

PHP Warning:  json_encode(): double INF does not conform to the JSON spec, 
encoded as 0 in php shell code on line 1

It happens only on certain strings that make PHP think the number is very large. 
According to the docs the 'e' should be followed with +/-, but it seems that 
isn't the case. 

This causes a problem whenever converting values that are, say, hashed with SHA1. 
Since the valid characters are [0-9][A-F], it's very possible to have a value 
that is: [0-9]e[0-9] 

Test script:
---------------
<?php

$t = array('test' => '123343e871700');
var_dump(json_encode($t, JSON_NUMERIC_CHECK));

Expected result:
----------------
string(10) "{"test":"123343e871700"}"

Actual result:
--------------
PHP Warning:  json_encode(): double INF does not conform to the JSON spec, 
encoded as 0 in php shell code on line 1
string(10) "{"test":0}"

Patches

return_string_instead_of_warning (last revision 2013-04-23 06:27 UTC by keith at openx dot com)
is_numeric_patch (last revision 2013-04-23 04:16 UTC by keith at openx dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-04-23 04:28 UTC] keith at openx dot com
So, I noticed on the is_numeric page that:

"Thus +0123.45e6 is a valid numeric value."

But can that be explained as to why that this? It breaks json_encode when 
JSON_NUMERIC_CHECK is called in certain situations. The function 
'is_numeric_string' returns the type 'double' for strings like "3e122345", and 
that isn't a double. 

My patch updated 'is_numeric_string' which might be too agressive. Maybe updating  
json.c is a better alternative.
 [2013-04-23 06:07 UTC] keith at openx dot com
So the new patch just updates json.c. Instead of throwing the warning and setting 
the value to 0, it makes the value a string. That way json_encode doesn't change 
a value that it possibly shouldn't.

Valid exponential notation values are converted.

php > $t = array('test' => '123343e871700');
php > var_dump(json_encode($t, JSON_NUMERIC_CHECK));
string(24) "{"test":"123343e871700"}"
php > $t = array('test' => '123343e1');
php > var_dump(json_encode($t, JSON_NUMERIC_CHECK));
string(16) "{"test":1233430}"
php > $t = array('test' => '1.03e-3');
php > var_dump(json_encode($t, JSON_NUMERIC_CHECK));
string(16) "{"test":0.00103}"
 [2014-04-11 14:49 UTC] afischoff at salesforce dot com
The same is true for number with leading zeros such as valid zip codes, like: 01001

json_encode with JSON_NUMERIC_CHECK will return integer: 1001
 [2014-10-28 02:18 UTC] rangi dot biddle at agfirstbop dot co dot nz
issue also appears for PHP 5.5.9-1ubuntu4.4
 [2015-01-21 03:51 UTC] anzhengchao at gmail dot com
issue also appears for PHP 5.6.4 (cli) (built: Jan  8 2015 09:41:21) OSX
 [2015-01-21 04:20 UTC] laruence@php.net
-Assigned To: +Assigned To: bukka
 [2015-01-21 04:20 UTC] laruence@php.net
is this possible to be fixed in jsond?
 [2015-01-21 20:41 UTC] bukka@php.net
It looks like a bug to me.

I comitted a fix to jsond: https://github.com/bukka/php-jsond/commit/37503cdff35733d580f289047f516a5df2e01813

I would like to wait after the jsond rfc vote and then possibly merge it to the core if no objections.
 [2015-02-22 20:23 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=591dbcabe57a32550fb73223521fa1323773628f
Log: Fix bug #64695 (JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e)
 [2015-02-22 20:23 UTC] bukka@php.net
-Status: Assigned +Status: Closed
 [2015-02-22 20:35 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=591dbcabe57a32550fb73223521fa1323773628f
Log: Fix bug #64695 (JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e)
 [2015-02-22 20:55 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=591dbcabe57a32550fb73223521fa1323773628f
Log: Fix bug #64695 (JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e)
 [2015-02-22 20:58 UTC] bukka@php.net
It's been fixed in 5.5, 5.6 and master
 [2016-01-13 03:01 UTC] mark dot caudill at sharpspring dot com
It appears that this never made its way to GitHub. That means it's not actually in most versions of PHP (including the one on php.net). I seem to be hitting this pretty extensively right now and I had assumed it was in 5.5.12.

Is it possible this happened for other bug fixes as well?

See the difference between:
http://git.php.net/?p=php-src.git;a=blob;f=NEWS;h=ee0e9869bd2d1acc02066564513efb6a39edd533;hb=refs/heads/PHP-5.5

and this file:
https://github.com/php/php-src/blob/a5864d9917357f4e68e4edb481ca7e3e71826ba7/NEWS#L1657

And the test for this made it in somehow:
https://github.com/php/php-src/blob/250938e2d35fc54161a18167b7901c5e3b574371/ext/json/tests/bug64695.phpt

http://php.net/ChangeLog-5.php

It looks like this fix also made it into PHP 7 successfully somehow in the transition.
 [2016-01-13 15:57 UTC] bukka@php.net
It made it to 5.5 and up. It is in this commit

https://github.com/php/php-src/commit/591dbcabe57a32550fb73223521fa1323773628f

you can also see it in the 5.5 news file - search for JSON_NUMERIC_CHECK

https://github.com/php/php-src/blob/PHP-5.5/NEWS

The reason why you are hitting it is that many distros are bundled with json-c due to a licensing issue. I am not sure if jsonc has this fixed thought but there is no issue with this core json ext.
 [2016-01-14 14:15 UTC] mark dot caudill at sharpspring dot com
Alright - thank you for the clarification. Is there any concern about it not being in the changelog on php.net?
 [2016-01-26 18:50 UTC] bukka@php.net
It is in the NEWS (changelog) for 5.5 as I linked:

https://github.com/php/php-src/blob/PHP-5.5/NEWS

So there is no issue...
 [2016-01-26 20:24 UTC] mark dot caudill at sharpspring dot com
Totally understand and I comprehended that the first time. I was saying that it isn't here at all and asking if that is something to care about: http://php.net/ChangeLog-5.php
 [2016-01-27 18:48 UTC] bukka@php.net
Ah I see. Good catch! That's definitely my fault and I'm sorry for that! I have no idea why I put it to the 5.5.12 because it should go to 5.5.23 which means it didn't go to ChangeLog.

I will email Julien (5.5 RM) and ask him if it can be fixed. Thanks!
 [2016-04-13 09:20 UTC] cearny at gmail dot com
I think this just reared it's ugly head again in 5.6.20 (it works fine in 5.6.18 and 7.0.x). PHP 5.6.20-1+deb.sury.org~trusty+1, to be more exact.

It complains that Inf and NaN can't be represented in JSON, because it thinks we're dealing with a hex number I guess?

<?php

echo json_encode(["rss" => "5e879769"]);
echo "\n";
echo json_last_error();
echo "\n";
echo "\n";
echo json_encode(["rss" => "5e879769"], JSON_NUMERIC_CHECK);
echo "\n";
echo json_last_error();
echo "\n";
echo "\n";
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Nov 16 22:01:35 2019 UTC