From 680cdbfab035237cd8e66f808193e2c82a43becb Mon Sep 17 00:00:00 2001 From: juan-morales Date: Mon, 1 Dec 2025 10:13:48 -0300 Subject: [PATCH 1/6] first commit --- ext/json/json.c | 49 ++++++++++++- ext/json/json_parser.y | 30 ++++++-- ext/json/json_scanner.re | 81 +++++++++++++++++++--- ext/json/php_json.h | 2 + ext/json/php_json_parser.h | 12 ++++ ext/json/php_json_scanner.h | 13 ++++ ext/json/tests/007.phpt | 8 +-- ext/json/tests/bug62010.phpt | 2 +- ext/json/tests/bug68546.phpt | 4 +- ext/json/tests/json_decode_exceptions.phpt | 2 +- ext/json/tests/json_validate_002.phpt | 6 +- ext/json/tests/json_validate_004.phpt | 8 +-- 12 files changed, 185 insertions(+), 32 deletions(-) diff --git a/ext/json/json.c b/ext/json/json.c index 9f91d39594ec7..09a4a997c18f2 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -63,6 +63,8 @@ static PHP_GINIT_FUNCTION(json) #endif json_globals->encoder_depth = 0; json_globals->error_code = 0; + json_globals->error_line = 0; + json_globals->error_column = 0; json_globals->encode_max_depth = PHP_JSON_PARSER_DEFAULT_DEPTH; } /* }}} */ @@ -70,6 +72,8 @@ static PHP_GINIT_FUNCTION(json) static PHP_RINIT_FUNCTION(json) { JSON_G(error_code) = 0; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; return SUCCESS; } @@ -177,6 +181,18 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ +static zend_string *php_json_get_error_msg_with_location(php_json_error_code error_code, int line, int column) /* {{{ */ +{ + const char *base_msg = php_json_get_error_msg(error_code); + + if (line > 0 && column > 0) { + return zend_strpprintf(0, "%s near location %d,%d", base_msg, line, column); + } + + return zend_string_init(base_msg, strlen(base_msg), 0); +} +/* }}} */ + PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ { php_json_parser parser; @@ -185,10 +201,17 @@ PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); + int error_line = php_json_parser_error_line(&parser); + int error_column = php_json_parser_error_column(&parser); + if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = error_code; + JSON_G(error_line) = error_line; + JSON_G(error_column) = error_column; } else { - zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(error_code), error_code); + zend_string *error_msg = php_json_get_error_msg_with_location(error_code, error_line, error_column); + zend_throw_exception(php_json_exception_ce, ZSTR_VAL(error_msg), error_code); + zend_string_release(error_msg); } RETVAL_NULL(); return FAILURE; @@ -208,7 +231,12 @@ PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_lon if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); + int error_line = php_json_parser_error_line(&parser); + int error_column = php_json_parser_error_column(&parser); + JSON_G(error_code) = error_code; + JSON_G(error_line) = error_line; + JSON_G(error_column) = error_column; return false; } @@ -274,11 +302,15 @@ PHP_FUNCTION(json_decode) if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = PHP_JSON_ERROR_NONE; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; } if (!str_len) { if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; } else { zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(PHP_JSON_ERROR_SYNTAX), PHP_JSON_ERROR_SYNTAX); } @@ -331,10 +363,14 @@ PHP_FUNCTION(json_validate) if (!str_len) { JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; RETURN_FALSE; } JSON_G(error_code) = PHP_JSON_ERROR_NONE; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; if (depth <= 0) { zend_argument_value_error(2, "must be greater than 0"); @@ -364,6 +400,15 @@ PHP_FUNCTION(json_last_error_msg) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_STRING(php_json_get_error_msg(JSON_G(error_code))); + if (JSON_G(error_line) > 0 && JSON_G(error_column) > 0) { + zend_string *error_msg = php_json_get_error_msg_with_location( + JSON_G(error_code), + JSON_G(error_line), + JSON_G(error_column) + ); + RETVAL_STR(error_msg); + } else { + RETURN_STRING(php_json_get_error_msg(JSON_G(error_code))); + } } /* }}} */ diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index d570cddc91e4b..98a4b9bd0e319 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -41,6 +41,7 @@ int json_yydebug = 1; } +%locations %define api.prefix {php_json_yy} %define api.pure full %param { php_json_parser *parser } @@ -49,7 +50,6 @@ int json_yydebug = 1; zval value; } - %token PHP_JSON_T_NUL %token PHP_JSON_T_TRUE %token PHP_JSON_T_FALSE @@ -66,8 +66,8 @@ int json_yydebug = 1; %destructor { zval_ptr_dtor_nogc(&$$); } %code { -static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); -static void php_json_yyerror(php_json_parser *parser, char const *msg); +static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser); +static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg); static int php_json_parser_array_create(php_json_parser *parser, zval *array); static int php_json_parser_object_create(php_json_parser *parser, zval *array); @@ -277,7 +277,7 @@ static int php_json_parser_object_update_validate(php_json_parser *parser, zval return SUCCESS; } -static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) +static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser) { int token = php_json_scan(&parser->scanner); @@ -293,14 +293,24 @@ static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) value->value = parser->scanner.value; } + location->first_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_column); + location->first_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_line); + location->last_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_column); + location->last_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_line); + return token; } -static void php_json_yyerror(php_json_parser *parser, char const *msg) +static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg) { if (!parser->scanner.errcode) { parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; } + + parser->scanner.errloc.first_column = location->first_column; + parser->scanner.errloc.first_line = location->first_line; + parser->scanner.errloc.last_column = location->last_column; + parser->scanner.errloc.last_line = location->last_line; } PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser) @@ -308,6 +318,16 @@ PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parse return parser->scanner.errcode; } +PHP_JSON_API int php_json_parser_error_line(const php_json_parser *parser) +{ + return parser->scanner.errloc.first_line; +} + +PHP_JSON_API int php_json_parser_error_column(const php_json_parser *parser) +{ + return parser->scanner.errloc.first_column; +} + static const php_json_parser_methods default_parser_methods = { php_json_parser_array_create, diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index 0debb3b03cb22..886c7a1a3000a 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -52,6 +52,8 @@ #define PHP_JSON_INT_MAX_LENGTH (MAX_LENGTH_OF_LONG - 1) +#define PHP_JSON_TOKEN_LENGTH(s) ((size_t) ((s)->cursor - (s)->token)) +#define PHP_JSON_TOKEN_LOCATION(location) (s)->errloc.location static void php_json_scanner_copy_string(php_json_scanner *s, size_t esc_size) { @@ -96,6 +98,10 @@ void php_json_scanner_init(php_json_scanner *s, const char *str, size_t str_len, s->cursor = (php_json_ctype *) str; s->limit = (php_json_ctype *) str + str_len; s->options = options; + PHP_JSON_TOKEN_LOCATION(first_column) = 1; + PHP_JSON_TOKEN_LOCATION(first_line) = 1; + PHP_JSON_TOKEN_LOCATION(last_column) = 1; + PHP_JSON_TOKEN_LOCATION(last_line) = 1; PHP_JSON_CONDITION_SET(JS); } @@ -104,6 +110,8 @@ int php_json_scan(php_json_scanner *s) ZVAL_NULL(&s->value); std: + PHP_JSON_TOKEN_LOCATION(first_column) = s->errloc.last_column; + PHP_JSON_TOKEN_LOCATION(first_line) = s->errloc.last_line; s->token = s->cursor; /*!re2c @@ -149,27 +157,50 @@ std: UTF16_3 = UTFPREF ( ( ( HEXC | [efEF] ) HEX ) | ( [dD] HEX7 ) ) HEX{2} ; UTF16_4 = UTFPREF [dD] [89abAB] HEX{2} UTFPREF [dD] [c-fC-F] HEX{2} ; - "{" { return '{'; } - "}" { return '}'; } - "[" { return '['; } - "]" { return ']'; } - ":" { return ':'; } - "," { return ','; } + "{" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '{'; + } + "}" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '}'; + } + "[" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '['; + } + "]" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ']'; + } + ":" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ':'; + } + "," { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ','; + } "null" { + PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_NULL(&s->value); return PHP_JSON_T_NUL; } "true" { + PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_TRUE(&s->value); return PHP_JSON_T_TRUE; } "false" { + PHP_JSON_TOKEN_LOCATION(last_column) += 5; ZVAL_FALSE(&s->value); return PHP_JSON_T_FALSE; } INT { bool bigint = 0, negative = s->token[0] == '-'; - size_t digits = (size_t) (s->cursor - s->token - negative); + size_t digits = PHP_JSON_TOKEN_LENGTH(s); + PHP_JSON_TOKEN_LOCATION(last_column) += digits; + digits -= negative; if (digits >= PHP_JSON_INT_MAX_LENGTH) { if (digits == PHP_JSON_INT_MAX_LENGTH) { int cmp = strncmp((char *) (s->token + negative), LONG_MIN_DIGITS, PHP_JSON_INT_MAX_LENGTH); @@ -192,10 +223,19 @@ std: } } FLOAT|EXP { + PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(s); ZVAL_DOUBLE(&s->value, zend_strtod((char *) s->token, NULL)); return PHP_JSON_T_DOUBLE; } - NL|WS { goto std; } + NL { + PHP_JSON_TOKEN_LOCATION(last_line)++; + PHP_JSON_TOKEN_LOCATION(last_column) = 1; + goto std; + } + WS { + PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(s); + goto std; + } EOI { if (s->limit < s->cursor) { return PHP_JSON_T_EOI; @@ -205,6 +245,7 @@ std: } } ["] { + PHP_JSON_TOKEN_LOCATION(last_column)++; s->str_start = s->cursor; s->str_esc = 0; s->utf8_invalid = 0; @@ -229,18 +270,22 @@ std: return PHP_JSON_T_ERROR; } UTF16_1 { + PHP_JSON_TOKEN_LOCATION(last_column) += 6; s->str_esc += 5; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_2 { + PHP_JSON_TOKEN_LOCATION(last_column) += 6; s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_3 { + PHP_JSON_TOKEN_LOCATION(last_column) += 6; s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_4 { + PHP_JSON_TOKEN_LOCATION(last_column) += 12; s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -249,6 +294,7 @@ std: return PHP_JSON_T_ERROR; } ESC { + PHP_JSON_TOKEN_LOCATION(last_column) += 2; s->str_esc++; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -257,6 +303,7 @@ std: return PHP_JSON_T_ERROR; } ["] { + PHP_JSON_TOKEN_LOCATION(last_column)++; zend_string *str; size_t len = (size_t)(s->cursor - s->str_start - s->str_esc - 1 + s->utf8_invalid_count); if (len == 0) { @@ -277,7 +324,22 @@ std: return PHP_JSON_T_STRING; } } - UTF8 { PHP_JSON_CONDITION_GOTO(STR_P1); } + UTF8_1 { + PHP_JSON_TOKEN_LOCATION(last_column)++; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_2 { + PHP_JSON_TOKEN_LOCATION(last_column) += 2; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_3 { + PHP_JSON_TOKEN_LOCATION(last_column) += 3; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_4 { + PHP_JSON_TOKEN_LOCATION(last_column) += 4; + PHP_JSON_CONDITION_GOTO(STR_P1); + } ANY { if (s->options & (PHP_JSON_INVALID_UTF8_IGNORE | PHP_JSON_INVALID_UTF8_SUBSTITUTE)) { if (s->options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) { @@ -295,7 +357,6 @@ std: s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } - UTF16_1 { int utf16 = php_json_ucs2_to_int(s, 2); PHP_JSON_SCANNER_COPY_UTF(); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index b79c7c836f7a3..6111620130d8e 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -86,6 +86,8 @@ ZEND_BEGIN_MODULE_GLOBALS(json) int encoder_depth; int encode_max_depth; php_json_error_code error_code; + int error_line; + int error_column; ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) diff --git a/ext/json/php_json_parser.h b/ext/json/php_json_parser.h index 8aedce9ac55d6..13b22fff413ca 100644 --- a/ext/json/php_json_parser.h +++ b/ext/json/php_json_parser.h @@ -50,12 +50,20 @@ typedef struct _php_json_parser_methods { php_json_parser_func_object_end_t object_end; } php_json_parser_methods; + typedef struct _php_json_parser_location { + int first_line; + int first_column; + int last_line; + int last_column; +} php_json_parser_location; + struct _php_json_parser { php_json_scanner scanner; zval *return_value; int depth; int max_depth; php_json_parser_methods methods; + php_json_parser_location *location; }; PHP_JSON_API void php_json_parser_init_ex( @@ -77,6 +85,10 @@ PHP_JSON_API void php_json_parser_init( PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser); +PHP_JSON_API int php_json_parser_error_line(const php_json_parser *parser); + +PHP_JSON_API int php_json_parser_error_column(const 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.h b/ext/json/php_json_scanner.h index a49be68cd6328..a6de149391dc1 100644 --- a/ext/json/php_json_scanner.h +++ b/ext/json/php_json_scanner.h @@ -22,6 +22,17 @@ typedef unsigned char php_json_ctype; +typedef struct _php_json_error_location { + /** first column of the error */ + size_t first_column; + /** first line of the error */ + size_t first_line; + /** last column of the error */ + size_t last_column; + /** last line of the error */ + size_t last_line; +} php_json_error_location; + typedef struct _php_json_scanner { php_json_ctype *cursor; /* cursor position */ php_json_ctype *token; /* token position */ @@ -35,10 +46,12 @@ typedef struct _php_json_scanner { int state; /* condition state */ int options; /* options */ php_json_error_code errcode; /* error type if there is an error */ + php_json_error_location errloc; /* error location */ int utf8_invalid; /* whether utf8 is invalid */ int utf8_invalid_count; /* number of extra character for invalid utf8 */ } php_json_scanner; +#define PHP_JSON_SCANNER_LOCATION(scanner, slocation) (scanner).errloc.slocation void php_json_scanner_init(php_json_scanner *scanner, const char *str, size_t str_len, int options); int php_json_scan(php_json_scanner *s); diff --git a/ext/json/tests/007.phpt b/ext/json/tests/007.phpt index dea641317e97f..062bbab457de7 100644 --- a/ext/json/tests/007.phpt +++ b/ext/json/tests/007.phpt @@ -24,14 +24,14 @@ int(0) string(8) "No error" NULL int(1) -string(28) "Maximum stack depth exceeded" +string(46) "Maximum stack depth exceeded near location 1,2" NULL int(2) -string(42) "State mismatch (invalid or malformed JSON)" +string(60) "State mismatch (invalid or malformed JSON) near location 1,3" NULL int(3) -string(53) "Control character error, possibly incorrectly encoded" +string(71) "Control character error, possibly incorrectly encoded near location 1,2" NULL int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1,3" Done diff --git a/ext/json/tests/bug62010.phpt b/ext/json/tests/bug62010.phpt index 2591231dcdda1..c013087608417 100644 --- a/ext/json/tests/bug62010.phpt +++ b/ext/json/tests/bug62010.phpt @@ -10,4 +10,4 @@ var_dump(json_last_error_msg()); --EXPECT-- NULL bool(true) -string(50) "Single unpaired UTF-16 surrogate in unicode escape" +string(68) "Single unpaired UTF-16 surrogate in unicode escape near location 1,1" diff --git a/ext/json/tests/bug68546.phpt b/ext/json/tests/bug68546.phpt index 8835a72c5eac7..f2ac47bea45ad 100644 --- a/ext/json/tests/bug68546.phpt +++ b/ext/json/tests/bug68546.phpt @@ -5,7 +5,7 @@ Bug #68546 (json_decode() Fatal error: Cannot access property started with '\0') var_dump(json_decode('{"key": {"\u0000": "aa"}}')); var_dump(json_last_error() === JSON_ERROR_INVALID_PROPERTY_NAME); -var_dump(json_decode('[{"key1": 0, "\u0000": 1}]')); +var_dump(json_decode('[{"key1": 0, "\u1234": 1, "\u0000": 1}]')); var_dump(json_last_error() === JSON_ERROR_INVALID_PROPERTY_NAME); var_dump(json_last_error_msg()); @@ -16,5 +16,5 @@ NULL bool(true) NULL bool(true) -string(36) "The decoded property name is invalid" +string(55) "The decoded property name is invalid near location 1,37" Done diff --git a/ext/json/tests/json_decode_exceptions.phpt b/ext/json/tests/json_decode_exceptions.phpt index 7dc2e7408a02c..3a263ff806ca7 100644 --- a/ext/json/tests/json_decode_exceptions.phpt +++ b/ext/json/tests/json_decode_exceptions.phpt @@ -13,7 +13,7 @@ try { --EXPECTF-- object(JsonException)#1 (7) { ["message":protected]=> - string(12) "Syntax error" + string(30) "Syntax error near location 1,2" ["string":"Exception":private]=> string(0) "" ["code":protected]=> diff --git a/ext/json/tests/json_validate_002.phpt b/ext/json/tests/json_validate_002.phpt index 53f4e4f2c2ea1..e2c0d6ff435aa 100644 --- a/ext/json/tests/json_validate_002.phpt +++ b/ext/json/tests/json_validate_002.phpt @@ -23,13 +23,13 @@ int(4) string(12) "Syntax error" bool(false) int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1,1" bool(false) int(4) string(12) "Syntax error" bool(false) int(1) -string(28) "Maximum stack depth exceeded" +string(46) "Maximum stack depth exceeded near location 1,1" bool(true) int(0) string(8) "No error" @@ -44,7 +44,7 @@ int(0) string(8) "No error" bool(false) int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1,1" bool(true) int(0) string(8) "No error" diff --git a/ext/json/tests/json_validate_004.phpt b/ext/json/tests/json_validate_004.phpt index d8a798d943278..c8807943c32f0 100644 --- a/ext/json/tests/json_validate_004.phpt +++ b/ext/json/tests/json_validate_004.phpt @@ -23,16 +23,16 @@ json_validate_trycatchdump("[\"\xc1\xc1\",\"a\"]", 512, JSON_INVALID_UTF8_IGNORE Testing Invalid UTF-8 bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,2" bool(true) int(0) string(8) "No error" From be47a53721afe1d7f485ee37733236bc59d61c49 Mon Sep 17 00:00:00 2001 From: juan-morales Date: Mon, 1 Dec 2025 11:15:02 -0300 Subject: [PATCH 2/6] tests --- ...son_last_error_msg_error_location_001.phpt | 121 ++++++++++++ ...son_last_error_msg_error_location_002.phpt | 103 ++++++++++ ...son_last_error_msg_error_location_003.phpt | 72 +++++++ ...son_last_error_msg_error_location_004.phpt | 93 +++++++++ ...son_last_error_msg_error_location_005.phpt | 103 ++++++++++ ...son_last_error_msg_error_location_006.phpt | 152 +++++++++++++++ ...son_last_error_msg_error_location_007.phpt | 178 +++++++++++++++++ ...son_last_error_msg_error_location_008.phpt | 182 ++++++++++++++++++ ...son_last_error_msg_error_location_009.phpt | 110 +++++++++++ ...son_last_error_msg_error_location_010.phpt | 164 ++++++++++++++++ 10 files changed, 1278 insertions(+) create mode 100644 ext/json/tests/json_last_error_msg_error_location_001.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_002.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_003.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_004.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_005.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_006.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_007.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_008.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_009.phpt create mode 100644 ext/json/tests/json_last_error_msg_error_location_010.phpt diff --git a/ext/json/tests/json_last_error_msg_error_location_001.phpt b/ext/json/tests/json_last_error_msg_error_location_001.phpt new file mode 100644 index 0000000000000..269eab0ed7bbe --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_001.phpt @@ -0,0 +1,121 @@ +--TEST-- +json_last_error_msg() - Error location reporting with ASCII characters +--FILE-- + +--EXPECT-- +Testing errors at various locations with ASCII characters + +Error at position 1,1: +bool(false) +int(4) +string(30) "Syntax error near location 1,1" + +Error at position 1,10: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error at position 1,9: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Error at position 1,16: +bool(false) +int(4) +string(31) "Syntax error near location 1,16" + +Error at position 1,15: +bool(false) +int(4) +string(31) "Syntax error near location 1,15" + +Error at position 1,10: +bool(false) +int(4) +string(31) "Syntax error near location 1,10" + +Error at position 1,7: +bool(false) +int(4) +string(30) "Syntax error near location 1,7" + +Error at position 1,2: +bool(false) +int(4) +string(30) "Syntax error near location 1,2" + +Error at position 1,16: +bool(false) +int(4) +string(31) "Syntax error near location 1,16" + +Error at position 1,4: +bool(false) +int(4) +string(30) "Syntax error near location 1,4" + +Error at position 1,10: +bool(false) +int(4) +string(31) "Syntax error near location 1,10" + +Error at position 1,10: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + diff --git a/ext/json/tests/json_last_error_msg_error_location_002.phpt b/ext/json/tests/json_last_error_msg_error_location_002.phpt new file mode 100644 index 0000000000000..26a195432dd16 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_002.phpt @@ -0,0 +1,103 @@ +--TEST-- +json_last_error_msg() - Error location reporting with Unicode UTF-8 characters +--FILE-- + +--EXPECT-- +Testing error locations with Unicode UTF-8 characters + +Error after Japanese characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,24" + +Error after Russian characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error after Chinese characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error after Arabic characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error after Emoji: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error in mixed ASCII and UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,32" + +Error with UTF-8 escaped sequences: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error in object with multiple UTF-8 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,32" + +Error in array with UTF-8 strings: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,30" + +Error in nested object with UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,23" + diff --git a/ext/json/tests/json_last_error_msg_error_location_003.phpt b/ext/json/tests/json_last_error_msg_error_location_003.phpt new file mode 100644 index 0000000000000..bafc87b7af259 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_003.phpt @@ -0,0 +1,72 @@ +--TEST-- +json_last_error_msg() - Error location reporting with multi-line JSON +--FILE-- + +--EXPECT-- +Testing error locations in multi-line JSON + +Error on line 2, column 13: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 2,13" + +Error on line 3, column 12: +bool(false) +int(4) +string(31) "Syntax error near location 3,12" + +Error on line 5, column 26: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 5,26" + +Error on line 7, column 1: +bool(false) +int(4) +string(30) "Syntax error near location 7,1" + diff --git a/ext/json/tests/json_last_error_msg_error_location_004.phpt b/ext/json/tests/json_last_error_msg_error_location_004.phpt new file mode 100644 index 0000000000000..1044f77aa4b0e --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_004.phpt @@ -0,0 +1,93 @@ +--TEST-- +json_last_error_msg() - Error location reporting with deeply nested structures +--FILE-- + +--EXPECT-- +Testing error locations in deeply nested structures + +Error in deeply nested object: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,31" + +Error in deeply nested array: +bool(true) +int(0) +string(8) "No error" + +Error in mixed nested structures: +bool(true) +int(0) +string(8) "No error" + +Error at end of deep nesting: +bool(true) +int(0) +string(8) "No error" + +Error in middle of deep nesting: +bool(false) +int(4) +string(31) "Syntax error near location 1,21" + +Error in complex structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,93" + +Error in array of objects: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,68" + +Error in object with array values: +bool(false) +int(2) +string(61) "State mismatch (invalid or malformed JSON) near location 1,82" + diff --git a/ext/json/tests/json_last_error_msg_error_location_005.phpt b/ext/json/tests/json_last_error_msg_error_location_005.phpt new file mode 100644 index 0000000000000..8560f3c5c797b --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_005.phpt @@ -0,0 +1,103 @@ +--TEST-- +json_last_error_msg() - Error location reporting with UTF-16 surrogate pairs +--FILE-- + +--EXPECT-- +Testing error locations with UTF-16 surrogate pairs and escape sequences + +Error after UTF-16 escaped emoji: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error after multiple UTF-16 pairs: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error with mixed UTF-8 and UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error with UTF-16 in key: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,24" + +Error with multiple UTF-16 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,42" + +Error with BMP characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error with supplementary plane: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error in array with UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,22" + +Error in nested structure with UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,28" + +Error with UTF-16 and control chars: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + diff --git a/ext/json/tests/json_last_error_msg_error_location_006.phpt b/ext/json/tests/json_last_error_msg_error_location_006.phpt new file mode 100644 index 0000000000000..ac7c3337278d5 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_006.phpt @@ -0,0 +1,152 @@ +--TEST-- +json_last_error_msg() - Error location reporting edge cases +--FILE-- + +--EXPECT-- +Testing error location edge cases + +Error at position 1,1: +bool(false) +int(4) +string(12) "Syntax error" + +Error at position 1,1 with invalid char: +bool(false) +int(4) +string(30) "Syntax error near location 1,1" + +Error after leading whitespace: +bool(false) +int(4) +string(30) "Syntax error near location 1,5" + +Error with tabs and spaces: +bool(false) +int(4) +string(30) "Syntax error near location 2,3" + +Error after multiple newlines: +bool(false) +int(4) +string(30) "Syntax error near location 4,2" + +Error at end of long string: +bool(false) +int(4) +string(33) "Syntax error near location 1,1011" + +Error with very long key: +bool(false) +int(3) +string(73) "Control character error, possibly incorrectly encoded near location 1,506" + +Error after empty object: +bool(false) +int(4) +string(30) "Syntax error near location 1,3" + +Error after empty array: +bool(false) +int(4) +string(30) "Syntax error near location 1,3" + +Error with multiple root values: +bool(false) +int(4) +string(30) "Syntax error near location 1,3" + +Error after valid number: +bool(false) +int(4) +string(30) "Syntax error near location 1,4" + +Error after valid boolean: +bool(false) +int(4) +string(30) "Syntax error near location 1,5" + +Error after valid null: +bool(false) +int(4) +string(30) "Syntax error near location 1,5" + +Error after valid string: +bool(false) +int(4) +string(30) "Syntax error near location 1,7" + +Error with mixed whitespace: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 3,2" + diff --git a/ext/json/tests/json_last_error_msg_error_location_007.phpt b/ext/json/tests/json_last_error_msg_error_location_007.phpt new file mode 100644 index 0000000000000..298136a30643c --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_007.phpt @@ -0,0 +1,178 @@ +--TEST-- +json_last_error_msg() - Error location with various error types +--FILE-- + +--EXPECT-- +Testing error locations with different error types + +State mismatch - expected value: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +State mismatch - expected key: +bool(false) +int(4) +string(30) "Syntax error near location 1,2" + +State mismatch - trailing comma in object: +bool(false) +int(4) +string(31) "Syntax error near location 1,17" + +State mismatch - trailing comma in array: +bool(false) +int(4) +string(31) "Syntax error near location 1,10" + +Invalid number format - leading zero: +bool(false) +int(4) +string(31) "Syntax error near location 1,10" + +Invalid number format - multiple decimals: +bool(false) +int(4) +string(31) "Syntax error near location 1,12" + +Invalid number format - incomplete exponent: +bool(false) +int(4) +string(31) "Syntax error near location 1,10" + +Invalid number format - double sign: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Unclosed string: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,9" + +Invalid escape sequence: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Incomplete unicode escape: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Invalid unicode escape: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Invalid true keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Invalid false keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Invalid null keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + +Mismatched brackets - ] instead of }: +bool(false) +int(2) +string(61) "State mismatch (invalid or malformed JSON) near location 1,14" + +Mismatched brackets - } instead of ]: +bool(false) +int(2) +string(60) "State mismatch (invalid or malformed JSON) near location 1,7" + +Extra closing bracket: +bool(false) +int(4) +string(31) "Syntax error near location 1,15" + +Missing comma between elements: +bool(false) +int(4) +string(30) "Syntax error near location 1,4" + +Missing comma between object properties: +bool(false) +int(4) +string(30) "Syntax error near location 1,9" + diff --git a/ext/json/tests/json_last_error_msg_error_location_008.phpt b/ext/json/tests/json_last_error_msg_error_location_008.phpt new file mode 100644 index 0000000000000..8d0c6bb5cd551 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_008.phpt @@ -0,0 +1,182 @@ +--TEST-- +json_last_error_msg() - Error location with mixed UTF-8 multi-byte characters +--FILE-- + +--EXPECT-- +Testing error locations with various UTF-8 multi-byte character widths + +Error with 2-byte UTF-8 (Latin Extended): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error with 2-byte UTF-8 (Greek): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,22" + +Error with 2-byte UTF-8 (Cyrillic): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,18" + +Error with 3-byte UTF-8 (Chinese): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error with 3-byte UTF-8 (Japanese Hiragana): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,18" + +Error with 3-byte UTF-8 (Japanese Katakana): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,18" + +Error with 3-byte UTF-8 (Korean): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error with 4-byte UTF-8 (Emoji faces): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error with 4-byte UTF-8 (Emoji objects): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,13" + +Error with 4-byte UTF-8 (Mathematical symbols): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error with mixed 1-2-3 byte UTF-8: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,9" + +Error with mixed 2-3-4 byte UTF-8: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,9" + +Error with all byte widths: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,9" + +Error with UTF-8 key at start: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + +Error with multiple UTF-8 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,51" + +Error in array with mixed UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,30" + +Error in nested structure with various UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,34" + +Error with combining diacritical marks: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,11" + +Error with Hebrew: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,14" + +Error with Arabic with diacritics: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,16" + diff --git a/ext/json/tests/json_last_error_msg_error_location_009.phpt b/ext/json/tests/json_last_error_msg_error_location_009.phpt new file mode 100644 index 0000000000000..ab3fcab14ca79 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_009.phpt @@ -0,0 +1,110 @@ +--TEST-- +json_last_error_msg() - Error location with depth errors and complex nesting +--FILE-- + +--EXPECT-- +Testing error locations with depth-related issues + +Max depth error at specific location: +bool(false) +int(1) +string(47) "Maximum stack depth exceeded near location 1,21" + +Max depth error in array: +bool(false) +int(1) +string(46) "Maximum stack depth exceeded near location 1,5" + +Max depth error with mixed structures: +bool(false) +int(1) +string(46) "Maximum stack depth exceeded near location 1,7" + +Syntax error at deep nesting level: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,31" + +Syntax error in deep array: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,6" + +Error after valid deep structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,48" + +Error in middle of nested structure: +bool(false) +int(4) +string(31) "Syntax error near location 1,29" + +Error in array with nested objects: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,30" + +Error in deep UTF-8 structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,22" + +Valid deep structure within limit: +bool(true) +int(0) +string(8) "No error" + diff --git a/ext/json/tests/json_last_error_msg_error_location_010.phpt b/ext/json/tests/json_last_error_msg_error_location_010.phpt new file mode 100644 index 0000000000000..fd2597dc77c0a --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_010.phpt @@ -0,0 +1,164 @@ +--TEST-- +json_last_error_msg() - Error location with whitespace variations +--FILE-- + +--EXPECT-- +Testing error locations with various whitespace patterns + +Error after multiple spaces: +bool(false) +int(4) +string(30) "Syntax error near location 1,7" + +Error after tabs: +bool(false) +int(4) +string(30) "Syntax error near location 1,5" + +Error after mixed whitespace: +bool(false) +int(4) +string(30) "Syntax error near location 1,7" + +Error on second line: +bool(false) +int(4) +string(30) "Syntax error near location 2,2" + +Error with CRLF line endings: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 2,8" + +Error after blank lines: +bool(false) +int(4) +string(30) "Syntax error near location 4,2" + +Error in string with spaces: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1,9" + +Error with whitespace around colon: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,12" + +Error with whitespace around comma: +bool(true) +int(0) +string(8) "No error" + +Error in pretty printed JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 4,11" + +Error in heavily indented JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 5,26" + +Error with mixed tabs and spaces: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 3,12" + +Error after whitespace-only line: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 3,12" + +Error in compact JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,22" + +Error with regular spaces: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1,10" + From 448f085dc953a4875f16194ab541c29c13668f89 Mon Sep 17 00:00:00 2001 From: juan-morales Date: Mon, 1 Dec 2025 12:49:45 -0300 Subject: [PATCH 3/6] fix counting columns for utf-x characters --- ext/json/json_scanner.re | 14 +++++----- ext/json/tests/bug68546.phpt | 2 +- ...son_last_error_msg_error_location_002.phpt | 16 +++++------ ...son_last_error_msg_error_location_005.phpt | 8 +++--- ...son_last_error_msg_error_location_008.phpt | 28 +++++++++---------- ...son_last_error_msg_error_location_009.phpt | 2 +- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index 886c7a1a3000a..4e0b21864cf05 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -270,22 +270,22 @@ std: return PHP_JSON_T_ERROR; } UTF16_1 { - PHP_JSON_TOKEN_LOCATION(last_column) += 6; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 s->str_esc += 5; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 6; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 6; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 12; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //12 s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -329,15 +329,15 @@ std: PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 2; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //2 PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 3; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //3 PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 4; + PHP_JSON_TOKEN_LOCATION(last_column) += 1; //4 PHP_JSON_CONDITION_GOTO(STR_P1); } ANY { diff --git a/ext/json/tests/bug68546.phpt b/ext/json/tests/bug68546.phpt index f2ac47bea45ad..e089d09365b67 100644 --- a/ext/json/tests/bug68546.phpt +++ b/ext/json/tests/bug68546.phpt @@ -16,5 +16,5 @@ NULL bool(true) NULL bool(true) -string(55) "The decoded property name is invalid near location 1,37" +string(55) "The decoded property name is invalid near location 1,27" Done diff --git a/ext/json/tests/json_last_error_msg_error_location_002.phpt b/ext/json/tests/json_last_error_msg_error_location_002.phpt index 26a195432dd16..3397ceb6156b0 100644 --- a/ext/json/tests/json_last_error_msg_error_location_002.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_002.phpt @@ -54,22 +54,22 @@ Testing error locations with Unicode UTF-8 characters Error after Japanese characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,24" +string(72) "Control character error, possibly incorrectly encoded near location 1,12" Error after Russian characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(71) "Control character error, possibly incorrectly encoded near location 1,9" Error after Chinese characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(71) "Control character error, possibly incorrectly encoded near location 1,8" Error after Arabic characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(71) "Control character error, possibly incorrectly encoded near location 1,9" Error after Emoji: bool(false) @@ -79,7 +79,7 @@ string(72) "Control character error, possibly incorrectly encoded near location Error in mixed ASCII and UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,32" +string(72) "Control character error, possibly incorrectly encoded near location 1,27" Error with UTF-8 escaped sequences: bool(false) @@ -89,15 +89,15 @@ string(72) "Control character error, possibly incorrectly encoded near location Error in object with multiple UTF-8 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,32" +string(72) "Control character error, possibly incorrectly encoded near location 1,22" Error in array with UTF-8 strings: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,30" +string(72) "Control character error, possibly incorrectly encoded near location 1,18" Error in nested object with UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,23" +string(72) "Control character error, possibly incorrectly encoded near location 1,15" diff --git a/ext/json/tests/json_last_error_msg_error_location_005.phpt b/ext/json/tests/json_last_error_msg_error_location_005.phpt index 8560f3c5c797b..8562a74729c48 100644 --- a/ext/json/tests/json_last_error_msg_error_location_005.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_005.phpt @@ -69,12 +69,12 @@ string(72) "Control character error, possibly incorrectly encoded near location Error with UTF-16 in key: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,24" +string(71) "Control character error, possibly incorrectly encoded near location 1,9" Error with multiple UTF-16 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,42" +string(72) "Control character error, possibly incorrectly encoded near location 1,22" Error with BMP characters: bool(false) @@ -89,12 +89,12 @@ string(72) "Control character error, possibly incorrectly encoded near location Error in array with UTF-16: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1,12" Error in nested structure with UTF-16: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,28" +string(72) "Control character error, possibly incorrectly encoded near location 1,18" Error with UTF-16 and control chars: bool(false) diff --git a/ext/json/tests/json_last_error_msg_error_location_008.phpt b/ext/json/tests/json_last_error_msg_error_location_008.phpt index 8d0c6bb5cd551..613fa96bd74d2 100644 --- a/ext/json/tests/json_last_error_msg_error_location_008.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_008.phpt @@ -83,37 +83,37 @@ Testing error locations with various UTF-8 multi-byte character widths Error with 2-byte UTF-8 (Latin Extended): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1,10" Error with 2-byte UTF-8 (Greek): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1,14" Error with 2-byte UTF-8 (Cyrillic): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,18" +string(72) "Control character error, possibly incorrectly encoded near location 1,12" Error with 3-byte UTF-8 (Chinese): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(71) "Control character error, possibly incorrectly encoded near location 1,8" Error with 3-byte UTF-8 (Japanese Hiragana): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,18" +string(72) "Control character error, possibly incorrectly encoded near location 1,10" Error with 3-byte UTF-8 (Japanese Katakana): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,18" +string(72) "Control character error, possibly incorrectly encoded near location 1,10" Error with 3-byte UTF-8 (Korean): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(71) "Control character error, possibly incorrectly encoded near location 1,8" Error with 4-byte UTF-8 (Emoji faces): bool(false) @@ -148,35 +148,35 @@ string(71) "Control character error, possibly incorrectly encoded near location Error with UTF-8 key at start: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(71) "Control character error, possibly incorrectly encoded near location 1,7" Error with multiple UTF-8 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,51" +string(72) "Control character error, possibly incorrectly encoded near location 1,35" Error in array with mixed UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,30" +string(72) "Control character error, possibly incorrectly encoded near location 1,25" Error in nested structure with various UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,34" +string(72) "Control character error, possibly incorrectly encoded near location 1,22" Error with combining diacritical marks: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1,10" Error with Hebrew: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,14" +string(72) "Control character error, possibly incorrectly encoded near location 1,10" Error with Arabic with diacritics: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,16" +string(72) "Control character error, possibly incorrectly encoded near location 1,11" diff --git a/ext/json/tests/json_last_error_msg_error_location_009.phpt b/ext/json/tests/json_last_error_msg_error_location_009.phpt index ab3fcab14ca79..e51618eadc207 100644 --- a/ext/json/tests/json_last_error_msg_error_location_009.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_009.phpt @@ -101,7 +101,7 @@ string(72) "Control character error, possibly incorrectly encoded near location Error in deep UTF-8 structure: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1,16" Valid deep structure within limit: bool(true) From d55103edb098ffc12288a78212a26b2e8ab6207f Mon Sep 17 00:00:00 2001 From: juan-morales Date: Tue, 2 Dec 2025 09:29:18 -0300 Subject: [PATCH 4/6] int to size_t --- ext/json/json.c | 12 ++++++------ ext/json/json_parser.y | 4 ++-- ext/json/json_scanner.re | 14 +++++++------- ext/json/php_json.h | 4 ++-- ext/json/php_json_parser.h | 12 ++++++------ 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ext/json/json.c b/ext/json/json.c index 09a4a997c18f2..da714753012da 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -181,12 +181,12 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ -static zend_string *php_json_get_error_msg_with_location(php_json_error_code error_code, int line, int column) /* {{{ */ +static zend_string *php_json_get_error_msg_with_location(php_json_error_code error_code, size_t line, size_t column) /* {{{ */ { const char *base_msg = php_json_get_error_msg(error_code); if (line > 0 && column > 0) { - return zend_strpprintf(0, "%s near location %d,%d", base_msg, line, column); + return zend_strpprintf(0, "%s near location %u,%u", base_msg, line, column); } return zend_string_init(base_msg, strlen(base_msg), 0); @@ -201,8 +201,8 @@ PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); - int error_line = php_json_parser_error_line(&parser); - int error_column = php_json_parser_error_column(&parser); + size_t error_line = php_json_parser_error_line(&parser); + size_t error_column = php_json_parser_error_column(&parser); if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = error_code; @@ -231,8 +231,8 @@ PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_lon if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); - int error_line = php_json_parser_error_line(&parser); - int error_column = php_json_parser_error_column(&parser); + size_t error_line = php_json_parser_error_line(&parser); + size_t error_column = php_json_parser_error_column(&parser); JSON_G(error_code) = error_code; JSON_G(error_line) = error_line; diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index 98a4b9bd0e319..8a8eca871fdec 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -318,12 +318,12 @@ PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parse return parser->scanner.errcode; } -PHP_JSON_API int php_json_parser_error_line(const php_json_parser *parser) +PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser) { return parser->scanner.errloc.first_line; } -PHP_JSON_API int php_json_parser_error_column(const php_json_parser *parser) +PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser) { return parser->scanner.errloc.first_column; } diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index 4e0b21864cf05..e365c834e2ed9 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -270,22 +270,22 @@ std: return PHP_JSON_T_ERROR; } UTF16_1 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 5; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //6 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //12 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -329,15 +329,15 @@ std: PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_2 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //2 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_3 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //3 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF8_4 { - PHP_JSON_TOKEN_LOCATION(last_column) += 1; //4 + PHP_JSON_TOKEN_LOCATION(last_column) += 1; PHP_JSON_CONDITION_GOTO(STR_P1); } ANY { diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 6111620130d8e..bbe8be9d60ada 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -86,8 +86,8 @@ ZEND_BEGIN_MODULE_GLOBALS(json) int encoder_depth; int encode_max_depth; php_json_error_code error_code; - int error_line; - int error_column; + size_t error_line; + size_t error_column; ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) diff --git a/ext/json/php_json_parser.h b/ext/json/php_json_parser.h index 13b22fff413ca..8fee3d11c6bf8 100644 --- a/ext/json/php_json_parser.h +++ b/ext/json/php_json_parser.h @@ -51,10 +51,10 @@ typedef struct _php_json_parser_methods { } php_json_parser_methods; typedef struct _php_json_parser_location { - int first_line; - int first_column; - int last_line; - int last_column; + size_t first_line; + size_t first_column; + size_t last_line; + size_t last_column; } php_json_parser_location; struct _php_json_parser { @@ -85,9 +85,9 @@ PHP_JSON_API void php_json_parser_init( PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser); -PHP_JSON_API int php_json_parser_error_line(const php_json_parser *parser); +PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser); -PHP_JSON_API int php_json_parser_error_column(const php_json_parser *parser); +PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser); PHP_JSON_API int php_json_parse(php_json_parser *parser); From b5e5a01b6760c8cd2651f54fcf12416bfbfb40dc Mon Sep 17 00:00:00 2001 From: juan-morales Date: Tue, 2 Dec 2025 09:35:03 -0300 Subject: [PATCH 5/6] json.c - fix parameter type passed to print fnction --- ext/json/json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/json.c b/ext/json/json.c index da714753012da..9ae7ea9c56ec6 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -186,7 +186,7 @@ static zend_string *php_json_get_error_msg_with_location(php_json_error_code err const char *base_msg = php_json_get_error_msg(error_code); if (line > 0 && column > 0) { - return zend_strpprintf(0, "%s near location %u,%u", base_msg, line, column); + return zend_strpprintf(0, "%s near location %zu,%zu", base_msg, line, column); } return zend_string_init(base_msg, strlen(base_msg), 0); From 6578f09925933cc20a1b602d87830313c731ff73 Mon Sep 17 00:00:00 2001 From: juan-morales Date: Tue, 2 Dec 2025 12:38:42 -0300 Subject: [PATCH 6/6] format row:col --- ext/json/json.c | 2 +- ext/json/tests/007.phpt | 8 +-- ext/json/tests/bug62010.phpt | 2 +- ext/json/tests/bug68546.phpt | 2 +- ext/json/tests/json_decode_exceptions.phpt | 2 +- ...son_last_error_msg_error_location_001.phpt | 72 +++++++++---------- ...son_last_error_msg_error_location_002.phpt | 20 +++--- ...son_last_error_msg_error_location_003.phpt | 8 +-- ...son_last_error_msg_error_location_004.phpt | 10 +-- ...son_last_error_msg_error_location_005.phpt | 20 +++--- ...son_last_error_msg_error_location_006.phpt | 38 +++++----- ...son_last_error_msg_error_location_007.phpt | 40 +++++------ ...son_last_error_msg_error_location_008.phpt | 40 +++++------ ...son_last_error_msg_error_location_009.phpt | 18 ++--- ...son_last_error_msg_error_location_010.phpt | 28 ++++---- ext/json/tests/json_validate_002.phpt | 6 +- ext/json/tests/json_validate_004.phpt | 8 +-- 17 files changed, 162 insertions(+), 162 deletions(-) diff --git a/ext/json/json.c b/ext/json/json.c index 9ae7ea9c56ec6..1c7e3219026eb 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -186,7 +186,7 @@ static zend_string *php_json_get_error_msg_with_location(php_json_error_code err const char *base_msg = php_json_get_error_msg(error_code); if (line > 0 && column > 0) { - return zend_strpprintf(0, "%s near location %zu,%zu", base_msg, line, column); + return zend_strpprintf(0, "%s near location %zu:%zu", base_msg, line, column); } return zend_string_init(base_msg, strlen(base_msg), 0); diff --git a/ext/json/tests/007.phpt b/ext/json/tests/007.phpt index 062bbab457de7..9a5ae654d6361 100644 --- a/ext/json/tests/007.phpt +++ b/ext/json/tests/007.phpt @@ -24,14 +24,14 @@ int(0) string(8) "No error" NULL int(1) -string(46) "Maximum stack depth exceeded near location 1,2" +string(46) "Maximum stack depth exceeded near location 1:2" NULL int(2) -string(60) "State mismatch (invalid or malformed JSON) near location 1,3" +string(60) "State mismatch (invalid or malformed JSON) near location 1:3" NULL int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,2" +string(71) "Control character error, possibly incorrectly encoded near location 1:2" NULL int(4) -string(30) "Syntax error near location 1,3" +string(30) "Syntax error near location 1:3" Done diff --git a/ext/json/tests/bug62010.phpt b/ext/json/tests/bug62010.phpt index c013087608417..862d7dc7e2c00 100644 --- a/ext/json/tests/bug62010.phpt +++ b/ext/json/tests/bug62010.phpt @@ -10,4 +10,4 @@ var_dump(json_last_error_msg()); --EXPECT-- NULL bool(true) -string(68) "Single unpaired UTF-16 surrogate in unicode escape near location 1,1" +string(68) "Single unpaired UTF-16 surrogate in unicode escape near location 1:1" diff --git a/ext/json/tests/bug68546.phpt b/ext/json/tests/bug68546.phpt index e089d09365b67..1847eabf3a8e3 100644 --- a/ext/json/tests/bug68546.phpt +++ b/ext/json/tests/bug68546.phpt @@ -16,5 +16,5 @@ NULL bool(true) NULL bool(true) -string(55) "The decoded property name is invalid near location 1,27" +string(55) "The decoded property name is invalid near location 1:27" Done diff --git a/ext/json/tests/json_decode_exceptions.phpt b/ext/json/tests/json_decode_exceptions.phpt index 3a263ff806ca7..d53941682e454 100644 --- a/ext/json/tests/json_decode_exceptions.phpt +++ b/ext/json/tests/json_decode_exceptions.phpt @@ -13,7 +13,7 @@ try { --EXPECTF-- object(JsonException)#1 (7) { ["message":protected]=> - string(30) "Syntax error near location 1,2" + string(30) "Syntax error near location 1:2" ["string":"Exception":private]=> string(0) "" ["code":protected]=> diff --git a/ext/json/tests/json_last_error_msg_error_location_001.phpt b/ext/json/tests/json_last_error_msg_error_location_001.phpt index 269eab0ed7bbe..e0553f9f7d651 100644 --- a/ext/json/tests/json_last_error_msg_error_location_001.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_001.phpt @@ -8,114 +8,114 @@ require_once("json_validate_requires.inc"); echo "Testing errors at various locations with ASCII characters\n\n"; // Error at start -echo "Error at position 1,1:\n"; +echo "Error at position 1:1:\n"; json_validate_trycatchdump("-"); // Error in middle of simple object -echo "\nError at position 1,10:\n"; +echo "\nError at position 1:10:\n"; json_validate_trycatchdump('{"name": "value}'); // Missing colon -echo "\nError at position 1,9:\n"; +echo "\nError at position 1:9:\n"; json_validate_trycatchdump('{"name" "value"}'); // Extra comma -echo "\nError at position 1,16:\n"; +echo "\nError at position 1:16:\n"; json_validate_trycatchdump('{"name": "val",}'); // Missing closing bracket in array -echo "\nError at position 1,15:\n"; +echo "\nError at position 1:15:\n"; json_validate_trycatchdump('[1, 2, 3, 4, 5'); // Invalid value -echo "\nError at position 1,10:\n"; +echo "\nError at position 1:10:\n"; json_validate_trycatchdump('{"test": undefined}'); // Trailing comma in array -echo "\nError at position 1,7:\n"; +echo "\nError at position 1:7:\n"; json_validate_trycatchdump('[1, 2,]'); // Single quote instead of double quote -echo "\nError at position 1,2:\n"; +echo "\nError at position 1:2:\n"; json_validate_trycatchdump("{'key': 'value'}"); // Missing closing brace -echo "\nError at position 1,16:\n"; +echo "\nError at position 1:16:\n"; json_validate_trycatchdump('{"key": "value"'); // Double comma -echo "\nError at position 1,4:\n"; +echo "\nError at position 1:4:\n"; json_validate_trycatchdump('[1,, 2]'); // Invalid escape sequence -echo "\nError at position 1,10:\n"; +echo "\nError at position 1:10:\n"; json_validate_trycatchdump('{"test": "\x"}'); // Unescaped control character -echo "\nError at position 1,10:\n"; +echo "\nError at position 1:10:\n"; json_validate_trycatchdump('{"test": "' . "\n" . '"}'); ?> --EXPECT-- Testing errors at various locations with ASCII characters -Error at position 1,1: +Error at position 1:1: bool(false) int(4) -string(30) "Syntax error near location 1,1" +string(30) "Syntax error near location 1:1" -Error at position 1,10: +Error at position 1:10: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" -Error at position 1,9: +Error at position 1:9: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" -Error at position 1,16: +Error at position 1:16: bool(false) int(4) -string(31) "Syntax error near location 1,16" +string(31) "Syntax error near location 1:16" -Error at position 1,15: +Error at position 1:15: bool(false) int(4) -string(31) "Syntax error near location 1,15" +string(31) "Syntax error near location 1:15" -Error at position 1,10: +Error at position 1:10: bool(false) int(4) -string(31) "Syntax error near location 1,10" +string(31) "Syntax error near location 1:10" -Error at position 1,7: +Error at position 1:7: bool(false) int(4) -string(30) "Syntax error near location 1,7" +string(30) "Syntax error near location 1:7" -Error at position 1,2: +Error at position 1:2: bool(false) int(4) -string(30) "Syntax error near location 1,2" +string(30) "Syntax error near location 1:2" -Error at position 1,16: +Error at position 1:16: bool(false) int(4) -string(31) "Syntax error near location 1,16" +string(31) "Syntax error near location 1:16" -Error at position 1,4: +Error at position 1:4: bool(false) int(4) -string(30) "Syntax error near location 1,4" +string(30) "Syntax error near location 1:4" -Error at position 1,10: +Error at position 1:10: bool(false) int(4) -string(31) "Syntax error near location 1,10" +string(31) "Syntax error near location 1:10" -Error at position 1,10: +Error at position 1:10: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" diff --git a/ext/json/tests/json_last_error_msg_error_location_002.phpt b/ext/json/tests/json_last_error_msg_error_location_002.phpt index 3397ceb6156b0..df7fc981ccbab 100644 --- a/ext/json/tests/json_last_error_msg_error_location_002.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_002.phpt @@ -54,50 +54,50 @@ Testing error locations with Unicode UTF-8 characters Error after Japanese characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(72) "Control character error, possibly incorrectly encoded near location 1:12" Error after Russian characters: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error after Chinese characters: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,8" +string(71) "Control character error, possibly incorrectly encoded near location 1:8" Error after Arabic characters: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error after Emoji: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" Error in mixed ASCII and UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,27" +string(72) "Control character error, possibly incorrectly encoded near location 1:27" Error with UTF-8 escaped sequences: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error in object with multiple UTF-8 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1:22" Error in array with UTF-8 strings: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,18" +string(72) "Control character error, possibly incorrectly encoded near location 1:18" Error in nested object with UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,15" +string(72) "Control character error, possibly incorrectly encoded near location 1:15" diff --git a/ext/json/tests/json_last_error_msg_error_location_003.phpt b/ext/json/tests/json_last_error_msg_error_location_003.phpt index bafc87b7af259..ec5e6b9b4d651 100644 --- a/ext/json/tests/json_last_error_msg_error_location_003.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_003.phpt @@ -53,20 +53,20 @@ Testing error locations in multi-line JSON Error on line 2, column 13: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 2,13" +string(72) "Control character error, possibly incorrectly encoded near location 2:13" Error on line 3, column 12: bool(false) int(4) -string(31) "Syntax error near location 3,12" +string(31) "Syntax error near location 3:12" Error on line 5, column 26: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 5,26" +string(72) "Control character error, possibly incorrectly encoded near location 5:26" Error on line 7, column 1: bool(false) int(4) -string(30) "Syntax error near location 7,1" +string(30) "Syntax error near location 7:1" diff --git a/ext/json/tests/json_last_error_msg_error_location_004.phpt b/ext/json/tests/json_last_error_msg_error_location_004.phpt index 1044f77aa4b0e..165449600fb39 100644 --- a/ext/json/tests/json_last_error_msg_error_location_004.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_004.phpt @@ -54,7 +54,7 @@ Testing error locations in deeply nested structures Error in deeply nested object: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,31" +string(72) "Control character error, possibly incorrectly encoded near location 1:31" Error in deeply nested array: bool(true) @@ -74,20 +74,20 @@ string(8) "No error" Error in middle of deep nesting: bool(false) int(4) -string(31) "Syntax error near location 1,21" +string(31) "Syntax error near location 1:21" Error in complex structure: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,93" +string(72) "Control character error, possibly incorrectly encoded near location 1:93" Error in array of objects: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,68" +string(72) "Control character error, possibly incorrectly encoded near location 1:68" Error in object with array values: bool(false) int(2) -string(61) "State mismatch (invalid or malformed JSON) near location 1,82" +string(61) "State mismatch (invalid or malformed JSON) near location 1:82" diff --git a/ext/json/tests/json_last_error_msg_error_location_005.phpt b/ext/json/tests/json_last_error_msg_error_location_005.phpt index 8562a74729c48..d12ce387e73ea 100644 --- a/ext/json/tests/json_last_error_msg_error_location_005.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_005.phpt @@ -54,50 +54,50 @@ Testing error locations with UTF-16 surrogate pairs and escape sequences Error after UTF-16 escaped emoji: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" Error after multiple UTF-16 pairs: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with mixed UTF-8 and UTF-16: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" Error with UTF-16 in key: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error with multiple UTF-16 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1:22" Error with BMP characters: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with supplementary plane: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" Error in array with UTF-16: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(72) "Control character error, possibly incorrectly encoded near location 1:12" Error in nested structure with UTF-16: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,18" +string(72) "Control character error, possibly incorrectly encoded near location 1:18" Error with UTF-16 and control chars: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" diff --git a/ext/json/tests/json_last_error_msg_error_location_006.phpt b/ext/json/tests/json_last_error_msg_error_location_006.phpt index ac7c3337278d5..e6aab1af8f27e 100644 --- a/ext/json/tests/json_last_error_msg_error_location_006.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_006.phpt @@ -8,11 +8,11 @@ require_once("json_validate_requires.inc"); echo "Testing error location edge cases\n\n"; // Error at very start -echo "Error at position 1,1:\n"; +echo "Error at position 1:1:\n"; json_validate_trycatchdump(''); -// Error at position 1,1 with single character -echo "\nError at position 1,1 with invalid char:\n"; +// Error at position 1:1 with single character +echo "\nError at position 1:1 with invalid char:\n"; json_validate_trycatchdump('x'); // Error after whitespace @@ -75,78 +75,78 @@ json_validate_trycatchdump("{\n\t\"key\": \n\t\"value\n}"); --EXPECT-- Testing error location edge cases -Error at position 1,1: +Error at position 1:1: bool(false) int(4) string(12) "Syntax error" -Error at position 1,1 with invalid char: +Error at position 1:1 with invalid char: bool(false) int(4) -string(30) "Syntax error near location 1,1" +string(30) "Syntax error near location 1:1" Error after leading whitespace: bool(false) int(4) -string(30) "Syntax error near location 1,5" +string(30) "Syntax error near location 1:5" Error with tabs and spaces: bool(false) int(4) -string(30) "Syntax error near location 2,3" +string(30) "Syntax error near location 2:3" Error after multiple newlines: bool(false) int(4) -string(30) "Syntax error near location 4,2" +string(30) "Syntax error near location 4:2" Error at end of long string: bool(false) int(4) -string(33) "Syntax error near location 1,1011" +string(33) "Syntax error near location 1:1011" Error with very long key: bool(false) int(3) -string(73) "Control character error, possibly incorrectly encoded near location 1,506" +string(73) "Control character error, possibly incorrectly encoded near location 1:506" Error after empty object: bool(false) int(4) -string(30) "Syntax error near location 1,3" +string(30) "Syntax error near location 1:3" Error after empty array: bool(false) int(4) -string(30) "Syntax error near location 1,3" +string(30) "Syntax error near location 1:3" Error with multiple root values: bool(false) int(4) -string(30) "Syntax error near location 1,3" +string(30) "Syntax error near location 1:3" Error after valid number: bool(false) int(4) -string(30) "Syntax error near location 1,4" +string(30) "Syntax error near location 1:4" Error after valid boolean: bool(false) int(4) -string(30) "Syntax error near location 1,5" +string(30) "Syntax error near location 1:5" Error after valid null: bool(false) int(4) -string(30) "Syntax error near location 1,5" +string(30) "Syntax error near location 1:5" Error after valid string: bool(false) int(4) -string(30) "Syntax error near location 1,7" +string(30) "Syntax error near location 1:7" Error with mixed whitespace: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 3,2" +string(71) "Control character error, possibly incorrectly encoded near location 3:2" diff --git a/ext/json/tests/json_last_error_msg_error_location_007.phpt b/ext/json/tests/json_last_error_msg_error_location_007.phpt index 298136a30643c..0e24889bbbbeb 100644 --- a/ext/json/tests/json_last_error_msg_error_location_007.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_007.phpt @@ -79,100 +79,100 @@ Testing error locations with different error types State mismatch - expected value: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" State mismatch - expected key: bool(false) int(4) -string(30) "Syntax error near location 1,2" +string(30) "Syntax error near location 1:2" State mismatch - trailing comma in object: bool(false) int(4) -string(31) "Syntax error near location 1,17" +string(31) "Syntax error near location 1:17" State mismatch - trailing comma in array: bool(false) int(4) -string(31) "Syntax error near location 1,10" +string(31) "Syntax error near location 1:10" Invalid number format - leading zero: bool(false) int(4) -string(31) "Syntax error near location 1,10" +string(31) "Syntax error near location 1:10" Invalid number format - multiple decimals: bool(false) int(4) -string(31) "Syntax error near location 1,12" +string(31) "Syntax error near location 1:12" Invalid number format - incomplete exponent: bool(false) int(4) -string(31) "Syntax error near location 1,10" +string(31) "Syntax error near location 1:10" Invalid number format - double sign: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Unclosed string: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Invalid escape sequence: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Incomplete unicode escape: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Invalid unicode escape: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Invalid true keyword: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Invalid false keyword: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Invalid null keyword: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" Mismatched brackets - ] instead of }: bool(false) int(2) -string(61) "State mismatch (invalid or malformed JSON) near location 1,14" +string(61) "State mismatch (invalid or malformed JSON) near location 1:14" Mismatched brackets - } instead of ]: bool(false) int(2) -string(60) "State mismatch (invalid or malformed JSON) near location 1,7" +string(60) "State mismatch (invalid or malformed JSON) near location 1:7" Extra closing bracket: bool(false) int(4) -string(31) "Syntax error near location 1,15" +string(31) "Syntax error near location 1:15" Missing comma between elements: bool(false) int(4) -string(30) "Syntax error near location 1,4" +string(30) "Syntax error near location 1:4" Missing comma between object properties: bool(false) int(4) -string(30) "Syntax error near location 1,9" +string(30) "Syntax error near location 1:9" diff --git a/ext/json/tests/json_last_error_msg_error_location_008.phpt b/ext/json/tests/json_last_error_msg_error_location_008.phpt index 613fa96bd74d2..4d8a1012316b4 100644 --- a/ext/json/tests/json_last_error_msg_error_location_008.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_008.phpt @@ -83,100 +83,100 @@ Testing error locations with various UTF-8 multi-byte character widths Error with 2-byte UTF-8 (Latin Extended): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with 2-byte UTF-8 (Greek): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,14" +string(72) "Control character error, possibly incorrectly encoded near location 1:14" Error with 2-byte UTF-8 (Cyrillic): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(72) "Control character error, possibly incorrectly encoded near location 1:12" Error with 3-byte UTF-8 (Chinese): bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,8" +string(71) "Control character error, possibly incorrectly encoded near location 1:8" Error with 3-byte UTF-8 (Japanese Hiragana): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with 3-byte UTF-8 (Japanese Katakana): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with 3-byte UTF-8 (Korean): bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,8" +string(71) "Control character error, possibly incorrectly encoded near location 1:8" Error with 4-byte UTF-8 (Emoji faces): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" Error with 4-byte UTF-8 (Emoji objects): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,13" +string(72) "Control character error, possibly incorrectly encoded near location 1:13" Error with 4-byte UTF-8 (Mathematical symbols): bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with mixed 1-2-3 byte UTF-8: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error with mixed 2-3-4 byte UTF-8: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error with all byte widths: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error with UTF-8 key at start: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,7" +string(71) "Control character error, possibly incorrectly encoded near location 1:7" Error with multiple UTF-8 keys: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,35" +string(72) "Control character error, possibly incorrectly encoded near location 1:35" Error in array with mixed UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,25" +string(72) "Control character error, possibly incorrectly encoded near location 1:25" Error in nested structure with various UTF-8: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1:22" Error with combining diacritical marks: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with Hebrew: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" Error with Arabic with diacritics: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,11" +string(72) "Control character error, possibly incorrectly encoded near location 1:11" diff --git a/ext/json/tests/json_last_error_msg_error_location_009.phpt b/ext/json/tests/json_last_error_msg_error_location_009.phpt index e51618eadc207..406179693ef69 100644 --- a/ext/json/tests/json_last_error_msg_error_location_009.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_009.phpt @@ -61,47 +61,47 @@ Testing error locations with depth-related issues Max depth error at specific location: bool(false) int(1) -string(47) "Maximum stack depth exceeded near location 1,21" +string(47) "Maximum stack depth exceeded near location 1:21" Max depth error in array: bool(false) int(1) -string(46) "Maximum stack depth exceeded near location 1,5" +string(46) "Maximum stack depth exceeded near location 1:5" Max depth error with mixed structures: bool(false) int(1) -string(46) "Maximum stack depth exceeded near location 1,7" +string(46) "Maximum stack depth exceeded near location 1:7" Syntax error at deep nesting level: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,31" +string(72) "Control character error, possibly incorrectly encoded near location 1:31" Syntax error in deep array: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,6" +string(71) "Control character error, possibly incorrectly encoded near location 1:6" Error after valid deep structure: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,48" +string(72) "Control character error, possibly incorrectly encoded near location 1:48" Error in middle of nested structure: bool(false) int(4) -string(31) "Syntax error near location 1,29" +string(31) "Syntax error near location 1:29" Error in array with nested objects: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,30" +string(72) "Control character error, possibly incorrectly encoded near location 1:30" Error in deep UTF-8 structure: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,16" +string(72) "Control character error, possibly incorrectly encoded near location 1:16" Valid deep structure within limit: bool(true) diff --git a/ext/json/tests/json_last_error_msg_error_location_010.phpt b/ext/json/tests/json_last_error_msg_error_location_010.phpt index fd2597dc77c0a..1085702058387 100644 --- a/ext/json/tests/json_last_error_msg_error_location_010.phpt +++ b/ext/json/tests/json_last_error_msg_error_location_010.phpt @@ -90,42 +90,42 @@ Testing error locations with various whitespace patterns Error after multiple spaces: bool(false) int(4) -string(30) "Syntax error near location 1,7" +string(30) "Syntax error near location 1:7" Error after tabs: bool(false) int(4) -string(30) "Syntax error near location 1,5" +string(30) "Syntax error near location 1:5" Error after mixed whitespace: bool(false) int(4) -string(30) "Syntax error near location 1,7" +string(30) "Syntax error near location 1:7" Error on second line: bool(false) int(4) -string(30) "Syntax error near location 2,2" +string(30) "Syntax error near location 2:2" Error with CRLF line endings: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 2,8" +string(71) "Control character error, possibly incorrectly encoded near location 2:8" Error after blank lines: bool(false) int(4) -string(30) "Syntax error near location 4,2" +string(30) "Syntax error near location 4:2" Error in string with spaces: bool(false) int(3) -string(71) "Control character error, possibly incorrectly encoded near location 1,9" +string(71) "Control character error, possibly incorrectly encoded near location 1:9" Error with whitespace around colon: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,12" +string(72) "Control character error, possibly incorrectly encoded near location 1:12" Error with whitespace around comma: bool(true) @@ -135,30 +135,30 @@ string(8) "No error" Error in pretty printed JSON: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 4,11" +string(72) "Control character error, possibly incorrectly encoded near location 4:11" Error in heavily indented JSON: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 5,26" +string(72) "Control character error, possibly incorrectly encoded near location 5:26" Error with mixed tabs and spaces: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 3,12" +string(72) "Control character error, possibly incorrectly encoded near location 3:12" Error after whitespace-only line: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 3,12" +string(72) "Control character error, possibly incorrectly encoded near location 3:12" Error in compact JSON: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,22" +string(72) "Control character error, possibly incorrectly encoded near location 1:22" Error with regular spaces: bool(false) int(3) -string(72) "Control character error, possibly incorrectly encoded near location 1,10" +string(72) "Control character error, possibly incorrectly encoded near location 1:10" diff --git a/ext/json/tests/json_validate_002.phpt b/ext/json/tests/json_validate_002.phpt index e2c0d6ff435aa..423564c4ad7c4 100644 --- a/ext/json/tests/json_validate_002.phpt +++ b/ext/json/tests/json_validate_002.phpt @@ -23,13 +23,13 @@ int(4) string(12) "Syntax error" bool(false) int(4) -string(30) "Syntax error near location 1,1" +string(30) "Syntax error near location 1:1" bool(false) int(4) string(12) "Syntax error" bool(false) int(1) -string(46) "Maximum stack depth exceeded near location 1,1" +string(46) "Maximum stack depth exceeded near location 1:1" bool(true) int(0) string(8) "No error" @@ -44,7 +44,7 @@ int(0) string(8) "No error" bool(false) int(4) -string(30) "Syntax error near location 1,1" +string(30) "Syntax error near location 1:1" bool(true) int(0) string(8) "No error" diff --git a/ext/json/tests/json_validate_004.phpt b/ext/json/tests/json_validate_004.phpt index c8807943c32f0..bd807defa1404 100644 --- a/ext/json/tests/json_validate_004.phpt +++ b/ext/json/tests/json_validate_004.phpt @@ -23,16 +23,16 @@ json_validate_trycatchdump("[\"\xc1\xc1\",\"a\"]", 512, JSON_INVALID_UTF8_IGNORE Testing Invalid UTF-8 bool(false) int(5) -string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,1" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1,2" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:2" bool(true) int(0) string(8) "No error"