]> granicus.if.org Git - php/commitdiff
MFH: add recursion protection to json_encode() and new tests
authorAntony Dovgal <tony2001@php.net>
Thu, 20 Jul 2006 08:56:57 +0000 (08:56 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 20 Jul 2006 08:56:57 +0000 (08:56 +0000)
ext/json/json.c
ext/json/tests/001.phpt
ext/json/tests/002.phpt [new file with mode: 0644]
ext/json/tests/003.phpt [new file with mode: 0644]
ext/json/tests/004.phpt [new file with mode: 0644]
ext/json/tests/005.phpt [new file with mode: 0644]

index 0df5017e44c995c38dc1744b5724a6422da8427c..99e80fa913de6383af90ad5adaf986512e1568c1 100644 (file)
@@ -135,6 +135,11 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) {
         r = 1;
     }
 
+    if (myht && myht->nApplyCount > 1) {
+        php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "recursion detected");
+        return;
+    }
+
     if (r == 0)
     {
         smart_str_appendc(buf, '[');
@@ -151,6 +156,7 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) {
         ulong index;
         uint key_len;
         HashPosition pos;
+        HashTable *tmp_ht;
         int need_comma = 0;
 
         zend_hash_internal_pointer_reset_ex(myht, &pos);
@@ -160,6 +166,11 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) {
                 break;
 
             if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) {
+                tmp_ht = HASH_OF(*data);
+                if (tmp_ht) {
+                    tmp_ht->nApplyCount++;
+                }
+
                 if (r == 0) {
                     if (need_comma) {
                         smart_str_appendc(buf, ',');
@@ -200,6 +211,10 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) {
                         json_encode_r(buf, *data TSRMLS_CC);
                     }
                 }
+
+                if (tmp_ht) {
+                    tmp_ht->nApplyCount--;
+                }
             }
         }
     }
index 89a9528d9aa525091c1aafc64810af79d05639cb..095aedf631965773c9d1700b363ae6b669fa40a4 100644 (file)
@@ -1,5 +1,7 @@
 --TEST--
 json_decode() tests
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
 --FILE--
 <?php
 
diff --git a/ext/json/tests/002.phpt b/ext/json/tests/002.phpt
new file mode 100644 (file)
index 0000000..5bc29bc
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+json_encode() tests
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+var_dump(json_encode(""));
+var_dump(json_encode(NULL));
+var_dump(json_encode(TRUE));
+var_dump(json_encode(array(""=>"")));
+var_dump(json_encode(array(array(1))));
+
+var_dump(json_encode(1));
+var_dump(json_encode("руссиш"));
+
+
+echo "Done\n";
+?>
+--EXPECTF--    
+string(2) """"
+string(4) "null"
+string(4) "true"
+string(2) "{}"
+string(5) "[[1]]"
+string(1) "1"
+string(38) ""\u0440\u0443\u0441\u0441\u0438\u0448""
+Done
diff --git a/ext/json/tests/003.phpt b/ext/json/tests/003.phpt
new file mode 100644 (file)
index 0000000..bb5619d
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+json_encode() & endless loop - 1
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$a = array();
+$a[] = &$a;
+
+var_dump($a);
+var_dump(json_encode($a));
+
+echo "Done\n";
+?>
+--EXPECTF--    
+array(1) {
+  [0]=>
+  &array(1) {
+    [0]=>
+    &array(1) {
+      [0]=>
+      *RECURSION*
+    }
+  }
+}
+
+Catchable fatal error: json_encode(): recursion detected in %s on line %d
diff --git a/ext/json/tests/004.phpt b/ext/json/tests/004.phpt
new file mode 100644 (file)
index 0000000..21777ba
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+json_encode() & endless loop - 2
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$a = new stdclass;
+$a->prop = $a;
+
+var_dump($a);
+var_dump(json_encode($a));
+
+echo "Done\n";
+?>
+--EXPECTF--    
+object(stdClass)#%d (1) {
+  ["prop"]=>
+  object(stdClass)#%d (1) {
+    ["prop"]=>
+    *RECURSION*
+  }
+}
+
+Catchable fatal error: json_encode(): recursion detected in %s on line %d
diff --git a/ext/json/tests/005.phpt b/ext/json/tests/005.phpt
new file mode 100644 (file)
index 0000000..b111687
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+json_encode() & endless loop - 3
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$a = array();
+$a[] = $a;
+
+var_dump($a);
+var_dump(json_encode($a));
+
+echo "Done\n";
+?>
+--EXPECTF--    
+array(1) {
+  [0]=>
+  array(1) {
+    [0]=>
+    *RECURSION*
+  }
+}
+
+Catchable fatal error: json_encode(): recursion detected in %s on line %d