[PHP-CVS] com php-src: Improve json_encode error handling: ext/json/JSON_parser.h ext/json/json.c ext/json/tests/003.phpt ext/json/tests/004.phpt ext/json/tests/inf_nan_error.phpt ext/json/tests/json_
Commit:84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f Author:Nikita Popov Sat, 23 Jun 2012 20:46:27 +0200 Parents: cc90ac54beb7359e5a3210261ce09159bbc43e92 Branches: PHP-5.3 PHP-5.4 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f Log: 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. Changed paths: M ext/json/JSON_parser.h M ext/json/json.c M ext/json/tests/003.phpt M ext/json/tests/004.phpt A ext/json/tests/inf_nan_error.phpt M ext/json/tests/json_encode_basic.phpt M ext/json/tests/pass001.1.phpt M ext/json/tests/pass001.phpt A ext/json/tests/unsupported_type_error.phpt diff --git a/ext/json/JSON_parser.h b/ext/json/JSON_parser.h index 746190b..5037344 100644 --- a/ext/json/JSON_parser.h +++ b/ext/json/JSON_parser.h @@ -24,7 +24,10 @@ enum error_codes { PHP_JSON_ERROR_STATE_MISMATCH, PHP_JSON_ERROR_CTRL_CHAR, PHP_JSON_ERROR_SYNTAX, -PHP_JSON_ERROR_UTF8 +PHP_JSON_ERROR_UTF8, +PHP_JSON_ERROR_RECURSION, +PHP_JSON_ERROR_INF_OR_NAN, +PHP_JSON_ERROR_UNSUPPORTED_TYPE }; extern JSON_parser new_JSON_parser(int depth); diff --git a/ext/json/json.c b/ext/json/json.c index ce2cf43..a904765 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-CVS] com php-src: Merge branch 'PHP-5.3' into PHP-5.4: ext/json/JSON_parser.h ext/json/json.c ext/json/php_json.h ext/json/tests/bug43941.phpt ext/json/tests/bug53946.phpt ext/json/tests/bug54058
Commit:36fa17a5fae84ab332366a202f0a709279a2466a Author:Nikita Popov Sat, 23 Jun 2012 21:14:45 +0200 Parents: e8862725770c3d5ee27c6c8c8a01b226b610fa08 84fe2cc890e49f40bac7c3ba74b3cfc6dc4cef2f Branches: PHP-5.4 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=36fa17a5fae84ab332366a202f0a709279a2466a Log: Merge branch 'PHP-5.3' into PHP-5.4 * PHP-5.3: Improve json_encode error handling - BFN Conflicts: ext/json/json.c Changed paths: MM ext/json/JSON_parser.h MM ext/json/json.c MM ext/json/php_json.h MA ext/json/tests/bug43941.phpt MA ext/json/tests/bug53946.phpt MM ext/json/tests/bug54058.phpt MA ext/json/tests/bug61978.phpt diff --cc ext/json/json.c index 557fbc3,a904765..bc30251 --- a/ext/json/json.c +++ b/ext/json/json.c @@@ -93,9 -73,7 +93,10 @@@ static PHP_MINIT_FUNCTION(json REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT); @@@ -103,10 -81,10 +104,13 @@@ 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); + REGISTER_LONG_CONSTANT("JSON_OBJECT_AS_ARRAY", PHP_JSON_OBJECT_AS_ARRAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_BIGINT_AS_STRING", PHP_JSON_BIGINT_AS_STRING, CONST_CS | CONST_PERSISTENT); + return SUCCESS; } /* }}} */ @@@ -387,11 -324,9 +393,9 @@@ static void json_escape_string(smart_st if (utf16) { efree(utf16); } - if (len < 0) { + if (ulen < 0) { JSON_G(error_code) = PHP_JSON_ERROR_UTF8; - if (!PG(display_errors)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument"); - } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument"); smart_str_appendl(buf, "null", 4); } else { smart_str_appendl(buf, "\"\"", 2); @@@ -502,56 -430,7 +506,57 @@@ } smart_str_appendc(buf, '"'); - efree(utf16); + if (utf16) { + efree(utf16); + } +} +/* }}} */ + + +static void json_encode_serializable_object(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ +{ + zend_class_entry *ce = Z_OBJCE_P(val); + zval *retval = NULL, fname; + HashTable* myht; + + if (Z_TYPE_P(val) == IS_ARRAY) { + myht = HASH_OF(val); + } else { + myht = Z_OBJPROP_P(val); + } + + 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; + } + + ZVAL_STRING(&fname, "jsonSerialize", 0); + + if (FAILURE == call_user_function_ex(EG(function_table), &val, &fname, &retval, 0, NULL, 1, NULL TSRMLS_CC) || !retval) { + zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Failed calling %s::jsonSerialize()", ce->name); + smart_str_appendl(buf, "null", sizeof("null") - 1); + return; +} + + if (EG(exception)) { + /* Error already raised */ + zval_ptr_dtor(&retval); + smart_str_appe
[PHP-CVS] com php-src: - BFN: NEWS
Commit:cc90ac54beb7359e5a3210261ce09159bbc43e92 Author:Felipe Pena Sat, 23 Jun 2012 15:21:20 -0300 Parents: c3f34796a053f5ff1016d872f8c339e32468783f Branches: PHP-5.3 Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=cc90ac54beb7359e5a3210261ce09159bbc43e92 Log: - BFN Changed paths: M NEWS Diff: diff --git a/NEWS b/NEWS index 79b7325..b9bb009 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,8 @@ PHP NEWS . Fixed bug #62227 (Invalid phar stream path causes crash). (Felipe) - Reflection: + . Fixed bug #62384 (Attempting to invoke a Closure more than once causes +segfault). (Felipe) . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks with constant). (Laruence) -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-CVS] com php-src: - BFN: NEWS
Commit:e8862725770c3d5ee27c6c8c8a01b226b610fa08 Author:Felipe Pena Sat, 23 Jun 2012 15:21:32 -0300 Parents: 5e36306feb8ce2b43eb494d5c486fd341b0a1ea7 Branches: PHP-5.4 Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e8862725770c3d5ee27c6c8c8a01b226b610fa08 Log: - BFN Changed paths: M NEWS Diff: diff --git a/NEWS b/NEWS index dfad253..e93d717 100644 --- a/NEWS +++ b/NEWS @@ -52,8 +52,10 @@ PHP NEWS return a value). (Johannes) - Reflection: - . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks - with constant). (Laruence) + . Fixed bug #62384 (Attempting to invoke a Closure more than once causes +segfault). (Felipe) + . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks +with constant). (Laruence) - Sockets: . Fixed bug #62025 (__ss_family was changed on AIX 5.3). (Felipe) -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-CVS] com php-src: Merge branch 'PHP-5.3' into PHP-5.4: ext/reflection/php_reflection.c
Commit:5e36306feb8ce2b43eb494d5c486fd341b0a1ea7 Author:Felipe Pena Sat, 23 Jun 2012 15:16:13 -0300 Parents: 2418791731a2d4b983bccb73d8b8835044f66673 c3f34796a053f5ff1016d872f8c339e32468783f Branches: PHP-5.4 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=5e36306feb8ce2b43eb494d5c486fd341b0a1ea7 Log: Merge branch 'PHP-5.3' into PHP-5.4 * PHP-5.3: - Improved fix for #62384 Bugs: https://bugs.php.net/62384 Changed paths: MM ext/reflection/php_reflection.c Diff: -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-CVS] com php-src: - Improved fix for #62384: ext/reflection/php_reflection.c
Commit:c3f34796a053f5ff1016d872f8c339e32468783f Author:Felipe Pena Sat, 23 Jun 2012 15:10:47 -0300 Parents: 84b1c568f4d593c2f415b05f3b1b8bd0465eec27 Branches: PHP-5.3 PHP-5.4 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=c3f34796a053f5ff1016d872f8c339e32468783f Log: - Improved fix for #62384 Bugs: https://bugs.php.net/62384 Changed paths: M ext/reflection/php_reflection.c Diff: diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 966c9a5..180ce8f 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2749,12 +2749,10 @@ ZEND_METHOD(reflection_method, invokeArgs) fcc.object_ptr = object; /* -* Closure::__invoke() actually expects a copy of zend_function, so that it -* frees it after the invoking. +* Copy the zend_function when calling via handler (e.g. Closure::__invoke()) */ - if (obj_ce == zend_ce_closure && object && - strlen(mptr->common.function_name) == sizeof(ZEND_INVOKE_FUNC_NAME)-1 && - memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) { + if (mptr->type == ZEND_INTERNAL_FUNCTION && + (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) { fcc.function_handler = _copy_function(mptr TSRMLS_CC); } -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php