summaryrefslogtreecommitdiff
path: root/ext/json/json_encoder.c
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2016-08-28 12:53:11 +0100
committerJakub Zelenka <bukka@php.net>2016-08-29 14:49:40 +0100
commitdf05dbb3dfa0b55b25ff499c7e1646928279952d (patch)
tree7ff8cbba01b738b235b6372ffa4c0a48baf6ab0e /ext/json/json_encoder.c
parent12a8c3f6e79ff159cce455ff9944a03aa70ff589 (diff)
downloadphp-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.c31
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;
}
}