Commit: 36fa17a5fae84ab332366a202f0a709279a2466a
Author: Nikita Popov <ni...@php.net> 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_appendl(buf, "null", sizeof("null") - 1);
+ return;
+ }
+
+ if ((Z_TYPE_P(retval) == IS_OBJECT) &&
+ (Z_OBJ_HANDLE_P(retval) == Z_OBJ_HANDLE_P(val))) {
+ /* Handle the case where jsonSerialize does: return $this; by
going straight to encode array */
+ json_encode_array(buf, &retval, options TSRMLS_CC);
+ } else {
+ /* All other types, encode as normal */
+ php_json_encode(buf, retval, options TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&retval);
}
/* }}} */
diff --cc ext/json/php_json.h
index ef3e4b5,3cb4902..afeff3f
--- a/ext/json/php_json.h
+++ b/ext/json/php_json.h
@@@ -60,23 -56,10 +60,24 @@@ extern zend_class_entry *php_json_seria
#define PHP_JSON_HEX_QUOT (1<<3)
#define PHP_JSON_FORCE_OBJECT (1<<4)
#define PHP_JSON_NUMERIC_CHECK (1<<5)
-#define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR (1<<9)
+#define PHP_JSON_UNESCAPED_SLASHES (1<<6)
+#define PHP_JSON_PRETTY_PRINT (1<<7)
+#define PHP_JSON_UNESCAPED_UNICODE (1<<8)
++#define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR (1<<9)
+
+/* Internal flags */
+#define PHP_JSON_OUTPUT_ARRAY 0
+#define PHP_JSON_OUTPUT_OBJECT 1
+
+/* json_decode() options */
+#define PHP_JSON_OBJECT_AS_ARRAY (1<<0)
+#define PHP_JSON_BIGINT_AS_STRING (1<<1)
+
+static inline void php_json_decode(zval *return_value, char *str, int
str_len, zend_bool assoc, long depth TSRMLS_DC)
+{
+ php_json_decode_ex(return_value, str, str_len, assoc ?
PHP_JSON_OBJECT_AS_ARRAY : 0, depth TSRMLS_CC);
+}
-#define PHP_JSON_OUTPUT_ARRAY 0
-#define PHP_JSON_OUTPUT_OBJECT 1
#endif /* PHP_JSON_H */
diff --cc ext/json/tests/bug43941.phpt
index 0f86d1d,0000000..fb59b71
mode 100644,000000..100644
--- a/ext/json/tests/bug43941.phpt
+++ b/ext/json/tests/bug43941.phpt
@@@ -1,21 -1,0 +1,28 @@@
+--TEST--
+Bug #43941 (json_encode() invalid UTF-8)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+var_dump(json_encode("abc"));
+var_dump(json_encode("ab\xE0"));
- var_dump(json_encode("ab\xE0c"));
- var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc")));
++var_dump(json_encode("ab\xE0", JSON_PARTIAL_OUTPUT_ON_ERROR));
++var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc"),
JSON_PARTIAL_OUTPUT_ON_ERROR));
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(5) ""abc""
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
++bool(false)
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
+string(4) "null"
- string(4) "null"
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
+string(17) "[null,null,"abc"]"
+Done
-
diff --cc ext/json/tests/bug53946.phpt
index abbb812,0000000..079906f
mode 100644,000000..100644
--- a/ext/json/tests/bug53946.phpt
+++ b/ext/json/tests/bug53946.phpt
@@@ -1,16 -1,0 +1,20 @@@
+--TEST--
+bug #53946 (json_encode() with JSON_UNESCAPED_UNICODE)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+var_dump(json_encode("latin 1234 -/ russian мама мыла раму specialchars
\x02 \x08 \n U+1D11E >𝄞<"));
+var_dump(json_encode("latin 1234 -/ russian мама мыла раму specialchars
\x02 \x08 \n U+1D11E >𝄞<", JSON_UNESCAPED_UNICODE));
+var_dump(json_encode("ab\xE0"));
+var_dump(json_encode("ab\xE0", JSON_UNESCAPED_UNICODE));
+?>
- --EXPECT--
++--EXPECTF--
+string(156) ""latin 1234 -\/ russian \u043c\u0430\u043c\u0430
\u043c\u044b\u043b\u0430 \u0440\u0430\u043c\u0443 specialchars \u0002 \b \n
U+1D11E >\ud834\udd1e<""
+string(100) ""latin 1234 -\/ russian мама мыла раму specialchars \u0002
\b \n U+1D11E >𝄞<""
- string(4) "null"
- string(4) "null"
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
++bool(false)
++
++Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
++bool(false)
diff --cc ext/json/tests/bug54058.phpt
index 3b1136b,08c7f57..e3596eb
--- a/ext/json/tests/bug54058.phpt
+++ b/ext/json/tests/bug54058.phpt
@@@ -29,7 -29,14 +29,15 @@@ json_encode($c)
var_dump(json_last_error());
?>
--EXPECTF--
++
+ Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
int(5)
+
+ Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
int(5)
+
+ Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
int(5)
+
+ Warning: json_encode(): Invalid UTF-8 sequence in argument in %s on line %d
int(5)
diff --cc ext/json/tests/bug61978.phpt
index 2c73297,0000000..4c863c6
mode 100644,000000..100644
--- a/ext/json/tests/bug61978.phpt
+++ b/ext/json/tests/bug61978.phpt
@@@ -1,47 -1,0 +1,47 @@@
+--TEST--
+Bug #61978 (Object recursion not detected for classes that implement
JsonSerializable)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+class JsonTest1 {
+ public $test;
+ public $me;
+ public function __construct() {
+ $this->test = '123';
+ $this->me = $this;
+ }
+}
+
+class JsonTest2 implements JsonSerializable {
+ public $test;
+ public function __construct() {
+ $this->test = '123';
+ }
+ public function jsonSerialize() {
+ return array(
+ 'test' => $this->test,
+ 'me' => $this
+ );
+ }
+}
+
+
+$obj1 = new JsonTest1();
- var_dump(json_encode($obj1));
++var_dump(json_encode($obj1, JSON_PARTIAL_OUTPUT_ON_ERROR));
+
+echo "\n==\n";
+
+$obj2 = new JsonTest2();
- var_dump(json_encode($obj2));
++var_dump(json_encode($obj2, JSON_PARTIAL_OUTPUT_ON_ERROR));
+
+?>
+--EXPECTF--
+Warning: json_encode(): recursion detected in %s on line %d
+string(44) "{"test":"123","me":{"test":"123","me":null}}"
+
+==
+
+Warning: json_encode(): recursion detected in %s on line %d
+string(44) "{"test":"123","me":{"test":"123","me":null}}"
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php