Skip to content

Commit 565f181

Browse files
committed
Fix issue json-c#875: cast to unsigned char so bytes above 0x7f aren't interpreted as negative, which was causing the strict-mode control characters check to incorrectly trigger.
1 parent 474ee12 commit 565f181

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

json_tokener.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
678678
state = json_tokener_state_string_escape;
679679
break;
680680
}
681-
else if ((tok->flags & JSON_TOKENER_STRICT) && c <= 0x1f)
681+
else if ((tok->flags & JSON_TOKENER_STRICT) && (unsigned char)c <= 0x1f)
682682
{
683683
// Disallow control characters in strict mode
684684
tok->err = json_tokener_error_parse_string;

tests/test_parse.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ struct incremental_step
297297
{"d", -1, -1, json_tokener_continue, 0, 0},
298298
{"1", -1, -1, json_tokener_continue, 0, 0},
299299
{"e\"", -1, -1, json_tokener_success, 1, 0},
300+
300301
/* parse two char at every time */
301302
{"\"\\u", -1, -1, json_tokener_continue, 0, 0},
302303
{"d8", -1, -1, json_tokener_continue, 0, 0},
@@ -322,6 +323,11 @@ struct incremental_step
322323
{"\"fff \\ud83d\\ude", -1, -1, json_tokener_continue, 0, 0},
323324
{"00 bar\"", -1, -1, json_tokener_success, 1, 0},
324325

326+
/* Check a utf-8 char (a+umlaut) that has bytes that look negative when
327+
char are signed (see also control char check below) */
328+
{"\"\xc3\xa4\"", -1, -1, json_tokener_success, 1, 0},
329+
{"\"\xc3\xa4\"", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
330+
325331
/* Check that json_tokener_reset actually resets */
326332
{"{ \"foo", -1, -1, json_tokener_continue, 1, 0},
327333
{": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1, 0},
@@ -394,8 +400,8 @@ struct incremental_step
394400

395401
{"Infinity", 9, 8, json_tokener_success, 1, 0},
396402
{"infinity", 9, 8, json_tokener_success, 1, 0},
397-
{"-infinity", 10, 9, json_tokener_success, 1, 0},
398403
{"infinity", 9, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
404+
{"-infinity", 10, 9, json_tokener_success, 1, 0},
399405
{"-infinity", 10, 1, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
400406

401407
{"inf", 3, 3, json_tokener_continue, 0, 0},
@@ -462,12 +468,15 @@ struct incremental_step
462468
{"[18446744073709551616]", 23, 21, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
463469

464470
/* XXX this seems like a bug, should fail with _error_parse_number instead */
471+
{"18446744073709551616", 21, 20, json_tokener_success, 1, 0},
465472
{"18446744073709551616", 21, 20, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT},
466473

467474
/* Exceeding integer limits as double parse OK */
468475
{"[9223372036854775808.0]", 24, 23, json_tokener_success, 1, 0},
476+
{"[-9223372036854775809.0]", 25, 24, json_tokener_success, 1, 0},
469477
{"[-9223372036854775809.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT},
470478
{"[18446744073709551615.0]", 25, 24, json_tokener_success, 1, 0},
479+
{"[18446744073709551616.0]", 25, 24, json_tokener_success, 1, 0},
471480
{"[18446744073709551616.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT},
472481

473482
/* offset=1 because "n" is the start of "null". hmm... */
@@ -524,6 +533,7 @@ struct incremental_step
524533
{"\"\\a\"", -1, 2, json_tokener_error_parse_string, 1, 0},
525534

526535
/* Check '\'' in strict model */
536+
{"\'foo\'", -1, 5, json_tokener_success, 1, 0},
527537
{"\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
528538

529539
/* Parse array/object */
@@ -544,9 +554,10 @@ struct incremental_step
544554
* in what we accept (up to a point).
545555
*/
546556
{"[1,2,3,]", -1, -1, json_tokener_success, 0, 0},
557+
{"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
547558
{"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0, 0},
559+
{"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0, JSON_TOKENER_STRICT},
548560

549-
{"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
550561
{"{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 1, JSON_TOKENER_STRICT},
551562

552563
// utf-8 test
@@ -656,7 +667,7 @@ static void test_incremental_parse(void)
656667
printf("json_tokener_parse(%s) ... ", string_to_parse);
657668
new_obj = json_tokener_parse(string_to_parse);
658669
if (new_obj == NULL)
659-
puts("got error as expected");
670+
printf("%s", "got error as expected\n");
660671

661672
/* test incremental parsing in various forms */
662673
tok = json_tokener_new();

tests/test_parse.expected

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ json_tokener_parse_ex(tok, "fff \ud834\udd, 15) ... OK: got correct error: cont
134134
json_tokener_parse_ex(tok, 1e bar" , 7) ... OK: got object of type [string]: "fff 𝄞 bar"
135135
json_tokener_parse_ex(tok, "fff \ud83d\ude, 15) ... OK: got correct error: continue
136136
json_tokener_parse_ex(tok, 00 bar" , 7) ... OK: got object of type [string]: "fff 😀 bar"
137+
json_tokener_parse_ex(tok, "ä" , 4) ... OK: got object of type [string]: "ä"
138+
json_tokener_parse_ex(tok, "ä" , 4) ... OK: got object of type [string]: "ä"
137139
json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
138140
json_tokener_parse_ex(tok, : "bar"} , 8) ... OK: got correct error: unexpected character
139141
json_tokener_parse_ex(tok, { "foo , 6) ... OK: got correct error: continue
@@ -177,8 +179,8 @@ json_tokener_parse_ex(tok, null , 4) ... OK: got correct error: continu
177179
json_tokener_parse_ex(tok, null , 5) ... OK: got object of type [null]: null
178180
json_tokener_parse_ex(tok, Infinity , 9) ... OK: got object of type [double]: Infinity
179181
json_tokener_parse_ex(tok, infinity , 9) ... OK: got object of type [double]: Infinity
180-
json_tokener_parse_ex(tok, -infinity , 10) ... OK: got object of type [double]: -Infinity
181182
json_tokener_parse_ex(tok, infinity , 9) ... OK: got correct error: unexpected character
183+
json_tokener_parse_ex(tok, -infinity , 10) ... OK: got object of type [double]: -Infinity
182184
json_tokener_parse_ex(tok, -infinity , 10) ... OK: got correct error: unexpected character
183185
json_tokener_parse_ex(tok, inf , 3) ... OK: got correct error: continue
184186
json_tokener_parse_ex(tok, inity , 6) ... OK: got object of type [double]: Infinity
@@ -218,11 +220,14 @@ json_tokener_parse_ex(tok, [-9223372036854775809], 23) ... OK: got correct erro
218220
json_tokener_parse_ex(tok, [18446744073709551615], 23) ... OK: got object of type [array]: [ 18446744073709551615 ]
219221
json_tokener_parse_ex(tok, [18446744073709551616], 23) ... OK: got object of type [array]: [ 18446744073709551615 ]
220222
json_tokener_parse_ex(tok, [18446744073709551616], 23) ... OK: got correct error: number expected
223+
json_tokener_parse_ex(tok, 18446744073709551616, 21) ... OK: got object of type [int]: 18446744073709551615
221224
json_tokener_parse_ex(tok, 18446744073709551616, 21) ... OK: got correct error: unexpected end of data
222225
json_tokener_parse_ex(tok, [9223372036854775808.0], 24) ... OK: got object of type [array]: [ 9223372036854775808.0 ]
223226
json_tokener_parse_ex(tok, [-9223372036854775809.0], 25) ... OK: got object of type [array]: [ -9223372036854775809.0 ]
227+
json_tokener_parse_ex(tok, [-9223372036854775809.0], 25) ... OK: got object of type [array]: [ -9223372036854775809.0 ]
224228
json_tokener_parse_ex(tok, [18446744073709551615.0], 25) ... OK: got object of type [array]: [ 18446744073709551615.0 ]
225229
json_tokener_parse_ex(tok, [18446744073709551616.0], 25) ... OK: got object of type [array]: [ 18446744073709551616.0 ]
230+
json_tokener_parse_ex(tok, [18446744073709551616.0], 25) ... OK: got object of type [array]: [ 18446744073709551616.0 ]
226231
json_tokener_parse_ex(tok, noodle , 7) ... OK: got correct error: null expected
227232
json_tokener_parse_ex(tok, naodle , 7) ... OK: got correct error: null expected
228233
json_tokener_parse_ex(tok, track , 6) ... OK: got correct error: boolean expected
@@ -250,6 +255,7 @@ json_tokener_parse_ex(tok, "\t" , 4) ... OK: got object of type [string
250255
json_tokener_parse_ex(tok, "\/" , 4) ... OK: got object of type [string]: "\/"
251256
json_tokener_parse_ex(tok, "/" , 3) ... OK: got object of type [string]: "\/"
252257
json_tokener_parse_ex(tok, "\a" , 4) ... OK: got correct error: invalid string sequence
258+
json_tokener_parse_ex(tok, 'foo' , 5) ... OK: got object of type [string]: "foo"
253259
json_tokener_parse_ex(tok, 'foo' , 5) ... OK: got correct error: unexpected character
254260
json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
255261
json_tokener_parse_ex(tok, [1,2,3} , 7) ... OK: got correct error: array value separator ',' expected
@@ -263,8 +269,9 @@ json_tokener_parse_ex(tok, {"a":1 , 6) ... OK: got correct error: continu
263269
json_tokener_parse_ex(tok, [,] , 3) ... OK: got correct error: unexpected character
264270
json_tokener_parse_ex(tok, [,1] , 4) ... OK: got correct error: unexpected character
265271
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
266-
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
267272
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got correct error: unexpected character
273+
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
274+
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
268275
json_tokener_parse_ex(tok, {"a":1,} , 8) ... OK: got correct error: unexpected character
269276
json_tokener_parse_ex(tok, "123asc$%&" , 11) ... OK: got object of type [string]: "123asc$%&"
270277
json_tokener_parse_ex(tok, "123asc$%&" , 11) ... OK: got object of type [string]: "123asc$%&"
@@ -322,5 +329,5 @@ json_tokener_parse_ex(tok, "" , 3) ... OK: got correct error: invalid
322329
json_tokener_parse_ex(tok, "" , 3) ... OK: got correct error: invalid string sequence
323330
json_tokener_parse_ex(tok, "" , 3) ... OK: got correct error: invalid string sequence
324331
json_tokener_parse_ex(tok, "" , 3) ... OK: got correct error: invalid string sequence
325-
End Incremental Tests OK=230 ERROR=0
332+
End Incremental Tests OK=237 ERROR=0
326333
==================================

0 commit comments

Comments
 (0)