diff options
author | Nikita Popov <nikic@php.net> | 2012-06-23 20:46:27 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2012-06-23 20:51:52 +0200 |
commit | 84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f (patch) | |
tree | 4b07a64554232483751acac245a9eb43154d0ecc /ext/json/json.c | |
parent | cc90ac54beb7359e5a3210261ce09159bbc43e92 (diff) | |
download | php-git-84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f.tar.gz |
Improve json_encode error handling
json_encode() now returns bool(false) for all possible errors, throws the
respective warning and also sets the respective json_last_error() error
code. Three new error codes have been added:
* JSON_ERROR_RECURSION
* JSON_ERROR_INF_OR_NAN
* JSON_ERROR_UNSUPPORTED_TYPE
To get a partial JSON output instead of bool(false) the option
JSON_PARTIAL_OUTPUT_ON_ERROR can be specified. In this case the invalid
segments will be replaced either by null (for recursion, unsupported type
and invalid JSON) or 0 (for Inf and NaN).
The warning for invalid UTF-8 stays intact and is thrown also with
display_errors = On. If this behavior is undesired this can be remedied
later.
Diffstat (limited to 'ext/json/json.c')
-rw-r--r-- | ext/json/json.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/ext/json/json.c b/ext/json/json.c index ce2cf43fcc..a90476530e 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -81,6 +81,9 @@ static PHP_MINIT_FUNCTION(json) REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_ERROR_RECURSION", PHP_JSON_ERROR_RECURSION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_ERROR_INF_OR_NAN", PHP_JSON_ERROR_INF_OR_NAN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", PHP_JSON_ERROR_UNSUPPORTED_TYPE, CONST_CS | CONST_PERSISTENT); return SUCCESS; } @@ -181,6 +184,7 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) } if (myht && myht->nApplyCount > 1) { + JSON_G(error_code) = PHP_JSON_ERROR_RECURSION; php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); smart_str_appendl(buf, "null", 4); return; @@ -303,7 +307,8 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR smart_str_appendl(buf, tmp, l); efree(tmp); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d); + JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec", d); smart_str_appendc(buf, '0'); } } @@ -460,7 +465,8 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_ smart_str_appendl(buf, d, len); efree(d); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl); + JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec", dbl); smart_str_appendc(buf, '0'); } } @@ -476,7 +482,8 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_ break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null"); + JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported"); smart_str_appendl(buf, "null", 4); break; } @@ -570,7 +577,7 @@ static PHP_FUNCTION(json_encode) php_json_encode(&buf, parameter, options TSRMLS_CC); - if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && options ^ PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { ZVAL_FALSE(return_value); } else { ZVAL_STRINGL(return_value, buf.c, buf.len, 1); |