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

Reply via email to