summaryrefslogtreecommitdiff
path: root/ext/json
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2006-07-20 08:56:57 +0000
committerAntony Dovgal <tony2001@php.net>2006-07-20 08:56:57 +0000
commit3e308d3a6b6cba69654598836481477816a298f1 (patch)
treeb1620a2faf912070dcabb0e7e24bfa653867fcab /ext/json
parent0b97d2bd6072fc8939f452459f0b4ae46582a06a (diff)
downloadphp-git-3e308d3a6b6cba69654598836481477816a298f1.tar.gz
MFH: add recursion protection to json_encode() and new tests
Diffstat (limited to 'ext/json')
-rw-r--r--ext/json/json.c15
-rw-r--r--ext/json/tests/001.phpt2
-rw-r--r--ext/json/tests/002.phpt28
-rw-r--r--ext/json/tests/003.phpt28
-rw-r--r--ext/json/tests/004.phpt25
-rw-r--r--ext/json/tests/005.phpt25
6 files changed, 123 insertions, 0 deletions
diff --git a/ext/json/json.c b/ext/json/json.c
index 0df5017e44..99e80fa913 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -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--;
+ }
}
}
}
diff --git a/ext/json/tests/001.phpt b/ext/json/tests/001.phpt
index 89a9528d9a..095aedf631 100644
--- a/ext/json/tests/001.phpt
+++ b/ext/json/tests/001.phpt
@@ -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
index 0000000000..5bc29bc5b9
--- /dev/null
+++ b/ext/json/tests/002.phpt
@@ -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
index 0000000000..bb5619d9dd
--- /dev/null
+++ b/ext/json/tests/003.phpt
@@ -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
index 0000000000..21777ba2a1
--- /dev/null
+++ b/ext/json/tests/004.phpt
@@ -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
index 0000000000..b11168702c
--- /dev/null
+++ b/ext/json/tests/005.phpt
@@ -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