diff options
author | Florian Anderiasch <fa@php.net> | 2012-07-24 13:15:16 +0200 |
---|---|---|
committer | Florian Anderiasch <fa@php.net> | 2012-07-24 13:15:16 +0200 |
commit | 45d596ea1e32792c7b7b7f28be220dea861b6708 (patch) | |
tree | 9dc75d99db089e813944ff8229618c307a70d686 | |
parent | dd9d64b21e4bbc8a106a6156dc6ffefbcc33ec02 (diff) | |
download | php-git-45d596ea1e32792c7b7b7f28be220dea861b6708.tar.gz |
Add optional depth parameter to json_encode #62369
-rw-r--r-- | ext/json/json.c | 10 | ||||
-rw-r--r-- | ext/json/php_json.h | 1 | ||||
-rw-r--r-- | ext/json/tests/bug62369.phpt | 34 |
3 files changed, 44 insertions, 1 deletions
diff --git a/ext/json/json.c b/ext/json/json.c index 96690477c9..dab423084c 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -47,6 +47,7 @@ ZEND_DECLARE_MODULE_GLOBALS(json) ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, depth) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1) @@ -126,6 +127,7 @@ static PHP_GINIT_FUNCTION(json) { json_globals->encoder_depth = 0; json_globals->error_code = 0; + json_globals->encode_max_depth = 0; } /* }}} */ @@ -341,6 +343,9 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) } } + if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) { + JSON_G(error_code) = PHP_JSON_ERROR_DEPTH; + } --JSON_G(encoder_depth); json_pretty_print_char(buf, options, '\n' TSRMLS_CC); json_pretty_print_indent(buf, options TSRMLS_CC); @@ -702,13 +707,16 @@ static PHP_FUNCTION(json_encode) zval *parameter; smart_str buf = {0}; long options = 0; + long depth = JSON_PARSER_DEFAULT_DEPTH; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", ¶meter, &options) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", ¶meter, &options, &depth) == FAILURE) { return; } JSON_G(error_code) = PHP_JSON_ERROR_NONE; + JSON_G(encode_max_depth) = depth; + php_json_encode(&buf, parameter, options TSRMLS_CC); if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { diff --git a/ext/json/php_json.h b/ext/json/php_json.h index afeff3f6cc..2b3cf5868a 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -40,6 +40,7 @@ extern zend_module_entry json_module_entry; ZEND_BEGIN_MODULE_GLOBALS(json) int encoder_depth; int error_code; + int encode_max_depth; ZEND_END_MODULE_GLOBALS(json) #ifdef ZTS diff --git a/ext/json/tests/bug62369.phpt b/ext/json/tests/bug62369.phpt new file mode 100644 index 0000000000..a5efd802c5 --- /dev/null +++ b/ext/json/tests/bug62369.phpt @@ -0,0 +1,34 @@ +--TEST-- +FR #62369 (Segfault on json_encode(deeply_nested_array) +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php + +$array = array(); +for ($i=0; $i<550; $i++) { + $array = array($array); +} + +json_encode($array, 0, 551); +switch (json_last_error()) { + case JSON_ERROR_NONE: + echo 'OK'.PHP_EOL; + break; + case JSON_ERROR_DEPTH: + echo 'ERROR'.PHP_EOL; + break; +} + +json_encode($array, 0, 540); +switch (json_last_error()) { + case JSON_ERROR_NONE: + echo 'OK'.PHP_EOL; + break; + case JSON_ERROR_DEPTH: + echo 'ERROR'.PHP_EOL; + break; +} +--EXPECTF-- +OK +ERROR |