Skip to content

Commit 05f2fc5

Browse files
committed
counts ok
1 parent 70024b7 commit 05f2fc5

File tree

6 files changed

+86
-14
lines changed

6 files changed

+86
-14
lines changed

ext/json/json.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,8 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{
159159
return "Control character error, possibly incorrectly encoded";
160160
case PHP_JSON_ERROR_SYNTAX:
161161
char *msg;
162-
spprintf(&msg, 0, "Syntax error at character %zu", JSON_G(error_pos));
162+
spprintf(&msg, 0, "Syntax error near character %zu", JSON_G(error_pos));
163163
return msg;
164-
//efree(msg);
165-
//return "Syntax error";
166164
case PHP_JSON_ERROR_UTF8:
167165
return "Malformed UTF-8 characters, possibly incorrectly encoded";
168166
case PHP_JSON_ERROR_RECURSION:

ext/json/json_parser.y

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ int json_yydebug = 1;
3535
#define PHP_JSON_DEPTH_INC \
3636
if (parser->max_depth && parser->depth >= parser->max_depth) { \
3737
parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \
38+
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
3839
YYERROR; \
3940
} \
4041
++parser->depth
@@ -108,6 +109,7 @@ object_end:
108109
| ']'
109110
{
110111
parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
112+
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
111113
YYERROR;
112114
}
113115
;
@@ -164,6 +166,7 @@ array_end:
164166
| '}'
165167
{
166168
parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
169+
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
167170
YYERROR;
168171
}
169172
;
@@ -242,6 +245,7 @@ static int php_json_parser_object_update(php_json_parser *parser, zval *object,
242245
} else {
243246
if (ZSTR_LEN(key) > 0 && ZSTR_VAL(key)[0] == '\0') {
244247
parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME;
248+
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
245249
zend_string_release_ex(key, 0);
246250
zval_ptr_dtor_nogc(zvalue);
247251
zval_ptr_dtor_nogc(object);
@@ -300,7 +304,9 @@ static void php_json_yyerror(php_json_parser *parser, char const *msg)
300304
{
301305
if (!parser->scanner.errcode) {
302306
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
303-
parser->scanner.errpos = (size_t)(parser->scanner.cursor - parser->scanner.str_start);
307+
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start);
308+
fprintf(stderr, "End of input: errpos=%zu, cursor=%p, str_start=%p\n", parser->scanner.errpos, parser->scanner.cursor, parser->scanner.str_start);
309+
//parser->scanner.errpos = (size_t)(parser->scanner.cursor - parser->scanner.str_start);
304310
}
305311
}
306312

@@ -346,12 +352,20 @@ PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser,
346352
int max_depth,
347353
const php_json_parser_methods *parser_methods)
348354
{
355+
349356
memset(parser, 0, sizeof(php_json_parser));
350357
php_json_scanner_init(&parser->scanner, str, str_len, options);
351358
parser->depth = 1;
352359
parser->max_depth = max_depth;
353360
parser->return_value = return_value;
354361
memcpy(&parser->methods, parser_methods, sizeof(php_json_parser_methods));
362+
363+
if (!str || str_len == 0) {
364+
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
365+
parser->scanner.errpos = 0;
366+
}
367+
368+
fprintf(stderr, "Init: str_start=%p, cursor=%p, limit=%p, str_len=%zu\n", parser->scanner.str_start, parser->scanner.cursor, parser->scanner.limit, str_len);
355369
}
356370

357371
PHP_JSON_API void php_json_parser_init(php_json_parser *parser,

ext/json/json_scanner.re

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,24 @@ static int php_json_ucs2_to_int(php_json_scanner *s, int size)
9393

9494
void php_json_scanner_init(php_json_scanner *s, const char *str, size_t str_len, int options)
9595
{
96+
s->token = NULL;
97+
s->marker = NULL;
98+
s->ctxmarker = NULL;
99+
s->pstr = NULL;
100+
s->str_esc = 0;
101+
s->state = 0;
102+
s->errcode = PHP_JSON_ERROR_NONE;
103+
s->errpos = 0; /* Initialize errpos */
104+
s->utf8_invalid = 0;
105+
s->utf8_invalid_count = 0;
106+
s->str_start = (php_json_ctype *)str; /* Initialize str_start */
107+
s->input_start = (php_json_ctype *)str; /* Initialize str_start */
108+
96109
s->cursor = (php_json_ctype *) str;
97110
s->limit = (php_json_ctype *) str + str_len;
98111
s->options = options;
112+
s->errpos = 0;
113+
s->errcode = 0;
99114
PHP_JSON_CONDITION_SET(JS);
100115
}
101116

@@ -106,6 +121,29 @@ int php_json_scan(php_json_scanner *s)
106121
std:
107122
s->token = s->cursor;
108123

124+
fprintf(stderr, "Scan: START=%p \n cursor=%p \n token=%p \n str_start=%p \n limit=%p \n value_START='%.*s' \n value_token='%.*s' \n value_cursor='%.*s' \n value_str_start='%.*s' \n",
125+
s->input_start,
126+
s->cursor,
127+
s->token,
128+
s->str_start,
129+
s->limit,
130+
(int)(s->limit - s->input_start),
131+
s->input_start,
132+
(int)(s->limit - s->token),
133+
s->token,
134+
(int)(s->limit - s->cursor),
135+
s->cursor,
136+
(int)(s->limit - s->str_start),
137+
s->str_start
138+
);
139+
140+
if (s->cursor >= s->limit) {
141+
s->errcode = PHP_JSON_ERROR_SYNTAX;
142+
s->errpos = (size_t)(s->str_start - s->input_start);
143+
fprintf(stderr, "End of input: errpos=%zu, cursor=%p, str_start=%p\n", s->errpos, s->cursor, s->str_start);
144+
return PHP_JSON_T_ERROR;
145+
}
146+
109147
/*!re2c
110148
re2c:indent:top = 1;
111149
re2c:yyfill:enable = 0;
@@ -201,6 +239,7 @@ std:
201239
return PHP_JSON_T_EOI;
202240
} else {
203241
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
242+
s->errpos = (size_t)(s->str_start - s->input_start);
204243
return PHP_JSON_T_ERROR;
205244
}
206245
}
@@ -213,19 +252,25 @@ std:
213252
}
214253
<JS>CTRL {
215254
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
255+
s->errpos = (size_t)(s->str_start - s->input_start);
216256
return PHP_JSON_T_ERROR;
217257
}
218258
<JS>UTF8 {
219259
s->errcode = PHP_JSON_ERROR_SYNTAX;
260+
s->errpos = (size_t)(s->str_start - s->input_start);
261+
fprintf(stderr, "Syntax error: errpos=%zu, cursor=%p, str_start=%p\n",
262+
s->errpos, s->cursor, s->str_start);
220263
return PHP_JSON_T_ERROR;
221264
}
222265
<JS>ANY {
223266
s->errcode = PHP_JSON_ERROR_UTF8;
267+
s->errpos = (size_t)(s->str_start - s->input_start);
224268
return PHP_JSON_T_ERROR;
225269
}
226270
227271
<STR_P1>CTRL {
228272
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
273+
s->errpos = (size_t)(s->str_start - s->input_start);
229274
return PHP_JSON_T_ERROR;
230275
}
231276
<STR_P1>UTF16_1 {
@@ -246,6 +291,7 @@ std:
246291
}
247292
<STR_P1>UCS2 {
248293
s->errcode = PHP_JSON_ERROR_UTF16;
294+
s->errpos = (size_t)(s->str_start - s->input_start);
249295
return PHP_JSON_T_ERROR;
250296
}
251297
<STR_P1>ESC {
@@ -254,6 +300,9 @@ std:
254300
}
255301
<STR_P1>ESCPREF {
256302
s->errcode = PHP_JSON_ERROR_SYNTAX;
303+
s->errpos = (size_t)(s->str_start - s->input_start);
304+
fprintf(stderr, "Syntax error: errpos=%zu, cursor=%p, str_start=%p\n",
305+
s->errpos, s->cursor, s->str_start);
257306
return PHP_JSON_T_ERROR;
258307
}
259308
<STR_P1>["] {
@@ -283,6 +332,7 @@ std:
283332
if (s->options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) {
284333
if (s->utf8_invalid_count > INT_MAX - 2) {
285334
s->errcode = PHP_JSON_ERROR_UTF8;
335+
s->errpos = (size_t)(s->str_start - s->input_start);
286336
return PHP_JSON_T_ERROR;
287337
}
288338
s->utf8_invalid_count += 2;
@@ -293,6 +343,7 @@ std:
293343
PHP_JSON_CONDITION_GOTO(STR_P1);
294344
}
295345
s->errcode = PHP_JSON_ERROR_UTF8;
346+
s->errpos = (size_t)(s->str_start - s->input_start);
296347
return PHP_JSON_T_ERROR;
297348
}
298349
@@ -358,6 +409,9 @@ std:
358409
break;
359410
default:
360411
s->errcode = PHP_JSON_ERROR_SYNTAX;
412+
s->errpos = (size_t)(s->str_start - s->input_start);
413+
fprintf(stderr, "Syntax error: errpos=%zu, cursor=%p, str_start=%p\n",
414+
s->errpos, s->cursor, s->str_start);
361415
return PHP_JSON_T_ERROR;
362416
}
363417
*(s->pstr++) = esc;
@@ -386,6 +440,9 @@ std:
386440
387441
<*>ANY {
388442
s->errcode = PHP_JSON_ERROR_SYNTAX;
443+
s->errpos = (size_t)(s->str_start - s->input_start);
444+
fprintf(stderr, "Syntax error: errpos=%zu, cursor=%p, str_start=%p\n",
445+
s->errpos, s->cursor, s->str_start);
389446
return PHP_JSON_T_ERROR;
390447
}
391448
*/

ext/json/php_json_parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ PHP_JSON_API void php_json_parser_init(
7777

7878
PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser);
7979

80+
PHP_JSON_API size_t php_json_parser_error_pos(const php_json_parser *parser);
81+
8082
PHP_JSON_API int php_json_parse(php_json_parser *parser);
8183

8284
int php_json_yyparse(php_json_parser *parser);

ext/json/php_json_scanner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef struct _php_json_scanner {
2929
php_json_ctype *marker; /* marker position for backtracking */
3030
php_json_ctype *ctxmarker; /* marker position for context backtracking */
3131
php_json_ctype *str_start; /* start position of the string */
32+
php_json_ctype *input_start; /* start position of the string */
3233
php_json_ctype *pstr; /* string pointer for escapes conversion */
3334
zval value; /* value */
3435
int str_esc; /* number of extra characters for escaping */

ext/json/tests/json_validate_002.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ json_validate() - Error handling
55

66
require_once("json_validate_requires.inc");
77

8-
json_validate_trycatchdump("");
9-
json_validate_trycatchdump("-");
10-
json_validate_trycatchdump("", -1);
8+
//json_validate_trycatchdump("");
9+
//json_validate_trycatchdump("-");
10+
//json_validate_trycatchdump("", -1);
1111
json_validate_trycatchdump('{"key1":"value1", "value2"}', 2);
12-
json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 1);
13-
json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 2);
14-
json_validate_trycatchdump("-", 0);
15-
json_validate_trycatchdump("-", 512, JSON_BIGINT_AS_STRING);
16-
json_validate_trycatchdump("-", 512, JSON_BIGINT_AS_STRING | JSON_INVALID_UTF8_IGNORE);
17-
json_validate_trycatchdump("-", 512, JSON_INVALID_UTF8_IGNORE);
18-
json_validate_trycatchdump("{}", 512, JSON_INVALID_UTF8_IGNORE);
12+
//json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 1);
13+
//json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 2);
14+
//json_validate_trycatchdump("-", 0);
15+
//json_validate_trycatchdump("-", 512, JSON_BIGINT_AS_STRING);
16+
//json_validate_trycatchdump("-", 512, JSON_BIGINT_AS_STRING | JSON_INVALID_UTF8_IGNORE);
17+
//json_validate_trycatchdump("-", 512, JSON_INVALID_UTF8_IGNORE);
18+
//json_validate_trycatchdump("{}", 512, JSON_INVALID_UTF8_IGNORE);
1919

2020
?>
2121
--EXPECTF--

0 commit comments

Comments
 (0)