From: Antony Dovgal Date: Thu, 20 Jul 2006 08:56:57 +0000 (+0000) Subject: MFH: add recursion protection to json_encode() and new tests X-Git-Tag: php-5.2.0RC1~50 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e308d3a6b6cba69654598836481477816a298f1;p=php MFH: add recursion protection to json_encode() and new tests --- 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-- + --FILE-- +--FILE-- +""))); +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-- + +--FILE-- + +--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-- + +--FILE-- +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-- + +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + array(1) { + [0]=> + *RECURSION* + } +} + +Catchable fatal error: json_encode(): recursion detected in %s on line %d