mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Alter php_json_decode_ex() to respect JSON_BIGINT_AS_STRING for bare numbers.
Fixes bug #63737 (json_decode does not properly decode with options parameter).
This commit is contained in:
parent
95fd52ff3d
commit
2d1694d4eb
3 changed files with 64 additions and 3 deletions
4
NEWS
4
NEWS
|
@ -2,6 +2,10 @@ PHP NEWS
|
||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
?? ??? 2012, PHP 5.4.11
|
?? ??? 2012, PHP 5.4.11
|
||||||
|
|
||||||
|
- JSON:
|
||||||
|
. Fixed bug #63737 (json_decode does not properly decode with options
|
||||||
|
parameter). (Adam)
|
||||||
|
|
||||||
?? ??? 2012, PHP 5.4.10
|
?? ??? 2012, PHP 5.4.10
|
||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
|
|
|
@ -682,7 +682,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
int type;
|
int type, overflow_info;
|
||||||
long p;
|
long p;
|
||||||
|
|
||||||
RETVAL_NULL();
|
RETVAL_NULL();
|
||||||
|
@ -698,11 +698,36 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
|
||||||
RETVAL_BOOL(0);
|
RETVAL_BOOL(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type = is_numeric_string(str, str_len, &p, &d, 0)) != 0) {
|
if ((type = is_numeric_string_ex(str, str_len, &p, &d, 0, &overflow_info)) != 0) {
|
||||||
if (type == IS_LONG) {
|
if (type == IS_LONG) {
|
||||||
RETVAL_LONG(p);
|
RETVAL_LONG(p);
|
||||||
} else if (type == IS_DOUBLE) {
|
} else if (type == IS_DOUBLE) {
|
||||||
|
if (options & PHP_JSON_BIGINT_AS_STRING && overflow_info) {
|
||||||
|
/* Within an object or array, a numeric literal is assumed
|
||||||
|
* to be an integer if and only if it's entirely made up of
|
||||||
|
* digits (exponent notation will result in the number
|
||||||
|
* being treated as a double). We'll match that behaviour
|
||||||
|
* here. */
|
||||||
|
int i;
|
||||||
|
zend_bool is_float = 0;
|
||||||
|
|
||||||
|
for (i = (str[0] == '-' ? 1 : 0); i < str_len; i++) {
|
||||||
|
/* Not using isdigit() because it's locale specific,
|
||||||
|
* but we expect JSON input to always be UTF-8. */
|
||||||
|
if (str[i] < '0' || str[i] > '9') {
|
||||||
|
is_float = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_float) {
|
||||||
RETVAL_DOUBLE(d);
|
RETVAL_DOUBLE(d);
|
||||||
|
} else {
|
||||||
|
RETVAL_STRINGL(str, str_len, 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RETVAL_DOUBLE(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
ext/json/tests/bug63737.phpt
Normal file
32
ext/json/tests/bug63737.phpt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #63737 (json_decode does not properly decode with options parameter)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if (!extension_loaded("json")) print "skip"; ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function decode($json) {
|
||||||
|
$x = json_decode($json);
|
||||||
|
var_dump($x);
|
||||||
|
$x = json_decode($json, false, 512, JSON_BIGINT_AS_STRING);
|
||||||
|
var_dump($x);
|
||||||
|
}
|
||||||
|
|
||||||
|
decode('123456789012345678901234567890');
|
||||||
|
decode('-123456789012345678901234567890');
|
||||||
|
|
||||||
|
// This shouldn't affect floats, but let's check that.
|
||||||
|
decode('123456789012345678901234567890.1');
|
||||||
|
decode('-123456789012345678901234567890.1');
|
||||||
|
|
||||||
|
echo "Done\n";
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
float(1.2345678901235E+29)
|
||||||
|
string(30) "123456789012345678901234567890"
|
||||||
|
float(-1.2345678901235E+29)
|
||||||
|
string(31) "-123456789012345678901234567890"
|
||||||
|
float(1.2345678901235E+29)
|
||||||
|
float(1.2345678901235E+29)
|
||||||
|
float(-1.2345678901235E+29)
|
||||||
|
float(-1.2345678901235E+29)
|
||||||
|
Done
|
Loading…
Add table
Add a link
Reference in a new issue