diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index b972d8aa..da0de9eb 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -780,10 +780,22 @@ JSONParser::getToken() } } - if (*p == 0) { - QTC::TC("libtests", "JSON parse null character"); - throw std::runtime_error( - "JSON: null character at offset " + std::to_string(offset)); + if ((*p < 32 && *p >= 0)) { + if (*p == '\t' || *p == '\n' || *p == '\r') { + // Legal white space not permitted in strings. This will always + // end the current token (unless we are still before the start + // of the token). + if (lex_state == ls_top) { + // Continue with token + } else { + // done + } + } else { + QTC::TC("libtests", "JSON parse null character"); + throw std::runtime_error( + "JSON: control or null character at offset " + + std::to_string(offset)); + } } action = append; switch (lex_state) { diff --git a/libtests/qtest/json_parse.test b/libtests/qtest/json_parse.test index d38d70de..8234b755 100644 --- a/libtests/qtest/json_parse.test +++ b/libtests/qtest/json_parse.test @@ -125,6 +125,10 @@ my @bad = ( "e after minus", # 42 "missing digit after e", # 43 "missing digit after e+/-", # 44 + # "tab char in string", # 45 + # "cr char in string", # 46 + # "lf char in string", # 47 + # "bs char in string", # 48 ); my $i = 0; diff --git a/libtests/qtest/json_parse/bad-18.out b/libtests/qtest/json_parse/bad-18.out index 0428b64f..1e779e41 100644 --- a/libtests/qtest/json_parse/bad-18.out +++ b/libtests/qtest/json_parse/bad-18.out @@ -1 +1 @@ -exception: bad-18.json: JSON: null character at offset 5 +exception: bad-18.json: JSON: control or null character at offset 5 diff --git a/libtests/qtest/json_parse/bad-45.json b/libtests/qtest/json_parse/bad-45.json new file mode 100644 index 00000000..16107dc0 --- /dev/null +++ b/libtests/qtest/json_parse/bad-45.json @@ -0,0 +1 @@ +"Tab in str ing" diff --git a/libtests/qtest/json_parse/bad-45.out b/libtests/qtest/json_parse/bad-45.out new file mode 100644 index 00000000..ba7e4f16 --- /dev/null +++ b/libtests/qtest/json_parse/bad-45.out @@ -0,0 +1 @@ +"Tab in str\ting" diff --git a/libtests/qtest/json_parse/bad-46.json b/libtests/qtest/json_parse/bad-46.json new file mode 100644 index 00000000..60873bf4 --- /dev/null +++ b/libtests/qtest/json_parse/bad-46.json @@ -0,0 +1 @@ +"cr in str ing" diff --git a/libtests/qtest/json_parse/bad-46.out b/libtests/qtest/json_parse/bad-46.out new file mode 100644 index 00000000..2baad6a4 --- /dev/null +++ b/libtests/qtest/json_parse/bad-46.out @@ -0,0 +1 @@ +"cr in str\ring" diff --git a/libtests/qtest/json_parse/bad-47.json b/libtests/qtest/json_parse/bad-47.json new file mode 100644 index 00000000..3c75427a --- /dev/null +++ b/libtests/qtest/json_parse/bad-47.json @@ -0,0 +1,2 @@ +"lf in str +ing" diff --git a/libtests/qtest/json_parse/bad-47.out b/libtests/qtest/json_parse/bad-47.out new file mode 100644 index 00000000..30549072 --- /dev/null +++ b/libtests/qtest/json_parse/bad-47.out @@ -0,0 +1 @@ +"lf in str\ning" diff --git a/libtests/qtest/json_parse/bad-48.json b/libtests/qtest/json_parse/bad-48.json new file mode 100644 index 00000000..1e605808 --- /dev/null +++ b/libtests/qtest/json_parse/bad-48.json @@ -0,0 +1 @@ +"bs in string" \ No newline at end of file diff --git a/libtests/qtest/json_parse/bad-48.out b/libtests/qtest/json_parse/bad-48.out new file mode 100644 index 00000000..0b20fc7a --- /dev/null +++ b/libtests/qtest/json_parse/bad-48.out @@ -0,0 +1 @@ +exception: bad-48.json: JSON: control or null character at offset 10