Skip to content

Commit 68d0f56

Browse files
authored
json: Report unterminated JSON strings as syntax errors (#22528)
Fixes #22527.
1 parent 2a712fb commit 68d0f56

12 files changed

Lines changed: 152 additions & 120 deletions

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ PHP NEWS
5858
IntlDateFormatter::localtime()/datefmt_localtime() now raise TypeError
5959
when the offset argument is not of type int. (Weilin Du)
6060

61+
- JSON:
62+
. Report unterminated JSON strings as syntax errors. (timwolla)
63+
6164
- Opcache:
6265
. Fixed bug GH-21770 (Infinite recursion in property hook getter in opcache
6366
preloaded trait). (iliaal)

ext/json/json_scanner.re

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,14 @@ std:
262262
s->errcode = PHP_JSON_ERROR_UTF8;
263263
return PHP_JSON_T_ERROR;
264264
}
265-
265+
<STR_P1>EOI {
266+
if (s->limit < s->cursor) {
267+
s->errcode = PHP_JSON_ERROR_SYNTAX;
268+
} else {
269+
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
270+
}
271+
return PHP_JSON_T_ERROR;
272+
}
266273
<STR_P1>CTRL {
267274
s->errcode = PHP_JSON_ERROR_CTRL_CHAR;
268275
return PHP_JSON_T_ERROR;

ext/json/tests/gh22527.phpt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
GH-22527: Unterminated JSON strings are misleadingly reported as “Control character error”
3+
--FILE--
4+
<?php
5+
6+
var_dump(json_decode('"'));
7+
var_dump(json_last_error(), json_last_error_msg());
8+
9+
var_dump(json_decode('"123'));
10+
var_dump(json_last_error(), json_last_error_msg());
11+
12+
var_dump(json_decode('{"123": "'));
13+
var_dump(json_last_error(), json_last_error_msg());
14+
15+
var_dump(json_decode('"' . chr(0)));
16+
var_dump(json_last_error(), json_last_error_msg());
17+
18+
?>
19+
--EXPECT--
20+
NULL
21+
int(4)
22+
string(30) "Syntax error near location 1:1"
23+
NULL
24+
int(4)
25+
string(30) "Syntax error near location 1:1"
26+
NULL
27+
int(4)
28+
string(30) "Syntax error near location 1:9"
29+
NULL
30+
int(3)
31+
string(71) "Control character error, possibly incorrectly encoded near location 1:1"

ext/json/tests/json_last_error_msg_error_location_001.phpt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ string(30) "Syntax error near location 1:1"
6666

6767
Error at position 1:10:
6868
bool(false)
69-
int(3)
70-
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
69+
int(4)
70+
string(31) "Syntax error near location 1:10"
7171

7272
Error at position 1:9:
7373
bool(false)
@@ -118,4 +118,3 @@ Error at position 1:10:
118118
bool(false)
119119
int(3)
120120
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
121-

ext/json/tests/json_last_error_msg_error_location_002.phpt

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,51 +53,50 @@ Testing error locations with Unicode UTF-8 characters
5353

5454
Error after Japanese characters:
5555
bool(false)
56-
int(3)
57-
string(72) "Control character error, possibly incorrectly encoded near location 1:12"
56+
int(4)
57+
string(31) "Syntax error near location 1:12"
5858

5959
Error after Russian characters:
6060
bool(false)
61-
int(3)
62-
string(71) "Control character error, possibly incorrectly encoded near location 1:9"
61+
int(4)
62+
string(30) "Syntax error near location 1:9"
6363

6464
Error after Chinese characters:
6565
bool(false)
66-
int(3)
67-
string(71) "Control character error, possibly incorrectly encoded near location 1:8"
66+
int(4)
67+
string(30) "Syntax error near location 1:8"
6868

6969
Error after Arabic characters:
7070
bool(false)
71-
int(3)
72-
string(71) "Control character error, possibly incorrectly encoded near location 1:9"
71+
int(4)
72+
string(30) "Syntax error near location 1:9"
7373

7474
Error after Emoji:
7575
bool(false)
76-
int(3)
77-
string(72) "Control character error, possibly incorrectly encoded near location 1:11"
76+
int(4)
77+
string(31) "Syntax error near location 1:11"
7878

7979
Error in mixed ASCII and UTF-8:
8080
bool(false)
81-
int(3)
82-
string(72) "Control character error, possibly incorrectly encoded near location 1:27"
81+
int(4)
82+
string(31) "Syntax error near location 1:27"
8383

8484
Error with UTF-8 escaped sequences:
8585
bool(false)
86-
int(3)
87-
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
86+
int(4)
87+
string(31) "Syntax error near location 1:10"
8888

8989
Error in object with multiple UTF-8 keys:
9090
bool(false)
91-
int(3)
92-
string(72) "Control character error, possibly incorrectly encoded near location 1:22"
91+
int(4)
92+
string(31) "Syntax error near location 1:22"
9393

9494
Error in array with UTF-8 strings:
9595
bool(false)
96-
int(3)
97-
string(72) "Control character error, possibly incorrectly encoded near location 1:18"
96+
int(4)
97+
string(31) "Syntax error near location 1:18"
9898

9999
Error in nested object with UTF-8:
100100
bool(false)
101-
int(3)
102-
string(72) "Control character error, possibly incorrectly encoded near location 1:15"
103-
101+
int(4)
102+
string(31) "Syntax error near location 1:15"

ext/json/tests/json_last_error_msg_error_location_004.phpt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ Testing error locations in deeply nested structures
5353

5454
Error in deeply nested object:
5555
bool(false)
56-
int(3)
57-
string(72) "Control character error, possibly incorrectly encoded near location 1:31"
56+
int(4)
57+
string(31) "Syntax error near location 1:31"
5858

5959
Error in deeply nested array:
6060
bool(true)
@@ -78,16 +78,15 @@ string(31) "Syntax error near location 1:21"
7878

7979
Error in complex structure:
8080
bool(false)
81-
int(3)
82-
string(72) "Control character error, possibly incorrectly encoded near location 1:93"
81+
int(4)
82+
string(31) "Syntax error near location 1:93"
8383

8484
Error in array of objects:
8585
bool(false)
86-
int(3)
87-
string(72) "Control character error, possibly incorrectly encoded near location 1:68"
86+
int(4)
87+
string(31) "Syntax error near location 1:68"
8888

8989
Error in object with array values:
9090
bool(false)
9191
int(2)
9292
string(61) "State mismatch (invalid or malformed JSON) near location 1:82"
93-

ext/json/tests/json_last_error_msg_error_location_005.phpt

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,51 +53,50 @@ Testing error locations with UTF-16 surrogate pairs and escape sequences
5353

5454
Error after UTF-16 escaped emoji:
5555
bool(false)
56-
int(3)
57-
string(72) "Control character error, possibly incorrectly encoded near location 1:11"
56+
int(4)
57+
string(31) "Syntax error near location 1:11"
5858

5959
Error after multiple UTF-16 pairs:
6060
bool(false)
61-
int(3)
62-
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
61+
int(4)
62+
string(31) "Syntax error near location 1:10"
6363

6464
Error with mixed UTF-8 and UTF-16:
6565
bool(false)
66-
int(3)
67-
string(72) "Control character error, possibly incorrectly encoded near location 1:11"
66+
int(4)
67+
string(31) "Syntax error near location 1:11"
6868

6969
Error with UTF-16 in key:
7070
bool(false)
71-
int(3)
72-
string(71) "Control character error, possibly incorrectly encoded near location 1:9"
71+
int(4)
72+
string(30) "Syntax error near location 1:9"
7373

7474
Error with multiple UTF-16 keys:
7575
bool(false)
76-
int(3)
77-
string(72) "Control character error, possibly incorrectly encoded near location 1:22"
76+
int(4)
77+
string(31) "Syntax error near location 1:22"
7878

7979
Error with BMP characters:
8080
bool(false)
81-
int(3)
82-
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
81+
int(4)
82+
string(31) "Syntax error near location 1:10"
8383

8484
Error with supplementary plane:
8585
bool(false)
86-
int(3)
87-
string(72) "Control character error, possibly incorrectly encoded near location 1:11"
86+
int(4)
87+
string(31) "Syntax error near location 1:11"
8888

8989
Error in array with UTF-16:
9090
bool(false)
91-
int(3)
92-
string(72) "Control character error, possibly incorrectly encoded near location 1:12"
91+
int(4)
92+
string(31) "Syntax error near location 1:12"
9393

9494
Error in nested structure with UTF-16:
9595
bool(false)
96-
int(3)
97-
string(72) "Control character error, possibly incorrectly encoded near location 1:18"
96+
int(4)
97+
string(31) "Syntax error near location 1:18"
9898

9999
Error with UTF-16 and control chars:
100100
bool(false)
101-
int(3)
102-
string(72) "Control character error, possibly incorrectly encoded near location 1:10"
103-
101+
int(4)
102+
string(31) "Syntax error near location 1:10"

ext/json/tests/json_last_error_msg_error_location_006.phpt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ string(33) "Syntax error near location 1:1011"
107107

108108
Error with very long key:
109109
bool(false)
110-
int(3)
111-
string(73) "Control character error, possibly incorrectly encoded near location 1:506"
110+
int(4)
111+
string(32) "Syntax error near location 1:506"
112112

113113
Error after empty object:
114114
bool(false)
@@ -149,4 +149,3 @@ Error with mixed whitespace:
149149
bool(false)
150150
int(3)
151151
string(71) "Control character error, possibly incorrectly encoded near location 3:2"
152-

ext/json/tests/json_last_error_msg_error_location_007.phpt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ string(30) "Syntax error near location 1:9"
118118

119119
Unclosed string:
120120
bool(false)
121-
int(3)
122-
string(71) "Control character error, possibly incorrectly encoded near location 1:9"
121+
int(4)
122+
string(30) "Syntax error near location 1:9"
123123

124124
Invalid escape sequence:
125125
bool(false)
@@ -175,4 +175,3 @@ Missing comma between object properties:
175175
bool(false)
176176
int(4)
177177
string(30) "Syntax error near location 1:9"
178-

0 commit comments

Comments
 (0)