mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Introduce json encoder to fix globals related issues
It fixes bugs #66025 and #73254 by replacing globals with a passed structure holding depth and error code. In addition it fixes #72069 in a more generic way.
This commit is contained in:
parent
be6bf71274
commit
c34de0b61c
6 changed files with 120 additions and 47 deletions
4
NEWS
4
NEWS
|
@ -10,6 +10,10 @@ PHP NEWS
|
||||||
. Fixed bug #73392 (A use-after-free in zend allocator management).
|
. Fixed bug #73392 (A use-after-free in zend allocator management).
|
||||||
(Laruence)
|
(Laruence)
|
||||||
|
|
||||||
|
- JSON:
|
||||||
|
. Introduced encoder struct instead of global which fixes bugs #66025 and
|
||||||
|
#73254 related to pretty print indentation. (Jakub Zelenka)
|
||||||
|
|
||||||
27 Oct 2016, PHP 7.1.0RC5
|
27 Oct 2016, PHP 7.1.0RC5
|
||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
|
|
|
@ -186,7 +186,17 @@ static PHP_MINFO_FUNCTION(json)
|
||||||
|
|
||||||
PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */
|
PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */
|
||||||
{
|
{
|
||||||
return php_json_encode_zval(buf, val, options);
|
php_json_encoder encoder;
|
||||||
|
int return_code;
|
||||||
|
|
||||||
|
php_json_encode_init(&encoder);
|
||||||
|
encoder.max_depth = JSON_G(encode_max_depth);
|
||||||
|
encoder.error_code = PHP_JSON_ERROR_NONE;
|
||||||
|
|
||||||
|
return_code = php_json_encode_zval(buf, val, options, &encoder);
|
||||||
|
JSON_G(error_code) = encoder.error_code;
|
||||||
|
|
||||||
|
return return_code;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -211,6 +221,7 @@ PHP_JSON_API int php_json_decode_ex(zval *return_value, char *str, size_t str_le
|
||||||
static PHP_FUNCTION(json_encode)
|
static PHP_FUNCTION(json_encode)
|
||||||
{
|
{
|
||||||
zval *parameter;
|
zval *parameter;
|
||||||
|
php_json_encoder encoder;
|
||||||
smart_str buf = {0};
|
smart_str buf = {0};
|
||||||
zend_long options = 0;
|
zend_long options = 0;
|
||||||
zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
|
zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH;
|
||||||
|
@ -219,22 +230,22 @@ static PHP_FUNCTION(json_encode)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_NONE;
|
php_json_encode_init(&encoder);
|
||||||
|
encoder.max_depth = (int)depth;
|
||||||
|
encoder.error_code = PHP_JSON_ERROR_NONE;
|
||||||
|
php_json_encode_zval(&buf, parameter, (int)options, &encoder);
|
||||||
|
JSON_G(error_code) = encoder.error_code;
|
||||||
|
|
||||||
JSON_G(encode_max_depth) = (int)depth;
|
if (encoder.error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
||||||
|
|
||||||
php_json_encode(&buf, parameter, (int)options);
|
|
||||||
|
|
||||||
if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
|
||||||
smart_str_free(&buf);
|
smart_str_free(&buf);
|
||||||
ZVAL_FALSE(return_value);
|
RETURN_FALSE;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
smart_str_0(&buf); /* copy? */
|
smart_str_0(&buf); /* copy? */
|
||||||
if (buf.s) {
|
if (buf.s) {
|
||||||
RETURN_NEW_STR(buf.s);
|
RETURN_NEW_STR(buf.s);
|
||||||
}
|
}
|
||||||
RETURN_EMPTY_STRING();
|
RETURN_EMPTY_STRING();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,14 @@
|
||||||
#include "ext/standard/html.h"
|
#include "ext/standard/html.h"
|
||||||
#include "zend_smart_str.h"
|
#include "zend_smart_str.h"
|
||||||
#include "php_json.h"
|
#include "php_json.h"
|
||||||
|
#include "php_json_encoder.h"
|
||||||
#include <zend_exceptions.h>
|
#include <zend_exceptions.h>
|
||||||
|
|
||||||
static const char digits[] = "0123456789abcdef";
|
static const char digits[] = "0123456789abcdef";
|
||||||
|
|
||||||
static int php_json_escape_string(smart_str *buf, char *s, size_t len, int options);
|
static int php_json_escape_string(
|
||||||
|
smart_str *buf, char *s, size_t len,
|
||||||
|
int options, php_json_encoder *encoder);
|
||||||
|
|
||||||
static int php_json_determine_array_type(zval *val) /* {{{ */
|
static int php_json_determine_array_type(zval *val) /* {{{ */
|
||||||
{
|
{
|
||||||
|
@ -76,12 +79,12 @@ static inline void php_json_pretty_print_char(smart_str *buf, int options, char
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static inline void php_json_pretty_print_indent(smart_str *buf, int options) /* {{{ */
|
static inline void php_json_pretty_print_indent(smart_str *buf, int options, php_json_encoder *encoder) /* {{{ */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (options & PHP_JSON_PRETTY_PRINT) {
|
if (options & PHP_JSON_PRETTY_PRINT) {
|
||||||
for (i = 0; i < JSON_G(encoder_depth); ++i) {
|
for (i = 0; i < encoder->depth; ++i) {
|
||||||
smart_str_appendl(buf, " ", 4);
|
smart_str_appendl(buf, " ", 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +129,7 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */
|
static int php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
|
||||||
{
|
{
|
||||||
int i, r, need_comma = 0;
|
int i, r, need_comma = 0;
|
||||||
HashTable *myht;
|
HashTable *myht;
|
||||||
|
@ -140,7 +143,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
|
encoder->error_code = PHP_JSON_ERROR_RECURSION;
|
||||||
smart_str_appendl(buf, "null", 4);
|
smart_str_appendl(buf, "null", 4);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +154,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
smart_str_appendc(buf, '{');
|
smart_str_appendc(buf, '{');
|
||||||
}
|
}
|
||||||
|
|
||||||
++JSON_G(encoder_depth);
|
++encoder->depth;
|
||||||
|
|
||||||
i = myht ? zend_hash_num_elements(myht) : 0;
|
i = myht ? zend_hash_num_elements(myht) : 0;
|
||||||
|
|
||||||
|
@ -174,7 +177,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
}
|
}
|
||||||
|
|
||||||
php_json_pretty_print_char(buf, options, '\n');
|
php_json_pretty_print_char(buf, options, '\n');
|
||||||
php_json_pretty_print_indent(buf, options);
|
php_json_pretty_print_indent(buf, options, encoder);
|
||||||
} else if (r == PHP_JSON_OUTPUT_OBJECT) {
|
} else if (r == PHP_JSON_OUTPUT_OBJECT) {
|
||||||
if (key) {
|
if (key) {
|
||||||
if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) {
|
if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) {
|
||||||
|
@ -190,9 +193,10 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
}
|
}
|
||||||
|
|
||||||
php_json_pretty_print_char(buf, options, '\n');
|
php_json_pretty_print_char(buf, options, '\n');
|
||||||
php_json_pretty_print_indent(buf, options);
|
php_json_pretty_print_indent(buf, options, encoder);
|
||||||
|
|
||||||
php_json_escape_string(buf, ZSTR_VAL(key), ZSTR_LEN(key), options & ~PHP_JSON_NUMERIC_CHECK);
|
php_json_escape_string(buf, ZSTR_VAL(key), ZSTR_LEN(key),
|
||||||
|
options & ~PHP_JSON_NUMERIC_CHECK, encoder);
|
||||||
} else {
|
} else {
|
||||||
if (need_comma) {
|
if (need_comma) {
|
||||||
smart_str_appendc(buf, ',');
|
smart_str_appendc(buf, ',');
|
||||||
|
@ -201,7 +205,7 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
}
|
}
|
||||||
|
|
||||||
php_json_pretty_print_char(buf, options, '\n');
|
php_json_pretty_print_char(buf, options, '\n');
|
||||||
php_json_pretty_print_indent(buf, options);
|
php_json_pretty_print_indent(buf, options, encoder);
|
||||||
|
|
||||||
smart_str_appendc(buf, '"');
|
smart_str_appendc(buf, '"');
|
||||||
smart_str_append_long(buf, (zend_long) index);
|
smart_str_append_long(buf, (zend_long) index);
|
||||||
|
@ -212,7 +216,8 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
php_json_pretty_print_char(buf, 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_zval(buf, data, options, encoder) == FAILURE &&
|
||||||
|
!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
||||||
PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht);
|
PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -221,18 +226,18 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) {
|
if (encoder->depth > encoder->max_depth) {
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_DEPTH;
|
encoder->error_code = PHP_JSON_ERROR_DEPTH;
|
||||||
if (!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
if (!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--JSON_G(encoder_depth);
|
--encoder->depth;
|
||||||
|
|
||||||
/* Only keep closing bracket on same line for empty arrays/objects */
|
/* Only keep closing bracket on same line for empty arrays/objects */
|
||||||
if (need_comma) {
|
if (need_comma) {
|
||||||
php_json_pretty_print_char(buf, options, '\n');
|
php_json_pretty_print_char(buf, options, '\n');
|
||||||
php_json_pretty_print_indent(buf, options);
|
php_json_pretty_print_indent(buf, options, encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
||||||
|
@ -282,7 +287,9 @@ static int php_json_utf8_to_utf16(unsigned short *utf16, char utf8[], size_t len
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static int php_json_escape_string(smart_str *buf, char *s, size_t len, int options) /* {{{ */
|
static int php_json_escape_string(
|
||||||
|
smart_str *buf, char *s, size_t len,
|
||||||
|
int options, php_json_encoder *encoder) /* {{{ */
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
unsigned int us;
|
unsigned int us;
|
||||||
|
@ -313,7 +320,7 @@ static int php_json_escape_string(smart_str *buf, char *s, size_t len, int optio
|
||||||
if (options & PHP_JSON_UNESCAPED_UNICODE) {
|
if (options & PHP_JSON_UNESCAPED_UNICODE) {
|
||||||
/* validate UTF-8 string first */
|
/* validate UTF-8 string first */
|
||||||
if (php_json_utf8_to_utf16(NULL, s, len) < 0) {
|
if (php_json_utf8_to_utf16(NULL, s, len) < 0) {
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
|
encoder->error_code = PHP_JSON_ERROR_UTF8;
|
||||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||||
smart_str_appendl(buf, "null", 4);
|
smart_str_appendl(buf, "null", 4);
|
||||||
}
|
}
|
||||||
|
@ -337,7 +344,7 @@ static int php_json_escape_string(smart_str *buf, char *s, size_t len, int optio
|
||||||
if (buf->s) {
|
if (buf->s) {
|
||||||
ZSTR_LEN(buf->s) = checkpoint;
|
ZSTR_LEN(buf->s) = checkpoint;
|
||||||
}
|
}
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
|
encoder->error_code = PHP_JSON_ERROR_UTF8;
|
||||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||||
smart_str_appendl(buf, "null", 4);
|
smart_str_appendl(buf, "null", 4);
|
||||||
}
|
}
|
||||||
|
@ -465,12 +472,12 @@ static int php_json_escape_string(smart_str *buf, char *s, size_t len, int optio
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static int php_json_encode_serializable_object(smart_str *buf, zval *val, int options) /* {{{ */
|
static int php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = Z_OBJCE_P(val);
|
zend_class_entry *ce = Z_OBJCE_P(val);
|
||||||
zval retval, fname;
|
zval retval, fname;
|
||||||
HashTable* myht;
|
HashTable* myht;
|
||||||
int origin_error_code;
|
int return_code;
|
||||||
|
|
||||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||||
myht = Z_ARRVAL_P(val);
|
myht = Z_ARRVAL_P(val);
|
||||||
|
@ -479,7 +486,7 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
|
encoder->error_code = PHP_JSON_ERROR_RECURSION;
|
||||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||||
smart_str_appendl(buf, "null", 4);
|
smart_str_appendl(buf, "null", 4);
|
||||||
}
|
}
|
||||||
|
@ -489,7 +496,6 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op
|
||||||
|
|
||||||
ZVAL_STRING(&fname, "jsonSerialize");
|
ZVAL_STRING(&fname, "jsonSerialize");
|
||||||
|
|
||||||
origin_error_code = JSON_G(error_code);
|
|
||||||
if (FAILURE == call_user_function_ex(EG(function_table), val, &fname, &retval, 0, NULL, 1, NULL) || Z_TYPE(retval) == IS_UNDEF) {
|
if (FAILURE == call_user_function_ex(EG(function_table), val, &fname, &retval, 0, NULL, 1, NULL) || Z_TYPE(retval) == IS_UNDEF) {
|
||||||
if (!EG(exception)) {
|
if (!EG(exception)) {
|
||||||
zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name));
|
zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name));
|
||||||
|
@ -502,7 +508,6 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_G(error_code) = origin_error_code;
|
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
/* Error already raised */
|
/* Error already raised */
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
|
@ -517,20 +522,20 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op
|
||||||
if ((Z_TYPE(retval) == IS_OBJECT) &&
|
if ((Z_TYPE(retval) == IS_OBJECT) &&
|
||||||
(Z_OBJ(retval) == Z_OBJ_P(val))) {
|
(Z_OBJ(retval) == Z_OBJ_P(val))) {
|
||||||
/* Handle the case where jsonSerialize does: return $this; by going straight to encode array */
|
/* Handle the case where jsonSerialize does: return $this; by going straight to encode array */
|
||||||
php_json_encode_array(buf, &retval, options);
|
return_code = php_json_encode_array(buf, &retval, options, encoder);
|
||||||
} else {
|
} else {
|
||||||
/* All other types, encode as normal */
|
/* All other types, encode as normal */
|
||||||
php_json_encode(buf, &retval, options);
|
return_code = php_json_encode_zval(buf, &retval, options, encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
zval_ptr_dtor(&fname);
|
zval_ptr_dtor(&fname);
|
||||||
|
|
||||||
return SUCCESS;
|
return return_code;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
int php_json_encode_zval(smart_str *buf, zval *val, int options) /* {{{ */
|
int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
|
||||||
{
|
{
|
||||||
again:
|
again:
|
||||||
switch (Z_TYPE_P(val))
|
switch (Z_TYPE_P(val))
|
||||||
|
@ -554,28 +559,28 @@ again:
|
||||||
if (php_json_is_valid_double(Z_DVAL_P(val))) {
|
if (php_json_is_valid_double(Z_DVAL_P(val))) {
|
||||||
php_json_encode_double(buf, Z_DVAL_P(val), options);
|
php_json_encode_double(buf, Z_DVAL_P(val), options);
|
||||||
} else {
|
} else {
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
|
encoder->error_code = PHP_JSON_ERROR_INF_OR_NAN;
|
||||||
smart_str_appendc(buf, '0');
|
smart_str_appendc(buf, '0');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IS_STRING:
|
case IS_STRING:
|
||||||
return php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options);
|
return php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options, encoder);
|
||||||
|
|
||||||
case IS_OBJECT:
|
case IS_OBJECT:
|
||||||
if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) {
|
if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) {
|
||||||
return php_json_encode_serializable_object(buf, val, options);
|
return php_json_encode_serializable_object(buf, val, options, encoder);
|
||||||
}
|
}
|
||||||
/* fallthrough -- Non-serializable object */
|
/* fallthrough -- Non-serializable object */
|
||||||
case IS_ARRAY:
|
case IS_ARRAY:
|
||||||
return php_json_encode_array(buf, val, options);
|
return php_json_encode_array(buf, val, options, encoder);
|
||||||
|
|
||||||
case IS_REFERENCE:
|
case IS_REFERENCE:
|
||||||
val = Z_REFVAL_P(val);
|
val = Z_REFVAL_P(val);
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE;
|
encoder->error_code = PHP_JSON_ERROR_UNSUPPORTED_TYPE;
|
||||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||||
smart_str_appendl(buf, "null", 4);
|
smart_str_appendl(buf, "null", 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,19 @@
|
||||||
#include "php.h"
|
#include "php.h"
|
||||||
#include "zend_smart_str.h"
|
#include "zend_smart_str.h"
|
||||||
|
|
||||||
int php_json_encode_zval(smart_str *buf, zval *val, int options);
|
typedef struct _php_json_encoder php_json_encoder;
|
||||||
|
|
||||||
|
struct _php_json_encoder {
|
||||||
|
int depth;
|
||||||
|
int max_depth;
|
||||||
|
php_json_error_code error_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void php_json_encode_init(php_json_encoder *encoder)
|
||||||
|
{
|
||||||
|
memset(encoder, 0, sizeof(php_json_encoder));
|
||||||
|
}
|
||||||
|
|
||||||
|
int php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder);
|
||||||
|
|
||||||
#endif /* PHP_JSON_ENCODER_H */
|
#endif /* PHP_JSON_ENCODER_H */
|
||||||
|
|
19
ext/json/tests/bug66025.phpt
Normal file
19
ext/json/tests/bug66025.phpt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #66025 (Indent wrong when json_encode() called from jsonSerialize function)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('json')) die('skip');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo implements JsonSerializable {
|
||||||
|
public function jsonSerialize() {
|
||||||
|
return json_encode([1], JSON_PRETTY_PRINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([new Foo]), "\n";
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
["[\n 1\n]"]
|
21
ext/json/tests/bug73254.phpt
Normal file
21
ext/json/tests/bug73254.phpt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #73254 (Incorrect indentation generated by json_encode() with JSON_PRETTY_PRINT)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('json')) die('skip');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
echo json_encode([json_encode([1], JSON_PRETTY_PRINT)]), "\n";
|
||||||
|
|
||||||
|
$fp = fopen('php://temp', 'r');
|
||||||
|
$data = ['a' => $fp];
|
||||||
|
echo json_encode($data), "\n";
|
||||||
|
echo json_encode([json_encode([1], JSON_PRETTY_PRINT)]), "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
["[\n 1\n]"]
|
||||||
|
|
||||||
|
["[\n 1\n]"]
|
Loading…
Add table
Add a link
Reference in a new issue