diff options
Diffstat (limited to 'ext/json')
| -rw-r--r-- | ext/json/config.m4 | 2 | ||||
| -rw-r--r-- | ext/json/json.c | 54 | ||||
| -rw-r--r-- | ext/json/json_encoder.c | 200 | ||||
| -rw-r--r-- | ext/json/json_parser.tab.c | 176 | ||||
| -rw-r--r-- | ext/json/json_parser.tab.h | 6 | ||||
| -rw-r--r-- | ext/json/json_parser.y | 168 | ||||
| -rw-r--r-- | ext/json/json_scanner.c | 1095 | ||||
| -rw-r--r-- | ext/json/php_json.h | 11 | ||||
| -rw-r--r-- | ext/json/php_json_encoder.h | 15 | ||||
| -rw-r--r-- | ext/json/php_json_parser.h | 56 | ||||
| -rw-r--r-- | ext/json/php_json_scanner_defs.h | 2 | ||||
| -rw-r--r-- | ext/json/tests/001.phpt | 6 | ||||
| -rw-r--r-- | ext/json/tests/bug66025.phpt | 19 | ||||
| -rw-r--r-- | ext/json/tests/bug68992.phpt | 29 | ||||
| -rw-r--r-- | ext/json/tests/bug73254.phpt | 21 | ||||
| -rw-r--r-- | ext/json/tests/json_encode_u2028_u2029.phpt | 36 | ||||
| -rw-r--r-- | ext/json/tests/pass001.1.phpt | 6 | ||||
| -rw-r--r-- | ext/json/tests/pass001.1_64bit.phpt | 6 | ||||
| -rw-r--r-- | ext/json/tests/pass001.phpt | 6 |
19 files changed, 1120 insertions, 794 deletions
diff --git a/ext/json/config.m4 b/ext/json/config.m4 index fb87a93992..1411e83faa 100644 --- a/ext/json/config.m4 +++ b/ext/json/config.m4 @@ -15,7 +15,7 @@ PHP_NEW_EXTENSION(json, json_parser.tab.c \ json_scanner.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) - PHP_INSTALL_HEADERS([ext/json], [php_json.h]) + PHP_INSTALL_HEADERS([ext/json], [php_json.h php_json_parser.h php_json_scanner.h]) PHP_ADD_MAKEFILE_FRAGMENT() PHP_SUBST(JSON_SHARED_LIBADD) fi diff --git a/ext/json/json.c b/ext/json/json.c index 01319d5f5b..219fd58cf5 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -33,14 +33,6 @@ #include "php_json_parser.h" #include <zend_exceptions.h> -#include <float.h> -#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) -#define NUM_BUF_SIZE (3 + DBL_MANT_DIG - DBL_MIN_EXP) -#else -#define NUM_BUF_SIZE 1080 -#endif - - static PHP_MINFO_FUNCTION(json); static PHP_FUNCTION(json_encode); static PHP_FUNCTION(json_decode); @@ -117,6 +109,7 @@ static PHP_MINIT_FUNCTION(json) PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE); PHP_JSON_REGISTER_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR); PHP_JSON_REGISTER_CONSTANT("JSON_PRESERVE_ZERO_FRACTION", PHP_JSON_PRESERVE_ZERO_FRACTION); + PHP_JSON_REGISTER_CONSTANT("JSON_UNESCAPED_LINE_TERMINATORS", PHP_JSON_UNESCAPED_LINE_TERMINATORS); /* options for json_decode */ PHP_JSON_REGISTER_CONSTANT("JSON_OBJECT_AS_ARRAY", PHP_JSON_OBJECT_AS_ARRAY); @@ -191,13 +184,23 @@ static PHP_MINFO_FUNCTION(json) } /* }}} */ -PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ +PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */ { - 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; } /* }}} */ -PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ +PHP_JSON_API int php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ { php_json_parser parser; @@ -205,8 +208,11 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, size_t str_l if (php_json_yyparse(&parser)) { JSON_G(error_code) = php_json_parser_error_code(&parser); - RETURN_NULL(); + RETVAL_NULL(); + return FAILURE; } + + return SUCCESS; } /* }}} */ @@ -215,6 +221,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, size_t str_l static PHP_FUNCTION(json_encode) { zval *parameter; + php_json_encoder encoder; smart_str buf = {0}; zend_long options = 0; zend_long depth = PHP_JSON_PARSER_DEFAULT_DEPTH; @@ -223,19 +230,22 @@ static PHP_FUNCTION(json_encode) return; } - JSON_G(error_code) = PHP_JSON_ERROR_NONE; - - JSON_G(encode_max_depth) = (int)depth; - - php_json_encode(&buf, parameter, (int)options); + 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; - if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { + if (encoder.error_code != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { smart_str_free(&buf); - ZVAL_FALSE(return_value); - } else { - smart_str_0(&buf); /* copy? */ - ZVAL_NEW_STR(return_value, buf.s); + RETURN_FALSE; + } + + smart_str_0(&buf); /* copy? */ + if (buf.s) { + RETURN_NEW_STR(buf.s); } + RETURN_EMPTY_STRING(); } /* }}} */ diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 8da2761e99..ca41f383be 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -29,19 +29,14 @@ #include "ext/standard/html.h" #include "zend_smart_str.h" #include "php_json.h" +#include "php_json_encoder.h" #include <zend_exceptions.h> -/* double limits */ -#include <float.h> -#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) -#define PHP_JSON_DOUBLE_MAX_LENGTH (3 + DBL_MANT_DIG - DBL_MIN_EXP) -#else -#define PHP_JSON_DOUBLE_MAX_LENGTH 1080 -#endif - static const char digits[] = "0123456789abcdef"; -static void 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) /* {{{ */ { @@ -53,6 +48,10 @@ static int php_json_determine_array_type(zval *val) /* {{{ */ zend_string *key; zend_ulong index, idx; + if (HT_IS_PACKED(myht) && HT_IS_WITHOUT_HOLES(myht)) { + return PHP_JSON_OUTPUT_ARRAY; + } + idx = 0; ZEND_HASH_FOREACH_KEY(myht, index, key) { if (key) { @@ -80,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; 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); } } @@ -103,10 +102,11 @@ static inline int php_json_is_valid_double(double d) /* {{{ */ static inline void php_json_encode_double(smart_str *buf, double d, int options) /* {{{ */ { size_t len; - char num[PHP_JSON_DOUBLE_MAX_LENGTH]; - php_gcvt(d, (int)EG(precision), '.', 'e', &num[0]); + char num[PHP_DOUBLE_MAX_LENGTH]; + + php_gcvt(d, (int)PG(serialize_precision), '.', 'e', num); len = strlen(num); - if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) { + if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_DOUBLE_MAX_LENGTH - 2) { num[len++] = '.'; num[len++] = '0'; num[len] = '\0'; @@ -115,7 +115,21 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) } /* }}} */ -static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */ +#define PHP_JSON_HASH_APPLY_PROTECTION_INC(_tmp_ht) \ + do { \ + if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \ + ZEND_HASH_INC_APPLY_COUNT(_tmp_ht); \ + } \ + } while (0) + +#define PHP_JSON_HASH_APPLY_PROTECTION_DEC(_tmp_ht) \ + do { \ + if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \ + ZEND_HASH_DEC_APPLY_COUNT(_tmp_ht); \ + } \ + } while (0) + +static int php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { int i, r, need_comma = 0; HashTable *myht; @@ -129,9 +143,9 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ } 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); - return; + return FAILURE; } if (r == PHP_JSON_OUTPUT_ARRAY) { @@ -140,7 +154,7 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ smart_str_appendc(buf, '{'); } - ++JSON_G(encoder_depth); + ++encoder->depth; i = myht ? zend_hash_num_elements(myht) : 0; @@ -153,9 +167,7 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { ZVAL_DEREF(data); tmp_ht = HASH_OF(data); - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_INC_APPLY_COUNT(tmp_ht); - } + PHP_JSON_HASH_APPLY_PROTECTION_INC(tmp_ht); if (r == PHP_JSON_OUTPUT_ARRAY) { if (need_comma) { @@ -165,15 +177,12 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ } php_json_pretty_print_char(buf, options, '\n'); - php_json_pretty_print_indent(buf, options); - php_json_encode(buf, data, options); + php_json_pretty_print_indent(buf, options, encoder); } else if (r == PHP_JSON_OUTPUT_OBJECT) { if (key) { - if (ZSTR_VAL(key)[0] == '\0' && Z_TYPE_P(val) == IS_OBJECT) { + if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) { /* Skip protected and private members. */ - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); - } + PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht); continue; } @@ -184,14 +193,10 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ } php_json_pretty_print_char(buf, options, '\n'); - php_json_pretty_print_indent(buf, options); - - php_json_escape_string(buf, ZSTR_VAL(key), ZSTR_LEN(key), options & ~PHP_JSON_NUMERIC_CHECK); - smart_str_appendc(buf, ':'); - - php_json_pretty_print_char(buf, options, ' '); + php_json_pretty_print_indent(buf, options, encoder); - php_json_encode(buf, data, options); + php_json_escape_string(buf, ZSTR_VAL(key), ZSTR_LEN(key), + options & ~PHP_JSON_NUMERIC_CHECK, encoder); } else { if (need_comma) { smart_str_appendc(buf, ','); @@ -200,34 +205,39 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ } 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_append_long(buf, (zend_long) index); smart_str_appendc(buf, '"'); - smart_str_appendc(buf, ':'); - - php_json_pretty_print_char(buf, options, ' '); - - php_json_encode(buf, data, options); } + + smart_str_appendc(buf, ':'); + php_json_pretty_print_char(buf, options, ' '); } - if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { - ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); + 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); + return FAILURE; } + + PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht); } ZEND_HASH_FOREACH_END(); } - if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) { - JSON_G(error_code) = PHP_JSON_ERROR_DEPTH; + if (encoder->depth > encoder->max_depth) { + encoder->error_code = PHP_JSON_ERROR_DEPTH; + if (!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { + return FAILURE; + } } - --JSON_G(encoder_depth); + --encoder->depth; /* Only keep closing bracket on same line for empty arrays/objects */ if (need_comma) { 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) { @@ -235,6 +245,8 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ } else { smart_str_appendc(buf, '}'); } + + return SUCCESS; } /* }}} */ @@ -275,7 +287,9 @@ static int php_json_utf8_to_utf16(unsigned short *utf16, char utf8[], size_t len } /* }}} */ -static void 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; unsigned int us; @@ -283,7 +297,7 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti if (len == 0) { smart_str_appendl(buf, "\"\"", 2); - return; + return SUCCESS; } if (options & PHP_JSON_NUMERIC_CHECK) { @@ -294,10 +308,10 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) { if (type == IS_LONG) { smart_str_append_long(buf, p); - return; + return SUCCESS; } else if (type == IS_DOUBLE && php_json_is_valid_double(d)) { php_json_encode_double(buf, d, options); - return; + return SUCCESS; } } @@ -306,9 +320,11 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti if (options & PHP_JSON_UNESCAPED_UNICODE) { /* validate UTF-8 string first */ if (php_json_utf8_to_utf16(NULL, s, len) < 0) { - JSON_G(error_code) = PHP_JSON_ERROR_UTF8; - smart_str_appendl(buf, "null", 4); - return; + encoder->error_code = PHP_JSON_ERROR_UTF8; + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; } } @@ -321,16 +337,27 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti do { us = (unsigned char)s[pos]; - if (us >= 0x80 && !(options & PHP_JSON_UNESCAPED_UNICODE)) { + if (us >= 0x80 && (!(options & PHP_JSON_UNESCAPED_UNICODE) || us == 0xE2)) { /* UTF-8 character */ us = php_next_utf8_char((const unsigned char *)s, len, &pos, &status); if (status != SUCCESS) { if (buf->s) { ZSTR_LEN(buf->s) = checkpoint; } - JSON_G(error_code) = PHP_JSON_ERROR_UTF8; - smart_str_appendl(buf, "null", 4); - return; + encoder->error_code = PHP_JSON_ERROR_UTF8; + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; + } + /* Escape U+2028/U+2029 line terminators, UNLESS both + JSON_UNESCAPED_UNICODE and + JSON_UNESCAPED_LINE_TERMINATORS were provided */ + if ((options & PHP_JSON_UNESCAPED_UNICODE) + && ((options & PHP_JSON_UNESCAPED_LINE_TERMINATORS) + || us < 0x2028 || us > 0x2029)) { + smart_str_appendl(buf, &s[pos - 3], 3); + continue; } /* From http://en.wikipedia.org/wiki/UTF16 */ if (us >= 0x10000) { @@ -440,15 +467,17 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti } while (pos < len); smart_str_appendc(buf, '"'); + + return SUCCESS; } /* }}} */ -static void 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); zval retval, fname; HashTable* myht; - int origin_error_code; + int return_code; if (Z_TYPE_P(val) == IS_ARRAY) { myht = Z_ARRVAL_P(val); @@ -457,48 +486,56 @@ static void php_json_encode_serializable_object(smart_str *buf, zval *val, int o } if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) { - JSON_G(error_code) = PHP_JSON_ERROR_RECURSION; - smart_str_appendl(buf, "null", 4); - return; + encoder->error_code = PHP_JSON_ERROR_RECURSION; + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; } 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 (!EG(exception)) { zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name)); } - smart_str_appendl(buf, "null", sizeof("null") - 1); zval_ptr_dtor(&fname); - return; + + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; } - JSON_G(error_code) = origin_error_code; if (EG(exception)) { /* Error already raised */ zval_ptr_dtor(&retval); zval_ptr_dtor(&fname); - smart_str_appendl(buf, "null", sizeof("null") - 1); - return; + + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; } if ((Z_TYPE(retval) == IS_OBJECT) && (Z_OBJ(retval) == Z_OBJ_P(val))) { /* 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 { /* 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(&fname); + + return return_code; } /* }}} */ -void 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: switch (Z_TYPE_P(val)) @@ -522,36 +559,35 @@ again: if (php_json_is_valid_double(Z_DVAL_P(val))) { php_json_encode_double(buf, Z_DVAL_P(val), options); } 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'); } break; case IS_STRING: - php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options); - break; + return php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options, encoder); case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) { - php_json_encode_serializable_object(buf, val, options); - break; + return php_json_encode_serializable_object(buf, val, options, encoder); } /* fallthrough -- Non-serializable object */ case IS_ARRAY: - php_json_encode_array(buf, val, options); - break; + return php_json_encode_array(buf, val, options, encoder); case IS_REFERENCE: val = Z_REFVAL_P(val); goto again; default: - JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE; - smart_str_appendl(buf, "null", 4); - break; + encoder->error_code = PHP_JSON_ERROR_UNSUPPORTED_TYPE; + if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) { + smart_str_appendl(buf, "null", 4); + } + return FAILURE; } - return; + return SUCCESS; } /* }}} */ diff --git a/ext/json/json_parser.tab.c b/ext/json/json_parser.tab.c index b01d031f14..b4f426e07a 100644 --- a/ext/json/json_parser.tab.c +++ b/ext/json/json_parser.tab.c @@ -98,6 +98,14 @@ int json_yydebug = 1; #define PHP_JSON_USE_1(uvr, uv1) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1) #define PHP_JSON_USE_2(uvr, uv1, uv2) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1); PHP_JSON_USE(uv2) +#define PHP_JSON_DEPTH_DEC --parser->depth +#define PHP_JSON_DEPTH_INC \ + if (parser->max_depth && parser->depth >= parser->max_depth) { \ + parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ + YYERROR; \ + } \ + ++parser->depth + @@ -131,8 +139,8 @@ int json_yydebug = 1; /* In a future release of Bison, this section will be replaced by #include "json_parser.tab.h". */ -#ifndef YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED -# define YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED +#ifndef YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED +# define YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -193,7 +201,7 @@ typedef union YYSTYPE YYSTYPE; int php_json_yyparse (php_json_parser *parser); -#endif /* !YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */ +#endif /* !YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ @@ -201,20 +209,9 @@ int php_json_yyparse (php_json_parser *parser); /* Unqualified %code blocks. */ -int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); -void php_json_yyerror(php_json_parser *parser, char const *msg); -void php_json_parser_object_init(php_json_parser *parser, zval *object); -int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue); -void php_json_parser_array_init(zval *object); -void php_json_parser_array_append(zval *array, zval *zvalue); +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); +static void php_json_yyerror(php_json_parser *parser, char const *msg); -#define PHP_JSON_DEPTH_DEC --parser->depth -#define PHP_JSON_DEPTH_INC \ - if (parser->max_depth && parser->depth >= parser->max_depth) { \ - parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ - YYERROR; \ - } \ - ++parser->depth @@ -514,10 +511,10 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 92, 92, 98, 105, 105, 113, 114, 123, 126, - 130, 136, 142, 149, 154, 161, 161, 169, 170, 179, - 182, 186, 191, 196, 203, 204, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 221 + 0, 89, 89, 95, 103, 102, 120, 121, 130, 133, + 137, 144, 151, 158, 163, 171, 170, 188, 189, 198, + 201, 205, 210, 215, 222, 223, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 240 }; #endif @@ -1465,15 +1462,23 @@ yyreduce: case 4: - { PHP_JSON_DEPTH_INC; } + { + PHP_JSON_DEPTH_INC; + if (parser->methods.object_start && FAILURE == parser->methods.object_start(parser)) { + YYERROR; + } + } break; case 5: { + ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value)); PHP_JSON_DEPTH_DEC; - (yyval.value) = (yyvsp[-1].value); + if (parser->methods.object_end && FAILURE == parser->methods.object_end(parser, &(yyval.value))) { + YYERROR; + } } break; @@ -1490,7 +1495,7 @@ yyreduce: case 8: { - php_json_parser_object_init(parser, &(yyval.value)); + parser->methods.object_create(parser, &(yyval.value)); } break; @@ -1498,9 +1503,10 @@ yyreduce: case 10: { - php_json_parser_object_init(parser, &(yyval.value)); - if (php_json_parser_object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) + parser->methods.object_create(parser, &(yyval.value)); + if (parser->methods.object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) { YYERROR; + } } break; @@ -1508,8 +1514,9 @@ yyreduce: case 11: { - if (php_json_parser_object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) + if (parser->methods.object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) { YYERROR; + } ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value)); } @@ -1542,15 +1549,23 @@ yyreduce: case 15: - { PHP_JSON_DEPTH_INC; } + { + PHP_JSON_DEPTH_INC; + if (parser->methods.array_start && FAILURE == parser->methods.array_start(parser)) { + YYERROR; + } + } break; case 16: { - PHP_JSON_DEPTH_DEC; ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value)); + PHP_JSON_DEPTH_DEC; + if (parser->methods.array_end && FAILURE == parser->methods.array_end(parser, &(yyval.value))) { + YYERROR; + } } break; @@ -1567,7 +1582,7 @@ yyreduce: case 19: { - php_json_parser_array_init(&(yyval.value)); + parser->methods.array_create(parser, &(yyval.value)); } break; @@ -1575,8 +1590,8 @@ yyreduce: case 21: { - php_json_parser_array_init(&(yyval.value)); - php_json_parser_array_append(&(yyval.value), &(yyvsp[0].value)); + parser->methods.array_create(parser, &(yyval.value)); + parser->methods.array_append(parser, &(yyval.value), &(yyvsp[0].value)); } break; @@ -1584,7 +1599,7 @@ yyreduce: case 22: { - php_json_parser_array_append(&(yyvsp[-2].value), &(yyvsp[0].value)); + parser->methods.array_append(parser, &(yyvsp[-2].value), &(yyvsp[0].value)); ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value)); } @@ -1839,40 +1854,34 @@ yyreturn: /* Functions */ -void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth) +static int php_json_parser_array_create(php_json_parser *parser, zval *array) { - memset(parser, 0, sizeof(php_json_parser)); - php_json_scanner_init(&parser->scanner, str, str_len, options); - parser->depth = 1; - parser->max_depth = max_depth; - parser->return_value = return_value; + return array_init(array); } -php_json_error_code php_json_parser_error_code(php_json_parser *parser) +static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue) { - return parser->scanner.errcode; + zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); + return SUCCESS; } -void php_json_parser_object_init(php_json_parser *parser, zval *object) +static int php_json_parser_object_create(php_json_parser *parser, zval *object) { if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) { - array_init(object); + return array_init(object); } else { - object_init(object); + return object_init(object); } } -int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) +static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) { /* if JSON_OBJECT_AS_ARRAY is set */ if (Z_TYPE_P(object) == IS_ARRAY) { zend_symtable_update(Z_ARRVAL_P(object), key, zvalue); } else { zval zkey; - if (ZSTR_LEN(key) == 0) { - zend_string_release(key); - key = zend_string_init("_empty_", sizeof("_empty_") - 1, 0); - } else if (ZSTR_VAL(key)[0] == '\0') { + if (ZSTR_LEN(key) > 0 && ZSTR_VAL(key)[0] == '\0') { parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME; zend_string_release(key); zval_dtor(zvalue); @@ -1880,7 +1889,7 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st return FAILURE; } ZVAL_NEW_STR(&zkey, key); - zend_std_write_property(object, &zkey, zvalue, NULL); + zend_std_write_property(object, &zkey, zvalue, NULL); if (Z_REFCOUNTED_P(zvalue)) { Z_DELREF_P(zvalue); @@ -1891,26 +1900,71 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st return SUCCESS; } -void php_json_parser_array_init(zval *array) -{ - array_init(array); -} - -void php_json_parser_array_append(zval *array, zval *zvalue) -{ - zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); -} - -int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) { int token = php_json_scan(&parser->scanner); value->value = parser->scanner.value; return token; } -void php_json_yyerror(php_json_parser *parser, char const *msg) +static void php_json_yyerror(php_json_parser *parser, char const *msg) { if (!parser->scanner.errcode) { parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; } } + +PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser) +{ + return parser->scanner.errcode; +} + +static const php_json_parser_methods default_parser_methods = +{ + php_json_parser_array_create, + php_json_parser_array_append, + NULL, + NULL, + php_json_parser_object_create, + php_json_parser_object_update, + NULL, + NULL, +}; + +PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth, + const php_json_parser_methods *parser_methods) +{ + memset(parser, 0, sizeof(php_json_parser)); + php_json_scanner_init(&parser->scanner, str, str_len, options); + parser->depth = 1; + parser->max_depth = max_depth; + parser->return_value = return_value; + memcpy(&parser->methods, parser_methods, sizeof(php_json_parser_methods)); +} + +PHP_JSON_API void php_json_parser_init(php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth) +{ + php_json_parser_init_ex( + parser, + return_value, + str, + str_len, + options, + max_depth, + &default_parser_methods); +} + +PHP_JSON_API int php_json_parse(php_json_parser *parser) +{ + return php_json_yyparse(parser); +} diff --git a/ext/json/json_parser.tab.h b/ext/json/json_parser.tab.h index 56bc2c40c9..4349b70406 100644 --- a/ext/json/json_parser.tab.h +++ b/ext/json/json_parser.tab.h @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED -# define YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED +#ifndef YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED +# define YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -92,4 +92,4 @@ typedef union YYSTYPE YYSTYPE; int php_json_yyparse (php_json_parser *parser); -#endif /* !YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */ +#endif /* !YY_PHP_JSON_YY_HOME_DMITRY_PHP_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */ diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index 2f37641c0c..43d941b56c 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -36,6 +36,14 @@ int json_yydebug = 1; #define PHP_JSON_USE_1(uvr, uv1) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1) #define PHP_JSON_USE_2(uvr, uv1, uv2) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1); PHP_JSON_USE(uv2) +#define PHP_JSON_DEPTH_DEC --parser->depth +#define PHP_JSON_DEPTH_INC \ + if (parser->max_depth && parser->depth >= parser->max_depth) { \ + parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ + YYERROR; \ + } \ + ++parser->depth + } %pure-parser @@ -70,20 +78,9 @@ int json_yydebug = 1; %destructor { zend_string_release($$.key); zval_dtor(&$$.val); } <pair> %code { -int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); -void php_json_yyerror(php_json_parser *parser, char const *msg); -void php_json_parser_object_init(php_json_parser *parser, zval *object); -int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue); -void php_json_parser_array_init(zval *object); -void php_json_parser_array_append(zval *array, zval *zvalue); +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); +static void php_json_yyerror(php_json_parser *parser, char const *msg); -#define PHP_JSON_DEPTH_DEC --parser->depth -#define PHP_JSON_DEPTH_INC \ - if (parser->max_depth && parser->depth >= parser->max_depth) { \ - parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ - YYERROR; \ - } \ - ++parser->depth } %% /* Rules */ @@ -102,10 +99,20 @@ start: ; object: - '{' { PHP_JSON_DEPTH_INC; } members object_end + '{' { + PHP_JSON_DEPTH_INC; + if (parser->methods.object_start && FAILURE == parser->methods.object_start(parser)) { + YYERROR; + } + } + members object_end + { + ZVAL_COPY_VALUE(&$$, &$3); PHP_JSON_DEPTH_DEC; - $$ = $3; + if (parser->methods.object_end && FAILURE == parser->methods.object_end(parser, &$$)) { + YYERROR; + } } ; @@ -121,7 +128,7 @@ object_end: members: /* empty */ { - php_json_parser_object_init(parser, &$$); + parser->methods.object_create(parser, &$$); } | member ; @@ -129,14 +136,16 @@ members: member: pair { - php_json_parser_object_init(parser, &$$); - if (php_json_parser_object_update(parser, &$$, $1.key, &$1.val) == FAILURE) + parser->methods.object_create(parser, &$$); + if (parser->methods.object_update(parser, &$$, $1.key, &$1.val) == FAILURE) { YYERROR; + } } | member ',' pair { - if (php_json_parser_object_update(parser, &$1, $3.key, &$3.val) == FAILURE) + if (parser->methods.object_update(parser, &$1, $3.key, &$3.val) == FAILURE) { YYERROR; + } ZVAL_COPY_VALUE(&$$, &$1); } | member errlex @@ -158,10 +167,20 @@ pair: ; array: - '[' { PHP_JSON_DEPTH_INC; } elements array_end + '[' + { + PHP_JSON_DEPTH_INC; + if (parser->methods.array_start && FAILURE == parser->methods.array_start(parser)) { + YYERROR; + } + } + elements array_end { - PHP_JSON_DEPTH_DEC; ZVAL_COPY_VALUE(&$$, &$3); + PHP_JSON_DEPTH_DEC; + if (parser->methods.array_end && FAILURE == parser->methods.array_end(parser, &$$)) { + YYERROR; + } } ; @@ -177,7 +196,7 @@ array_end: elements: /* empty */ { - php_json_parser_array_init(&$$); + parser->methods.array_create(parser, &$$); } | element ; @@ -185,12 +204,12 @@ elements: element: value { - php_json_parser_array_init(&$$); - php_json_parser_array_append(&$$, &$1); + parser->methods.array_create(parser, &$$); + parser->methods.array_append(parser, &$$, &$1); } | element ',' value { - php_json_parser_array_append(&$1, &$3); + parser->methods.array_append(parser, &$1, &$3); ZVAL_COPY_VALUE(&$$, &$1); } | element errlex @@ -224,43 +243,37 @@ errlex: YYERROR; } ; - + %% /* Functions */ -void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth) +static int php_json_parser_array_create(php_json_parser *parser, zval *array) { - memset(parser, 0, sizeof(php_json_parser)); - php_json_scanner_init(&parser->scanner, str, str_len, options); - parser->depth = 1; - parser->max_depth = max_depth; - parser->return_value = return_value; + return array_init(array); } -php_json_error_code php_json_parser_error_code(php_json_parser *parser) +static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue) { - return parser->scanner.errcode; + zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); + return SUCCESS; } -void php_json_parser_object_init(php_json_parser *parser, zval *object) +static int php_json_parser_object_create(php_json_parser *parser, zval *object) { if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) { - array_init(object); + return array_init(object); } else { - object_init(object); + return object_init(object); } } -int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) +static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) { /* if JSON_OBJECT_AS_ARRAY is set */ if (Z_TYPE_P(object) == IS_ARRAY) { zend_symtable_update(Z_ARRVAL_P(object), key, zvalue); } else { zval zkey; - if (ZSTR_LEN(key) == 0) { - zend_string_release(key); - key = zend_string_init("_empty_", sizeof("_empty_") - 1, 0); - } else if (ZSTR_VAL(key)[0] == '\0') { + if (ZSTR_LEN(key) > 0 && ZSTR_VAL(key)[0] == '\0') { parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME; zend_string_release(key); zval_dtor(zvalue); @@ -268,7 +281,7 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st return FAILURE; } ZVAL_NEW_STR(&zkey, key); - zend_std_write_property(object, &zkey, zvalue, NULL); + zend_std_write_property(object, &zkey, zvalue, NULL); if (Z_REFCOUNTED_P(zvalue)) { Z_DELREF_P(zvalue); @@ -279,26 +292,71 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st return SUCCESS; } -void php_json_parser_array_init(zval *array) -{ - array_init(array); -} - -void php_json_parser_array_append(zval *array, zval *zvalue) -{ - zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); -} - -int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) +static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) { int token = php_json_scan(&parser->scanner); value->value = parser->scanner.value; return token; } -void php_json_yyerror(php_json_parser *parser, char const *msg) +static void php_json_yyerror(php_json_parser *parser, char const *msg) { if (!parser->scanner.errcode) { parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; } } + +PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser) +{ + return parser->scanner.errcode; +} + +static const php_json_parser_methods default_parser_methods = +{ + php_json_parser_array_create, + php_json_parser_array_append, + NULL, + NULL, + php_json_parser_object_create, + php_json_parser_object_update, + NULL, + NULL, +}; + +PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth, + const php_json_parser_methods *parser_methods) +{ + memset(parser, 0, sizeof(php_json_parser)); + php_json_scanner_init(&parser->scanner, str, str_len, options); + parser->depth = 1; + parser->max_depth = max_depth; + parser->return_value = return_value; + memcpy(&parser->methods, parser_methods, sizeof(php_json_parser_methods)); +} + +PHP_JSON_API void php_json_parser_init(php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth) +{ + php_json_parser_init_ex( + parser, + return_value, + str, + str_len, + options, + max_depth, + &default_parser_methods); +} + +PHP_JSON_API int php_json_parse(php_json_parser *parser) +{ + return php_json_yyparse(parser); +} diff --git a/ext/json/json_scanner.c b/ext/json/json_scanner.c index ee46a13198..cc9c0c6bb8 100644 --- a/ext/json/json_scanner.c +++ b/ext/json/json_scanner.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.14.3 */ +/* Generated by re2c 0.13.5 */ /* +----------------------------------------------------------------------+ | PHP Version 7 | @@ -147,46 +147,47 @@ yyc_JS: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + yych = *YYCURSOR; if (yych <= ']') { if (yych <= '"') { if (yych <= '\f') { if (yych <= 0x08) { - if (yych >= 0x01) goto yy5; + if (yych >= 0x01) goto yy4; } else { - if (yych <= '\t') goto yy7; - if (yych <= '\n') goto yy9; - goto yy5; + if (yych <= '\t') goto yy6; + if (yych <= '\n') goto yy8; + goto yy4; } } else { if (yych <= 0x1F) { - if (yych <= '\r') goto yy10; - goto yy5; + if (yych <= '\r') goto yy9; + goto yy4; } else { - if (yych <= ' ') goto yy11; - if (yych <= '!') goto yy12; - goto yy14; + if (yych <= ' ') goto yy10; + if (yych <= '!') goto yy11; + goto yy13; } } } else { if (yych <= '0') { if (yych <= ',') { - if (yych <= '+') goto yy12; - goto yy16; + if (yych <= '+') goto yy11; + goto yy15; } else { - if (yych <= '-') goto yy18; - if (yych <= '/') goto yy12; - goto yy19; + if (yych <= '-') goto yy17; + if (yych <= '/') goto yy11; + goto yy18; } } else { if (yych <= 'Z') { - if (yych <= '9') goto yy21; - if (yych <= ':') goto yy22; - goto yy12; + if (yych <= '9') goto yy20; + if (yych <= ':') goto yy21; + goto yy11; } else { - if (yych <= '[') goto yy24; - if (yych <= '\\') goto yy12; - goto yy26; + if (yych <= '[') goto yy23; + if (yych <= '\\') goto yy11; + goto yy25; } } } @@ -194,41 +195,41 @@ yyc_JS: if (yych <= '}') { if (yych <= 's') { if (yych <= 'f') { - if (yych <= 'e') goto yy12; - goto yy28; + if (yych <= 'e') goto yy11; + goto yy27; } else { - if (yych == 'n') goto yy29; - goto yy12; + if (yych == 'n') goto yy28; + goto yy11; } } else { if (yych <= 'z') { - if (yych <= 't') goto yy30; - goto yy12; + if (yych <= 't') goto yy29; + goto yy11; } else { - if (yych <= '{') goto yy31; - if (yych <= '|') goto yy12; - goto yy33; + if (yych <= '{') goto yy30; + if (yych <= '|') goto yy11; + goto yy32; } } } else { if (yych <= 0xEC) { if (yych <= 0xC1) { - if (yych <= 0x7F) goto yy12; - goto yy35; + if (yych <= 0x7F) goto yy11; + goto yy34; } else { - if (yych <= 0xDF) goto yy37; - if (yych <= 0xE0) goto yy38; - goto yy39; + if (yych <= 0xDF) goto yy36; + if (yych <= 0xE0) goto yy37; + goto yy38; } } else { if (yych <= 0xF0) { - if (yych <= 0xED) goto yy40; - if (yych <= 0xEF) goto yy41; - goto yy42; + if (yych <= 0xED) goto yy39; + if (yych <= 0xEF) goto yy40; + goto yy41; } else { - if (yych <= 0xF3) goto yy43; - if (yych <= 0xF4) goto yy44; - goto yy35; + if (yych <= 0xF3) goto yy42; + if (yych <= 0xF4) goto yy43; + goto yy34; } } } @@ -242,36 +243,36 @@ yyc_JS: return PHP_JSON_T_ERROR; } } -yy5: +yy4: ++YYCURSOR; { s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } -yy7: +yy6: ++YYCURSOR; yych = *YYCURSOR; - goto yy82; -yy8: + goto yy81; +yy7: { goto std; } +yy8: + yych = *++YYCURSOR; + goto yy7; yy9: yych = *++YYCURSOR; - goto yy8; + if (yych == '\n') goto yy82; + goto yy81; yy10: yych = *++YYCURSOR; - if (yych == '\n') goto yy83; - goto yy82; + goto yy81; yy11: - yych = *++YYCURSOR; - goto yy82; -yy12: ++YYCURSOR; -yy13: +yy12: { s->errcode = PHP_JSON_ERROR_SYNTAX; return PHP_JSON_T_ERROR; } -yy14: +yy13: ++YYCURSOR; { s->str_start = s->cursor; @@ -279,25 +280,25 @@ yy14: PHP_JSON_CONDITION_SET(STR_P1); PHP_JSON_CONDITION_GOTO(STR_P1); } -yy16: +yy15: ++YYCURSOR; { return ','; } -yy18: +yy17: yych = *++YYCURSOR; - if (yych <= '/') goto yy13; - if (yych <= '0') goto yy80; - if (yych <= '9') goto yy70; - goto yy13; -yy19: + if (yych <= '/') goto yy12; + if (yych <= '0') goto yy79; + if (yych <= '9') goto yy69; + goto yy12; +yy18: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'D') { - if (yych == '.') goto yy72; + if (yych == '.') goto yy71; } else { - if (yych <= 'E') goto yy73; - if (yych == 'e') goto yy73; + if (yych <= 'E') goto yy72; + if (yych == 'e') goto yy72; } -yy20: +yy19: { zend_bool bigint = 0, negative = s->token[0] == '-'; size_t digits = (size_t) (s->cursor - s->token - negative); @@ -322,305 +323,305 @@ yy20: return PHP_JSON_T_DOUBLE; } } -yy21: +yy20: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy71; -yy22: + goto yy70; +yy21: ++YYCURSOR; { return ':'; } -yy24: +yy23: ++YYCURSOR; { return '['; } -yy26: +yy25: ++YYCURSOR; { return ']'; } +yy27: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'a') goto yy64; + goto yy12; yy28: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'a') goto yy65; - goto yy13; + if (yych == 'u') goto yy60; + goto yy12; yy29: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'u') goto yy61; - goto yy13; + if (yych == 'r') goto yy56; + goto yy12; yy30: - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'r') goto yy57; - goto yy13; -yy31: ++YYCURSOR; { return '{'; } -yy33: +yy32: ++YYCURSOR; { return '}'; } -yy35: +yy34: ++YYCURSOR; -yy36: +yy35: { s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } -yy37: +yy36: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy36; - if (yych <= 0xBF) goto yy48; - goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych <= 0xBF) goto yy47; + goto yy35; +yy37: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x9F) goto yy35; + if (yych <= 0xBF) goto yy55; + goto yy35; yy38: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x9F) goto yy36; - if (yych <= 0xBF) goto yy56; - goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych <= 0xBF) goto yy54; + goto yy35; yy39: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy36; - if (yych <= 0xBF) goto yy55; - goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych <= 0x9F) goto yy53; + goto yy35; yy40: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy36; - if (yych <= 0x9F) goto yy54; - goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych <= 0xBF) goto yy52; + goto yy35; yy41: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy36; - if (yych <= 0xBF) goto yy53; - goto yy36; + if (yych <= 0x8F) goto yy35; + if (yych <= 0xBF) goto yy50; + goto yy35; yy42: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x8F) goto yy36; - if (yych <= 0xBF) goto yy51; - goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych <= 0xBF) goto yy48; + goto yy35; yy43: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy36; - if (yych <= 0xBF) goto yy49; - goto yy36; -yy44: - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy36; - if (yych >= 0x90) goto yy36; + if (yych <= 0x7F) goto yy35; + if (yych >= 0x90) goto yy35; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy47; -yy46: + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy46; +yy45: YYCURSOR = YYMARKER; if (yyaccept <= 1) { - if (yyaccept == 0) { - goto yy20; + if (yyaccept <= 0) { + goto yy19; } else { - goto yy13; + goto yy12; } } else { - if (yyaccept == 2) { - goto yy36; + if (yyaccept <= 2) { + goto yy35; } else { - goto yy77; + goto yy76; } } +yy46: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy45; + if (yych >= 0xC0) goto yy45; yy47: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych >= 0xC0) goto yy46; + goto yy12; yy48: yych = *++YYCURSOR; - goto yy13; -yy49: + if (yych <= 0x7F) goto yy45; + if (yych >= 0xC0) goto yy45; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych >= 0xC0) goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; +yy50: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; -yy51: + if (yych <= 0x7F) goto yy45; + if (yych >= 0xC0) goto yy45; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych >= 0xC0) goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; +yy52: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; yy53: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; yy54: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; yy55: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; + if (yych <= 0x7F) goto yy45; + if (yych <= 0xBF) goto yy47; + goto yy45; yy56: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy46; - if (yych <= 0xBF) goto yy48; - goto yy46; -yy57: + if (yych != 'u') goto yy45; yych = *++YYCURSOR; - if (yych != 'u') goto yy46; - yych = *++YYCURSOR; - if (yych != 'e') goto yy46; + if (yych != 'e') goto yy45; ++YYCURSOR; { ZVAL_TRUE(&s->value); return PHP_JSON_T_TRUE; } -yy61: +yy60: yych = *++YYCURSOR; - if (yych != 'l') goto yy46; + if (yych != 'l') goto yy45; yych = *++YYCURSOR; - if (yych != 'l') goto yy46; + if (yych != 'l') goto yy45; ++YYCURSOR; { ZVAL_NULL(&s->value); return PHP_JSON_T_NUL; } -yy65: +yy64: yych = *++YYCURSOR; - if (yych != 'l') goto yy46; + if (yych != 'l') goto yy45; yych = *++YYCURSOR; - if (yych != 's') goto yy46; + if (yych != 's') goto yy45; yych = *++YYCURSOR; - if (yych != 'e') goto yy46; + if (yych != 'e') goto yy45; ++YYCURSOR; { ZVAL_FALSE(&s->value); return PHP_JSON_T_FALSE; } -yy70: +yy69: yyaccept = 0; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; -yy71: +yy70: if (yybm[0+yych] & 64) { - goto yy70; + goto yy69; } if (yych <= 'D') { - if (yych != '.') goto yy20; + if (yych != '.') goto yy19; } else { - if (yych <= 'E') goto yy73; - if (yych == 'e') goto yy73; - goto yy20; + if (yych <= 'E') goto yy72; + if (yych == 'e') goto yy72; + goto yy19; } -yy72: +yy71: yych = *++YYCURSOR; - if (yych <= '/') goto yy46; - if (yych <= '9') goto yy78; - goto yy46; -yy73: + if (yych <= '/') goto yy45; + if (yych <= '9') goto yy77; + goto yy45; +yy72: yych = *++YYCURSOR; if (yych <= ',') { - if (yych != '+') goto yy46; + if (yych != '+') goto yy45; } else { - if (yych <= '-') goto yy74; - if (yych <= '/') goto yy46; - if (yych <= '9') goto yy75; - goto yy46; + if (yych <= '-') goto yy73; + if (yych <= '/') goto yy45; + if (yych <= '9') goto yy74; + goto yy45; } -yy74: +yy73: yych = *++YYCURSOR; - if (yych <= '/') goto yy46; - if (yych >= ':') goto yy46; -yy75: + if (yych <= '/') goto yy45; + if (yych >= ':') goto yy45; +yy74: ++YYCURSOR; yych = *YYCURSOR; - if (yych <= '/') goto yy77; - if (yych <= '9') goto yy75; -yy77: + if (yych <= '/') goto yy76; + if (yych <= '9') goto yy74; +yy76: { ZVAL_DOUBLE(&s->value, zend_strtod((char *) s->token, NULL)); return PHP_JSON_T_DOUBLE; } -yy78: +yy77: yyaccept = 3; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; if (yych <= 'D') { - if (yych <= '/') goto yy77; - if (yych <= '9') goto yy78; - goto yy77; + if (yych <= '/') goto yy76; + if (yych <= '9') goto yy77; + goto yy76; } else { - if (yych <= 'E') goto yy73; - if (yych == 'e') goto yy73; - goto yy77; + if (yych <= 'E') goto yy72; + if (yych == 'e') goto yy72; + goto yy76; } -yy80: +yy79: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'D') { - if (yych == '.') goto yy72; - goto yy20; + if (yych == '.') goto yy71; + goto yy19; } else { - if (yych <= 'E') goto yy73; - if (yych == 'e') goto yy73; - goto yy20; + if (yych <= 'E') goto yy72; + if (yych == 'e') goto yy72; + goto yy19; } -yy81: +yy80: ++YYCURSOR; yych = *YYCURSOR; -yy82: +yy81: if (yybm[0+yych] & 128) { - goto yy81; + goto yy80; } - goto yy8; -yy83: + goto yy7; +yy82: ++YYCURSOR; yych = *YYCURSOR; - goto yy8; + goto yy7; } /* *********************************** */ yyc_STR_P1: yych = *YYCURSOR; if (yych <= 0xDF) { if (yych <= '[') { - if (yych <= 0x1F) goto yy86; - if (yych == '"') goto yy90; - goto yy88; + if (yych <= 0x1F) goto yy85; + if (yych == '"') goto yy89; + goto yy87; } else { - if (yych <= '\\') goto yy92; - if (yych <= 0x7F) goto yy88; - if (yych <= 0xC1) goto yy94; - goto yy96; + if (yych <= '\\') goto yy91; + if (yych <= 0x7F) goto yy87; + if (yych <= 0xC1) goto yy93; + goto yy95; } } else { if (yych <= 0xEF) { - if (yych <= 0xE0) goto yy97; - if (yych <= 0xEC) goto yy98; - if (yych <= 0xED) goto yy99; - goto yy100; + if (yych <= 0xE0) goto yy96; + if (yych <= 0xEC) goto yy97; + if (yych <= 0xED) goto yy98; + goto yy99; } else { - if (yych <= 0xF0) goto yy101; - if (yych <= 0xF3) goto yy102; - if (yych <= 0xF4) goto yy103; - goto yy94; + if (yych <= 0xF0) goto yy100; + if (yych <= 0xF3) goto yy101; + if (yych <= 0xF4) goto yy102; + goto yy93; } } -yy86: +yy85: ++YYCURSOR; { s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } -yy88: +yy87: ++YYCURSOR; -yy89: +yy88: { PHP_JSON_CONDITION_GOTO(STR_P1); } -yy90: +yy89: ++YYCURSOR; { zend_string *str; @@ -644,392 +645,392 @@ yy90: return PHP_JSON_T_STRING; } } -yy92: +yy91: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'e') { if (yych <= '/') { - if (yych == '"') goto yy116; - if (yych >= '/') goto yy116; + if (yych == '"') goto yy115; + if (yych >= '/') goto yy115; } else { if (yych <= '\\') { - if (yych >= '\\') goto yy116; + if (yych >= '\\') goto yy115; } else { - if (yych == 'b') goto yy116; + if (yych == 'b') goto yy115; } } } else { if (yych <= 'q') { - if (yych <= 'f') goto yy116; - if (yych == 'n') goto yy116; + if (yych <= 'f') goto yy115; + if (yych == 'n') goto yy115; } else { if (yych <= 's') { - if (yych <= 'r') goto yy116; + if (yych <= 'r') goto yy115; } else { - if (yych <= 't') goto yy116; - if (yych <= 'u') goto yy118; + if (yych <= 't') goto yy115; + if (yych <= 'u') goto yy117; } } } -yy93: +yy92: { s->errcode = PHP_JSON_ERROR_SYNTAX; return PHP_JSON_T_ERROR; } -yy94: +yy93: ++YYCURSOR; -yy95: +yy94: { s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } -yy96: +yy95: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy95; - if (yych <= 0xBF) goto yy107; - goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych <= 0xBF) goto yy106; + goto yy94; +yy96: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x9F) goto yy94; + if (yych <= 0xBF) goto yy114; + goto yy94; yy97: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x9F) goto yy95; - if (yych <= 0xBF) goto yy115; - goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych <= 0xBF) goto yy113; + goto yy94; yy98: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy95; - if (yych <= 0xBF) goto yy114; - goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych <= 0x9F) goto yy112; + goto yy94; yy99: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy95; - if (yych <= 0x9F) goto yy113; - goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych <= 0xBF) goto yy111; + goto yy94; yy100: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy95; - if (yych <= 0xBF) goto yy112; - goto yy95; + if (yych <= 0x8F) goto yy94; + if (yych <= 0xBF) goto yy109; + goto yy94; yy101: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x8F) goto yy95; - if (yych <= 0xBF) goto yy110; - goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych <= 0xBF) goto yy107; + goto yy94; yy102: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy95; - if (yych <= 0xBF) goto yy108; - goto yy95; -yy103: - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy95; - if (yych >= 0x90) goto yy95; + if (yych <= 0x7F) goto yy94; + if (yych >= 0x90) goto yy94; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy106; -yy105: + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy105; +yy104: YYCURSOR = YYMARKER; if (yyaccept <= 1) { - if (yyaccept == 0) { - goto yy93; + if (yyaccept <= 0) { + goto yy92; } else { - goto yy95; + goto yy94; } } else { - goto yy127; + goto yy126; } +yy105: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy104; + if (yych >= 0xC0) goto yy104; yy106: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych >= 0xC0) goto yy105; + goto yy88; yy107: yych = *++YYCURSOR; - goto yy89; -yy108: + if (yych <= 0x7F) goto yy104; + if (yych >= 0xC0) goto yy104; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych >= 0xC0) goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; +yy109: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; -yy110: + if (yych <= 0x7F) goto yy104; + if (yych >= 0xC0) goto yy104; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych >= 0xC0) goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; +yy111: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; yy112: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; yy113: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; yy114: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; + if (yych <= 0x7F) goto yy104; + if (yych <= 0xBF) goto yy106; + goto yy104; yy115: - yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy105; - if (yych <= 0xBF) goto yy107; - goto yy105; -yy116: ++YYCURSOR; { s->str_esc++; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy118: +yy117: yych = *++YYCURSOR; if (yych <= 'D') { if (yych <= '9') { - if (yych <= '/') goto yy105; - if (yych >= '1') goto yy120; + if (yych <= '/') goto yy104; + if (yych >= '1') goto yy119; } else { - if (yych <= '@') goto yy105; - if (yych <= 'C') goto yy120; - goto yy121; + if (yych <= '@') goto yy104; + if (yych <= 'C') goto yy119; + goto yy120; } } else { if (yych <= 'c') { - if (yych <= 'F') goto yy120; - if (yych <= '`') goto yy105; - goto yy120; + if (yych <= 'F') goto yy119; + if (yych <= '`') goto yy104; + goto yy119; } else { - if (yych <= 'd') goto yy121; - if (yych <= 'f') goto yy120; - goto yy105; + if (yych <= 'd') goto yy120; + if (yych <= 'f') goto yy119; + goto yy104; } } yych = *++YYCURSOR; if (yych <= '9') { - if (yych <= '/') goto yy105; - if (yych <= '0') goto yy140; - if (yych <= '7') goto yy141; - goto yy122; + if (yych <= '/') goto yy104; + if (yych <= '0') goto yy139; + if (yych <= '7') goto yy140; + goto yy121; } else { if (yych <= 'F') { - if (yych <= '@') goto yy105; - goto yy122; + if (yych <= '@') goto yy104; + goto yy121; } else { - if (yych <= '`') goto yy105; - if (yych <= 'f') goto yy122; - goto yy105; + if (yych <= '`') goto yy104; + if (yych <= 'f') goto yy121; + goto yy104; } } -yy120: +yy119: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy122; - goto yy105; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy121; + goto yy104; } else { - if (yych <= 'F') goto yy122; - if (yych <= '`') goto yy105; - if (yych <= 'f') goto yy122; - goto yy105; + if (yych <= 'F') goto yy121; + if (yych <= '`') goto yy104; + if (yych <= 'f') goto yy121; + goto yy104; } -yy121: +yy120: yych = *++YYCURSOR; if (yych <= 'B') { if (yych <= '7') { - if (yych <= '/') goto yy105; + if (yych <= '/') goto yy104; } else { - if (yych <= '9') goto yy123; - if (yych <= '@') goto yy105; - goto yy123; + if (yych <= '9') goto yy122; + if (yych <= '@') goto yy104; + goto yy122; } } else { if (yych <= '`') { - if (yych <= 'F') goto yy124; - goto yy105; + if (yych <= 'F') goto yy123; + goto yy104; } else { - if (yych <= 'b') goto yy123; - if (yych <= 'f') goto yy124; - goto yy105; + if (yych <= 'b') goto yy122; + if (yych <= 'f') goto yy123; + goto yy104; } } +yy121: + yych = *++YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy136; + goto yy104; + } else { + if (yych <= 'F') goto yy136; + if (yych <= '`') goto yy104; + if (yych <= 'f') goto yy136; + goto yy104; + } yy122: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy137; - goto yy105; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy127; + goto yy104; } else { - if (yych <= 'F') goto yy137; - if (yych <= '`') goto yy105; - if (yych <= 'f') goto yy137; - goto yy105; + if (yych <= 'F') goto yy127; + if (yych <= '`') goto yy104; + if (yych <= 'f') goto yy127; + goto yy104; } yy123: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy128; - goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy128; - if (yych <= '`') goto yy105; - if (yych <= 'f') goto yy128; - goto yy105; + if (yych <= 'F') goto yy124; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } yy124: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { if (yych <= 'F') goto yy125; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } yy125: - yych = *++YYCURSOR; - if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; - } else { - if (yych <= 'F') goto yy126; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; - } -yy126: ++YYCURSOR; -yy127: +yy126: { s->errcode = PHP_JSON_ERROR_UTF16; return PHP_JSON_T_ERROR; } -yy128: +yy127: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy129; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy128; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy129: +yy128: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych != '\\') goto yy127; + if (yych != '\\') goto yy126; yych = *++YYCURSOR; - if (yych != 'u') goto yy105; + if (yych != 'u') goto yy104; yych = *++YYCURSOR; - if (yych == 'D') goto yy132; - if (yych != 'd') goto yy105; -yy132: + if (yych == 'D') goto yy131; + if (yych != 'd') goto yy104; +yy131: yych = *++YYCURSOR; - if (yych <= 'B') goto yy105; - if (yych <= 'F') goto yy133; - if (yych <= 'b') goto yy105; - if (yych >= 'g') goto yy105; -yy133: + if (yych <= 'B') goto yy104; + if (yych <= 'F') goto yy132; + if (yych <= 'b') goto yy104; + if (yych >= 'g') goto yy104; +yy132: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy134; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy133; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy134: +yy133: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy135; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy134; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy135: +yy134: ++YYCURSOR; { s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy137: +yy136: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy138; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy137; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy138: +yy137: ++YYCURSOR; { s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy140: +yy139: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych <= '7') goto yy145; - if (yych <= '9') goto yy142; - goto yy105; + if (yych <= '/') goto yy104; + if (yych <= '7') goto yy144; + if (yych <= '9') goto yy141; + goto yy104; } else { - if (yych <= 'F') goto yy142; - if (yych <= '`') goto yy105; - if (yych <= 'f') goto yy142; - goto yy105; + if (yych <= 'F') goto yy141; + if (yych <= '`') goto yy104; + if (yych <= 'f') goto yy141; + goto yy104; } -yy141: +yy140: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy142; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy141; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy142: +yy141: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy143; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy142; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy143: +yy142: ++YYCURSOR; { s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy145: +yy144: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy105; - if (yych >= ':') goto yy105; + if (yych <= '/') goto yy104; + if (yych >= ':') goto yy104; } else { - if (yych <= 'F') goto yy146; - if (yych <= '`') goto yy105; - if (yych >= 'g') goto yy105; + if (yych <= 'F') goto yy145; + if (yych <= '`') goto yy104; + if (yych >= 'g') goto yy104; } -yy146: +yy145: ++YYCURSOR; { s->str_esc += 5; @@ -1038,22 +1039,22 @@ yy146: /* *********************************** */ yyc_STR_P2: yych = *YYCURSOR; - if (yych == '"') goto yy152; - if (yych == '\\') goto yy154; + if (yych == '"') goto yy151; + if (yych == '\\') goto yy153; ++YYCURSOR; { PHP_JSON_CONDITION_GOTO(STR_P2); } -yy152: +yy151: ++YYCURSOR; YYSETCONDITION(yycJS); { PHP_JSON_SCANNER_COPY_ESC(); return PHP_JSON_T_STRING; } -yy154: +yy153: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'u') goto yy156; -yy155: + if (yych == 'u') goto yy155; +yy154: { char esc; PHP_JSON_SCANNER_COPY_ESC(); @@ -1087,103 +1088,103 @@ yy155: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy156: +yy155: yych = *++YYCURSOR; if (yych <= 'D') { if (yych <= '9') { - if (yych <= '/') goto yy157; - if (yych <= '0') goto yy158; - goto yy159; + if (yych <= '/') goto yy156; + if (yych <= '0') goto yy157; + goto yy158; } else { - if (yych <= '@') goto yy157; - if (yych <= 'C') goto yy159; - goto yy160; + if (yych <= '@') goto yy156; + if (yych <= 'C') goto yy158; + goto yy159; } } else { if (yych <= 'c') { - if (yych <= 'F') goto yy159; - if (yych >= 'a') goto yy159; + if (yych <= 'F') goto yy158; + if (yych >= 'a') goto yy158; } else { - if (yych <= 'd') goto yy160; - if (yych <= 'f') goto yy159; + if (yych <= 'd') goto yy159; + if (yych <= 'f') goto yy158; } } -yy157: +yy156: YYCURSOR = YYMARKER; - goto yy155; -yy158: + goto yy154; +yy157: yych = *++YYCURSOR; if (yych <= '9') { - if (yych <= '/') goto yy157; - if (yych <= '0') goto yy175; - if (yych <= '7') goto yy176; - goto yy162; + if (yych <= '/') goto yy156; + if (yych <= '0') goto yy174; + if (yych <= '7') goto yy175; + goto yy161; } else { if (yych <= 'F') { - if (yych <= '@') goto yy157; - goto yy162; + if (yych <= '@') goto yy156; + goto yy161; } else { - if (yych <= '`') goto yy157; - if (yych <= 'f') goto yy162; - goto yy157; + if (yych <= '`') goto yy156; + if (yych <= 'f') goto yy161; + goto yy156; } } +yy158: + yych = *++YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy156; + if (yych <= '9') goto yy161; + goto yy156; + } else { + if (yych <= 'F') goto yy161; + if (yych <= '`') goto yy156; + if (yych <= 'f') goto yy161; + goto yy156; + } yy159: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych <= '9') goto yy162; - goto yy157; + if (yych <= '/') goto yy156; + if (yych <= '7') goto yy161; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy162; - if (yych <= '`') goto yy157; - if (yych <= 'f') goto yy162; - goto yy157; + if (yych <= 'B') goto yy160; + if (yych <= '`') goto yy156; + if (yych >= 'c') goto yy156; } yy160: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych <= '7') goto yy162; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych <= '9') goto yy165; + goto yy156; } else { - if (yych <= 'B') goto yy161; - if (yych <= '`') goto yy157; - if (yych >= 'c') goto yy157; + if (yych <= 'F') goto yy165; + if (yych <= '`') goto yy156; + if (yych <= 'f') goto yy165; + goto yy156; } yy161: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych <= '9') goto yy166; - goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy166; - if (yych <= '`') goto yy157; - if (yych <= 'f') goto yy166; - goto yy157; + if (yych <= 'F') goto yy162; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } yy162: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { if (yych <= 'F') goto yy163; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } yy163: - yych = *++YYCURSOR; - if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; - } else { - if (yych <= 'F') goto yy164; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; - } -yy164: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 4); @@ -1194,51 +1195,51 @@ yy164: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy166: +yy165: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy167; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy166; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy167: +yy166: yych = *++YYCURSOR; - if (yych != '\\') goto yy157; + if (yych != '\\') goto yy156; yych = *++YYCURSOR; - if (yych != 'u') goto yy157; + if (yych != 'u') goto yy156; yych = *++YYCURSOR; - if (yych == 'D') goto yy170; - if (yych != 'd') goto yy157; -yy170: + if (yych == 'D') goto yy169; + if (yych != 'd') goto yy156; +yy169: yych = *++YYCURSOR; - if (yych <= 'B') goto yy157; - if (yych <= 'F') goto yy171; - if (yych <= 'b') goto yy157; - if (yych >= 'g') goto yy157; -yy171: + if (yych <= 'B') goto yy156; + if (yych <= 'F') goto yy170; + if (yych <= 'b') goto yy156; + if (yych >= 'g') goto yy156; +yy170: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy172; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy171; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy172: +yy171: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy173; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy172; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy173: +yy172: ++YYCURSOR; { int utf32, utf16_hi, utf16_lo; @@ -1253,40 +1254,40 @@ yy173: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy175: +yy174: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych <= '7') goto yy180; - if (yych <= '9') goto yy177; - goto yy157; + if (yych <= '/') goto yy156; + if (yych <= '7') goto yy179; + if (yych <= '9') goto yy176; + goto yy156; } else { - if (yych <= 'F') goto yy177; - if (yych <= '`') goto yy157; - if (yych <= 'f') goto yy177; - goto yy157; + if (yych <= 'F') goto yy176; + if (yych <= '`') goto yy156; + if (yych <= 'f') goto yy176; + goto yy156; } -yy176: +yy175: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy177; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy176; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy177: +yy176: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy178; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy177; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy178: +yy177: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 3); @@ -1296,17 +1297,17 @@ yy178: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy180: +yy179: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy157; - if (yych >= ':') goto yy157; + if (yych <= '/') goto yy156; + if (yych >= ':') goto yy156; } else { - if (yych <= 'F') goto yy181; - if (yych <= '`') goto yy157; - if (yych >= 'g') goto yy157; + if (yych <= 'F') goto yy180; + if (yych <= '`') goto yy156; + if (yych >= 'g') goto yy156; } -yy181: +yy180: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 2); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 7bcca27335..cedb8ae453 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -22,7 +22,7 @@ #ifndef PHP_JSON_H #define PHP_JSON_H -#define PHP_JSON_VERSION "1.4.0" +#define PHP_JSON_VERSION "1.5.0" #include "zend_smart_str_public.h" extern zend_module_entry json_module_entry; @@ -67,6 +67,7 @@ typedef enum { #define PHP_JSON_UNESCAPED_UNICODE (1<<8) #define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR (1<<9) #define PHP_JSON_PRESERVE_ZERO_FRACTION (1<<10) +#define PHP_JSON_UNESCAPED_LINE_TERMINATORS (1<<11) /* json_decode() options */ #define PHP_JSON_OBJECT_AS_ARRAY (1<<0) @@ -92,12 +93,12 @@ PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) ZEND_TSRMLS_CACHE_EXTERN() #endif -PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options); -PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth); +PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options); +PHP_JSON_API int php_json_decode_ex(zval *return_value, char *str, size_t str_len, zend_long options, zend_long depth); -static inline void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, zend_long depth) +static inline int php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, zend_long depth) { - php_json_decode_ex(return_value, str, str_len, assoc ? PHP_JSON_OBJECT_AS_ARRAY : 0, depth); + return php_json_decode_ex(return_value, str, str_len, assoc ? PHP_JSON_OBJECT_AS_ARRAY : 0, depth); } diff --git a/ext/json/php_json_encoder.h b/ext/json/php_json_encoder.h index b10f7a614a..68ce8b2de2 100644 --- a/ext/json/php_json_encoder.h +++ b/ext/json/php_json_encoder.h @@ -22,6 +22,19 @@ #include "php.h" #include "zend_smart_str.h" -void 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 */ diff --git a/ext/json/php_json_parser.h b/ext/json/php_json_parser.h index 6964ef8e8e..afead526c2 100644 --- a/ext/json/php_json_parser.h +++ b/ext/json/php_json_parser.h @@ -22,16 +22,64 @@ #include "php.h" #include "php_json_scanner.h" -typedef struct _php_json_parser { +typedef struct _php_json_parser php_json_parser; + +typedef int (*php_json_parser_func_array_create_t)( + php_json_parser *parser, zval *array); +typedef int (*php_json_parser_func_array_append_t)( + php_json_parser *parser, zval *array, zval *zvalue); +typedef int (*php_json_parser_func_array_start_t)( + php_json_parser *parser); +typedef int (*php_json_parser_func_array_end_t)( + php_json_parser *parser, zval *object); +typedef int (*php_json_parser_func_object_create_t)( + php_json_parser *parser, zval *object); +typedef int (*php_json_parser_func_object_update_t)( + php_json_parser *parser, zval *object, zend_string *key, zval *zvalue); +typedef int (*php_json_parser_func_object_start_t)( + php_json_parser *parser); +typedef int (*php_json_parser_func_object_end_t)( + php_json_parser *parser, zval *object); + +typedef struct _php_json_parser_methods { + php_json_parser_func_array_create_t array_create; + php_json_parser_func_array_append_t array_append; + php_json_parser_func_array_start_t array_start; + php_json_parser_func_array_end_t array_end; + php_json_parser_func_object_create_t object_create; + php_json_parser_func_object_update_t object_update; + php_json_parser_func_object_start_t object_start; + php_json_parser_func_object_end_t object_end; +} php_json_parser_methods; + +struct _php_json_parser { php_json_scanner scanner; zval *return_value; int depth; int max_depth; -} php_json_parser; + php_json_parser_methods methods; +}; + +PHP_JSON_API void php_json_parser_init_ex( + php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth, + const php_json_parser_methods *methods); + +PHP_JSON_API void php_json_parser_init( + php_json_parser *parser, + zval *return_value, + char *str, + size_t str_len, + int options, + int max_depth); -void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth); +PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser); -php_json_error_code php_json_parser_error_code(php_json_parser *parser); +PHP_JSON_API int php_json_parse(php_json_parser *parser); int php_json_yyparse(php_json_parser *parser); diff --git a/ext/json/php_json_scanner_defs.h b/ext/json/php_json_scanner_defs.h index a75e766a65..b3867433a7 100644 --- a/ext/json/php_json_scanner_defs.h +++ b/ext/json/php_json_scanner_defs.h @@ -1,4 +1,4 @@ -/* Generated by re2c 0.14.3 */ +/* Generated by re2c 0.13.5 */ enum YYCONDTYPE { yycJS, diff --git a/ext/json/tests/001.phpt b/ext/json/tests/001.phpt index 02d43c4243..e908b44349 100644 --- a/ext/json/tests/001.phpt +++ b/ext/json/tests/001.phpt @@ -53,16 +53,16 @@ object(stdClass)#%d (1) { } } object(stdClass)#%d (1) { - ["_empty_"]=> + [""]=> object(stdClass)#%d (1) { ["foo"]=> string(0) "" } } object(stdClass)#%d (1) { - ["_empty_"]=> + [""]=> object(stdClass)#%d (1) { - ["_empty_"]=> + [""]=> string(0) "" } } diff --git a/ext/json/tests/bug66025.phpt b/ext/json/tests/bug66025.phpt new file mode 100644 index 0000000000..9322d39b66 --- /dev/null +++ b/ext/json/tests/bug66025.phpt @@ -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]"] diff --git a/ext/json/tests/bug68992.phpt b/ext/json/tests/bug68992.phpt new file mode 100644 index 0000000000..06448bbb38 --- /dev/null +++ b/ext/json/tests/bug68992.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #68992 (json_encode stacks exceptions thrown by JsonSerializable classes) +--SKIPIF-- +<?php +if (!extension_loaded('json')) die('skip'); +?> +--FILE-- +<?php + +class MyClass implements JsonSerializable { + public function jsonSerialize() { + throw new Exception('Not implemented!'); + } +} +$classes = []; +for($i = 0; $i < 5; $i++) { + $classes[] = new MyClass(); +} + +try { + json_encode($classes); +} catch(Exception $e) { + do { + printf("%s (%d) [%s]\n", $e->getMessage(), $e->getCode(), get_class($e)); + } while ($e = $e->getPrevious()); +} +?> +--EXPECT-- +Not implemented! (0) [Exception] diff --git a/ext/json/tests/bug73254.phpt b/ext/json/tests/bug73254.phpt new file mode 100644 index 0000000000..b043330cb7 --- /dev/null +++ b/ext/json/tests/bug73254.phpt @@ -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]"] diff --git a/ext/json/tests/json_encode_u2028_u2029.phpt b/ext/json/tests/json_encode_u2028_u2029.phpt new file mode 100644 index 0000000000..4b87e9b307 --- /dev/null +++ b/ext/json/tests/json_encode_u2028_u2029.phpt @@ -0,0 +1,36 @@ +--TEST-- +json_encode() tests for U+2028, U+2029 +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php +var_dump(json_encode(array("a\xC3\xA1b"))); +var_dump(json_encode(array("a\xC3\xA1b"), JSON_UNESCAPED_UNICODE)); +var_dump(json_encode("a\xE2\x80\xA7b")); +var_dump(json_encode("a\xE2\x80\xA7b", JSON_UNESCAPED_UNICODE)); +var_dump(json_encode("a\xE2\x80\xA8b")); +var_dump(json_encode("a\xE2\x80\xA8b", JSON_UNESCAPED_UNICODE)); +var_dump(json_encode("a\xE2\x80\xA8b", JSON_UNESCAPED_LINE_TERMINATORS)); +var_dump(json_encode("a\xE2\x80\xA8b", JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS)); +var_dump(json_encode("a\xE2\x80\xA9b")); +var_dump(json_encode("a\xE2\x80\xA9b", JSON_UNESCAPED_UNICODE)); +var_dump(json_encode("a\xE2\x80\xA9b", JSON_UNESCAPED_LINE_TERMINATORS)); +var_dump(json_encode("a\xE2\x80\xA9b", JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS)); +var_dump(json_encode("a\xE2\x80\xAAb")); +var_dump(json_encode("a\xE2\x80\xAAb", JSON_UNESCAPED_UNICODE)); +?> +--EXPECT-- +string(12) "["a\u00e1b"]" +string(8) "["aáb"]" +string(10) ""a\u2027b"" +string(7) ""a‧b"" +string(10) ""a\u2028b"" +string(10) ""a\u2028b"" +string(10) ""a\u2028b"" +string(7) ""a
b"" +string(10) ""a\u2029b"" +string(10) ""a\u2029b"" +string(10) ""a\u2029b"" +string(7) ""a
b"" +string(10) ""a\u202ab"" +string(7) ""ab"" diff --git a/ext/json/tests/pass001.1.phpt b/ext/json/tests/pass001.1.phpt index 611c40c4a4..d952e5811f 100644 --- a/ext/json/tests/pass001.1.phpt +++ b/ext/json/tests/pass001.1.phpt @@ -204,7 +204,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> float(INF) ["E no ."]=> float(4000000000000) @@ -527,7 +527,7 @@ array(14) { string(7) "rosebud" } ENCODE: FROM OBJECT -["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":{},"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] +["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":{},"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] ENCODE: FROM ARRAY ["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},[],[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":[],"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] DECODE AGAIN: AS OBJECT @@ -566,7 +566,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> int(0) ["E no ."]=> %s(4000000000000) diff --git a/ext/json/tests/pass001.1_64bit.phpt b/ext/json/tests/pass001.1_64bit.phpt index e6666d1599..3970fa434e 100644 --- a/ext/json/tests/pass001.1_64bit.phpt +++ b/ext/json/tests/pass001.1_64bit.phpt @@ -204,7 +204,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> float(INF) ["E no ."]=> float(4000000000000) @@ -527,7 +527,7 @@ array(14) { string(7) "rosebud" } ENCODE: FROM OBJECT -["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":{},"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] +["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":{},"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] ENCODE: FROM ARRAY ["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},[],[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"E no .":4000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":[],"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] DECODE AGAIN: AS OBJECT @@ -566,7 +566,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> int(0) ["E no ."]=> int(4000000000000) diff --git a/ext/json/tests/pass001.phpt b/ext/json/tests/pass001.phpt index ffe7c61f01..948929d5a5 100644 --- a/ext/json/tests/pass001.phpt +++ b/ext/json/tests/pass001.phpt @@ -188,7 +188,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> float(INF) ["zero"]=> int(0) @@ -425,7 +425,7 @@ array(14) { string(7) "rosebud" } ENCODE: FROM OBJECT -["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","true":true,"false":false,"null":null,"array":[],"object":{},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] +["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","true":true,"false":false,"null":null,"array":[],"object":{},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] ENCODE: FROM ARRAY ["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},[],[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"":0,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","true":true,"false":false,"null":null,"array":[],"object":[],"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] DECODE AGAIN: AS OBJECT @@ -464,7 +464,7 @@ array(14) { float(1.23456789E-13) ["E"]=> float(1.23456789E+34) - ["_empty_"]=> + [""]=> int(0) ["zero"]=> int(0) |
