]> granicus.if.org Git - php/commitdiff
Fixed bug #40503 (json_encode() value corruption on 32bit systems with
authorIlia Alshanetsky <iliaa@php.net>
Sun, 18 Feb 2007 16:54:59 +0000 (16:54 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Sun, 18 Feb 2007 16:54:59 +0000 (16:54 +0000)
overflown values).

NEWS
ext/json/json.c
ext/json/tests/bug40503.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b8ea683eca88be35b785ba41c4ef1d1014d4ddd3..90a8009ce68839d2281fb5913a71b8222cb64337 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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).
index 0f552d4fcd1f9812bdb793f6a79ca90be32b2b49..1bfe3e0743f0f3b2baa3bdef8c34fd75f01b69d4 100644 (file)
@@ -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 (file)
index 0000000..d451eea
--- /dev/null
@@ -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