Skip to content

Commit f4f5e08

Browse files
committed
better position calculation
1 parent 0593c47 commit f4f5e08

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

ext/json/json_parser.y

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +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); \
38+
parser->scanner.errpos = (size_t)((parser->scanner.str_start - parser->scanner.input_start) - parser->scanner.str_esc - parser->scanner.utf8_invalid_count); \
3939
YYERROR; \
4040
} \
4141
++parser->depth
@@ -109,7 +109,7 @@ object_end:
109109
| ']'
110110
{
111111
parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
112-
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
112+
parser->scanner.errpos = (size_t)((parser->scanner.str_start - parser->scanner.input_start) - parser->scanner.str_esc - parser->scanner.utf8_invalid_count); \
113113
YYERROR;
114114
}
115115
;
@@ -166,7 +166,7 @@ array_end:
166166
| '}'
167167
{
168168
parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
169-
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
169+
parser->scanner.errpos = (size_t)((parser->scanner.str_start - parser->scanner.input_start) - parser->scanner.str_esc - parser->scanner.utf8_invalid_count); \
170170
YYERROR;
171171
}
172172
;
@@ -245,7 +245,7 @@ static int php_json_parser_object_update(php_json_parser *parser, zval *object,
245245
} else {
246246
if (ZSTR_LEN(key) > 0 && ZSTR_VAL(key)[0] == '\0') {
247247
parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME;
248-
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start); \
248+
parser->scanner.errpos = (size_t)((parser->scanner.str_start - parser->scanner.input_start) - parser->scanner.str_esc - parser->scanner.utf8_invalid_count); \
249249
zend_string_release_ex(key, 0);
250250
zval_ptr_dtor_nogc(zvalue);
251251
zval_ptr_dtor_nogc(object);
@@ -304,7 +304,7 @@ static void php_json_yyerror(php_json_parser *parser, char const *msg)
304304
{
305305
if (!parser->scanner.errcode) {
306306
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
307-
parser->scanner.errpos = (size_t)(parser->scanner.str_start - parser->scanner.input_start);
307+
parser->scanner.errpos = (size_t)((parser->scanner.str_start - parser->scanner.input_start) - parser->scanner.str_esc - parser->scanner.utf8_invalid_count);
308308
}
309309
}
310310

ext/json/json_scanner.re

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ std:
216216
return PHP_JSON_T_EOI;
217217
} else {
218218
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
219-
s->errpos = (size_t)(s->str_start - s->input_start);
219+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
220220
return PHP_JSON_T_ERROR;
221221
}
222222
}
@@ -229,24 +229,23 @@ std:
229229
}
230230
<JS>CTRL {
231231
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
232-
s->errpos = (size_t)(s->str_start - s->input_start);
232+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
233233
return PHP_JSON_T_ERROR;
234234
}
235235
<JS>UTF8 {
236236
s->errcode = PHP_JSON_ERROR_SYNTAX;
237-
s->errpos = (size_t)(s->str_start - s->input_start);
238-
237+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
239238
return PHP_JSON_T_ERROR;
240239
}
241240
<JS>ANY {
242241
s->errcode = PHP_JSON_ERROR_UTF8;
243-
s->errpos = (size_t)(s->str_start - s->input_start);
242+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
244243
return PHP_JSON_T_ERROR;
245244
}
246245
247246
<STR_P1>CTRL {
248247
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
249-
s->errpos = (size_t)(s->str_start - s->input_start);
248+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
250249
return PHP_JSON_T_ERROR;
251250
}
252251
<STR_P1>UTF16_1 {
@@ -267,7 +266,7 @@ std:
267266
}
268267
<STR_P1>UCS2 {
269268
s->errcode = PHP_JSON_ERROR_UTF16;
270-
s->errpos = (size_t)(s->str_start - s->input_start);
269+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
271270
return PHP_JSON_T_ERROR;
272271
}
273272
<STR_P1>ESC {
@@ -276,7 +275,7 @@ std:
276275
}
277276
<STR_P1>ESCPREF {
278277
s->errcode = PHP_JSON_ERROR_SYNTAX;
279-
s->errpos = (size_t)(s->str_start - s->input_start);
278+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
280279
281280
return PHP_JSON_T_ERROR;
282281
}
@@ -307,7 +306,7 @@ std:
307306
if (s->options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) {
308307
if (s->utf8_invalid_count > INT_MAX - 2) {
309308
s->errcode = PHP_JSON_ERROR_UTF8;
310-
s->errpos = (size_t)(s->str_start - s->input_start);
309+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
311310
return PHP_JSON_T_ERROR;
312311
}
313312
s->utf8_invalid_count += 2;
@@ -318,7 +317,7 @@ std:
318317
PHP_JSON_CONDITION_GOTO(STR_P1);
319318
}
320319
s->errcode = PHP_JSON_ERROR_UTF8;
321-
s->errpos = (size_t)(s->str_start - s->input_start);
320+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
322321
return PHP_JSON_T_ERROR;
323322
}
324323
@@ -384,7 +383,7 @@ std:
384383
break;
385384
default:
386385
s->errcode = PHP_JSON_ERROR_SYNTAX;
387-
s->errpos = (size_t)(s->str_start - s->input_start);
386+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
388387
389388
return PHP_JSON_T_ERROR;
390389
}
@@ -414,7 +413,7 @@ std:
414413
415414
<*>ANY {
416415
s->errcode = PHP_JSON_ERROR_SYNTAX;
417-
s->errpos = (size_t)(s->str_start - s->input_start);
416+
s->errpos = (size_t)(s->str_start - s->input_start - s->str_esc - s->utf8_invalid_count);
418417
419418
return PHP_JSON_T_ERROR;
420419
}

ext/json/tests/bug68546.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ NULL
1616
bool(true)
1717
NULL
1818
bool(true)
19-
string(54) "The decoded property name is invalid near character 20"
19+
string(54) "The decoded property name is invalid near character 15"
2020
Done

ext/json/tests/json_validate_002.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ json_validate_trycatchdump("");
99
json_validate_trycatchdump("-");
1010
json_validate_trycatchdump("", -1);
1111
json_validate_trycatchdump('{"key1":"value1", "value2"}', 2);
12+
json_validate_trycatchdump('{"text":"Hello \u20AC World", "key1":"Hello \xE2\x28 World"}', 2);
13+
json_validate_trycatchdump('{"text":"Hello \u20AC World"}', 2);
1214
json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 1);
1315
json_validate_trycatchdump('{"key1":"value1", "key2":"value2"}', 2);
1416
json_validate_trycatchdump("-", 0);
@@ -32,6 +34,12 @@ bool(false)
3234
int(4)
3335
string(30) "Syntax error near character 19"
3436
bool(false)
37+
int(4)
38+
string(30) "Syntax error near character 38"
39+
bool(true)
40+
int(0)
41+
string(8) "No error"
42+
bool(false)
3543
int(1)
3644
string(28) "Maximum stack depth exceeded"
3745
bool(true)

0 commit comments

Comments
 (0)