diff options
author | Jakub Zelenka <bukka@php.net> | 2016-08-28 12:53:11 +0100 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2016-08-29 14:49:40 +0100 |
commit | df05dbb3dfa0b55b25ff499c7e1646928279952d (patch) | |
tree | 7ff8cbba01b738b235b6372ffa4c0a48baf6ab0e /ext/json/json_encoder.c | |
parent | 12a8c3f6e79ff159cce455ff9944a03aa70ff589 (diff) | |
download | php-git-df05dbb3dfa0b55b25ff499c7e1646928279952d.tar.gz |
Fix recursion and protection in the failed JSON encoding
Diffstat (limited to 'ext/json/json_encoder.c')
-rw-r--r-- | ext/json/json_encoder.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index fd9669f9d6..8fd2f23dff 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -108,6 +108,20 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) } /* }}} */ +#define PHP_JSON_HASH_APPLY_PROTECTION_INC(_tmp_ht) \ + do { \ + if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \ + ZEND_HASH_INC_APPLY_COUNT(_tmp_ht); \ + } \ + } while (0) + +#define PHP_JSON_HASH_APPLY_PROTECTION_DEC(_tmp_ht) \ + do { \ + if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \ + ZEND_HASH_DEC_APPLY_COUNT(_tmp_ht); \ + } \ + } while (0) + static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */ { int i, r, need_comma = 0; @@ -146,9 +160,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { ZVAL_DEREF(data); tmp_ht = HASH_OF(data); - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_INC_APPLY_COUNT(tmp_ht); - } + PHP_JSON_HASH_APPLY_PROTECTION_INC(tmp_ht); if (r == PHP_JSON_OUTPUT_ARRAY) { if (need_comma) { @@ -163,9 +175,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ if (key) { if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) { /* Skip protected and private members. */ - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); - } + PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht); continue; } @@ -198,19 +208,18 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ php_json_pretty_print_char(buf, options, ' '); } - if (php_json_encode(buf, data, options) == FAILURE && (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { + if (php_json_encode(buf, data, options) == FAILURE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { + PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht); return FAILURE; } - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); - } + PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht); } ZEND_HASH_FOREACH_END(); } if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) { JSON_G(error_code) = PHP_JSON_ERROR_DEPTH; - if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + if (!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { return FAILURE; } } |