diff options
| -rw-r--r-- | NEWS | 2 | ||||
| -rw-r--r-- | ext/json/json.c | 20 | ||||
| -rw-r--r-- | ext/json/tests/bug40503.phpt | 19 |
3 files changed, 32 insertions, 9 deletions
@@ -6,6 +6,8 @@ PHP NEWS - Add --ri switch to CLI which allows to check extension information. (Marcus) - Added tidyNode::getParent() method (John, Nuno) - Fixed zend_llist_remove_tail (Michael Wallner, Dmitry) +- Fixed bug #40503 (json_encode() value corruption on 32bit systems with + overflown values). (Ilia) - Fixed bug #40467 (Partial SOAP request sent when XSD sequence or choice include minOccurs=0). (Dmitry) - Fixed bug #40465 (Ensure that all PHP elements are printed by var_dump). diff --git a/ext/json/json.c b/ext/json/json.c index 0f552d4fcd..1bfe3e0743 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -345,7 +345,7 @@ static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC) { } break; case IS_LONG: - smart_str_append_long(buf, Z_LVAL_P(val)); + smart_str_append_long(buf, Z_LVAL_P(val)); break; case IS_DOUBLE: { @@ -353,14 +353,16 @@ static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC) { int len; double dbl = Z_DVAL_P(val); - if (!zend_isinf(dbl) && !zend_isnan(dbl)) - { - len = spprintf(&d, 0, "%.9g", dbl); - if (d) - { - smart_str_appendl(buf, d, len); - efree(d); - } + if (!zend_isinf(dbl) && !zend_isnan(dbl)) { + len = spprintf(&d, 0, "%.9g", dbl); + if (d) { + if (dbl > LONG_MAX && !memchr(d, '.', len)) { + smart_str_append_unsigned(buf, (unsigned long)Z_DVAL_P(val)); + } else { + smart_str_appendl(buf, d, len); + } + efree(d); + } } else { diff --git a/ext/json/tests/bug40503.phpt b/ext/json/tests/bug40503.phpt new file mode 100644 index 0000000000..d451eea35d --- /dev/null +++ b/ext/json/tests/bug40503.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #40503 (json_encode() value corruption on 32bit systems with overflown values) +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php +function show_eq($x,$y) { + echo "$x ". ($x==$y ? "==" : "!=") ." $y\n"; +} + +$value = 0x7FFFFFFF; #2147483647; +show_eq("$value", json_encode($value)); +$value++; +show_eq("$value", json_encode($value)); + +?> +--EXPECT-- +2147483647 == 2147483647 +2147483648 == 2147483648 |
