From e8e8f6f43c760523520dfe7a5c76d88c959599f6 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Mon, 17 Jan 2022 18:40:38 -0500 Subject: Add JSON::parse --- libtests/build.mk | 1 + libtests/json.cc | 136 +++++++++++++++++--------------- libtests/json_parse.cc | 27 +++++++ libtests/libtests.testcov | 26 +++++++ libtests/qtest/json/json.out | 25 +++--- libtests/qtest/json_parse.test | 137 +++++++++++++++++++++++++++++++++ libtests/qtest/json_parse/bad-01.json | 1 + libtests/qtest/json_parse/bad-01.out | 1 + libtests/qtest/json_parse/bad-02.json | 1 + libtests/qtest/json_parse/bad-02.out | 1 + libtests/qtest/json_parse/bad-03.json | 1 + libtests/qtest/json_parse/bad-03.out | 1 + libtests/qtest/json_parse/bad-04.json | 2 + libtests/qtest/json_parse/bad-04.out | 1 + libtests/qtest/json_parse/bad-05.json | 1 + libtests/qtest/json_parse/bad-05.out | 1 + libtests/qtest/json_parse/bad-06.json | 1 + libtests/qtest/json_parse/bad-06.out | 1 + libtests/qtest/json_parse/bad-07.json | 1 + libtests/qtest/json_parse/bad-07.out | 1 + libtests/qtest/json_parse/bad-08.json | 1 + libtests/qtest/json_parse/bad-08.out | 1 + libtests/qtest/json_parse/bad-09.json | 1 + libtests/qtest/json_parse/bad-09.out | 1 + libtests/qtest/json_parse/bad-10.json | 1 + libtests/qtest/json_parse/bad-10.out | 1 + libtests/qtest/json_parse/bad-11.json | 1 + libtests/qtest/json_parse/bad-11.out | 1 + libtests/qtest/json_parse/bad-12.json | 1 + libtests/qtest/json_parse/bad-12.out | 1 + libtests/qtest/json_parse/bad-13.json | 1 + libtests/qtest/json_parse/bad-13.out | 1 + libtests/qtest/json_parse/bad-14.json | 1 + libtests/qtest/json_parse/bad-14.out | 1 + libtests/qtest/json_parse/bad-15.json | 1 + libtests/qtest/json_parse/bad-15.out | 1 + libtests/qtest/json_parse/bad-16.json | 1 + libtests/qtest/json_parse/bad-16.out | 1 + libtests/qtest/json_parse/bad-17.json | 1 + libtests/qtest/json_parse/bad-17.out | 1 + libtests/qtest/json_parse/bad-18.json | Bin 0 -> 9 bytes libtests/qtest/json_parse/bad-18.out | 1 + libtests/qtest/json_parse/bad-19.json | 1 + libtests/qtest/json_parse/bad-19.out | 1 + libtests/qtest/json_parse/bad-20.json | 1 + libtests/qtest/json_parse/bad-20.out | 1 + libtests/qtest/json_parse/bad-21.json | 1 + libtests/qtest/json_parse/bad-21.out | 1 + libtests/qtest/json_parse/bad-22.json | 1 + libtests/qtest/json_parse/bad-22.out | 1 + libtests/qtest/json_parse/bad-23.json | 1 + libtests/qtest/json_parse/bad-23.out | 1 + libtests/qtest/json_parse/bad-24.json | 1 + libtests/qtest/json_parse/bad-24.out | 1 + libtests/qtest/json_parse/bad-25.json | 1 + libtests/qtest/json_parse/bad-25.out | 1 + libtests/qtest/json_parse/bad-26.json | 1 + libtests/qtest/json_parse/bad-26.out | 1 + libtests/qtest/json_parse/bad-27.json | 1 + libtests/qtest/json_parse/bad-27.out | 1 + libtests/qtest/json_parse/bad-28.json | 1 + libtests/qtest/json_parse/bad-28.out | 1 + libtests/qtest/json_parse/bad-29.json | 1 + libtests/qtest/json_parse/bad-29.out | 1 + libtests/qtest/json_parse/bad-30.json | 1 + libtests/qtest/json_parse/bad-30.out | 1 + libtests/qtest/json_parse/bad-31.json | 1 + libtests/qtest/json_parse/bad-31.out | 1 + libtests/qtest/json_parse/bad-32.json | 1 + libtests/qtest/json_parse/bad-32.out | 1 + libtests/qtest/json_parse/bad-33.json | 1 + libtests/qtest/json_parse/bad-33.out | 1 + libtests/qtest/json_parse/bad-34.json | 1 + libtests/qtest/json_parse/bad-34.out | 1 + libtests/qtest/json_parse/bad-35.json | 1 + libtests/qtest/json_parse/bad-35.out | 1 + libtests/qtest/json_parse/good-01.json | 3 + libtests/qtest/json_parse/good-02.json | 1 + libtests/qtest/json_parse/good-03.json | 1 + libtests/qtest/json_parse/good-04.json | 1 + libtests/qtest/json_parse/good-05.json | 1 + libtests/qtest/json_parse/good-06.json | 1 + libtests/qtest/json_parse/good-07.json | 1 + libtests/qtest/json_parse/good-08.json | 1 + libtests/qtest/json_parse/good-09.json | 1 + libtests/qtest/json_parse/save-01.json | 17 ++++ libtests/qtest/json_parse/save-02.json | 1 + libtests/qtest/json_parse/save-03.json | 1 + libtests/qtest/json_parse/save-04.json | 10 +++ libtests/qtest/json_parse/save-05.json | 1 + libtests/qtest/json_parse/save-06.json | 1 + libtests/qtest/json_parse/save-07.json | 1 + libtests/qtest/json_parse/save-08.json | 10 +++ libtests/qtest/json_parse/save-09.json | 7 ++ 94 files changed, 410 insertions(+), 72 deletions(-) create mode 100644 libtests/json_parse.cc create mode 100644 libtests/qtest/json_parse.test create mode 100644 libtests/qtest/json_parse/bad-01.json create mode 100644 libtests/qtest/json_parse/bad-01.out create mode 100644 libtests/qtest/json_parse/bad-02.json create mode 100644 libtests/qtest/json_parse/bad-02.out create mode 100644 libtests/qtest/json_parse/bad-03.json create mode 100644 libtests/qtest/json_parse/bad-03.out create mode 100644 libtests/qtest/json_parse/bad-04.json create mode 100644 libtests/qtest/json_parse/bad-04.out create mode 100644 libtests/qtest/json_parse/bad-05.json create mode 100644 libtests/qtest/json_parse/bad-05.out create mode 100644 libtests/qtest/json_parse/bad-06.json create mode 100644 libtests/qtest/json_parse/bad-06.out create mode 100644 libtests/qtest/json_parse/bad-07.json create mode 100644 libtests/qtest/json_parse/bad-07.out create mode 100644 libtests/qtest/json_parse/bad-08.json create mode 100644 libtests/qtest/json_parse/bad-08.out create mode 100644 libtests/qtest/json_parse/bad-09.json create mode 100644 libtests/qtest/json_parse/bad-09.out create mode 100644 libtests/qtest/json_parse/bad-10.json create mode 100644 libtests/qtest/json_parse/bad-10.out create mode 100644 libtests/qtest/json_parse/bad-11.json create mode 100644 libtests/qtest/json_parse/bad-11.out create mode 100644 libtests/qtest/json_parse/bad-12.json create mode 100644 libtests/qtest/json_parse/bad-12.out create mode 100644 libtests/qtest/json_parse/bad-13.json create mode 100644 libtests/qtest/json_parse/bad-13.out create mode 100644 libtests/qtest/json_parse/bad-14.json create mode 100644 libtests/qtest/json_parse/bad-14.out create mode 100644 libtests/qtest/json_parse/bad-15.json create mode 100644 libtests/qtest/json_parse/bad-15.out create mode 100644 libtests/qtest/json_parse/bad-16.json create mode 100644 libtests/qtest/json_parse/bad-16.out create mode 100644 libtests/qtest/json_parse/bad-17.json create mode 100644 libtests/qtest/json_parse/bad-17.out create mode 100644 libtests/qtest/json_parse/bad-18.json create mode 100644 libtests/qtest/json_parse/bad-18.out create mode 100644 libtests/qtest/json_parse/bad-19.json create mode 100644 libtests/qtest/json_parse/bad-19.out create mode 100644 libtests/qtest/json_parse/bad-20.json create mode 100644 libtests/qtest/json_parse/bad-20.out create mode 100644 libtests/qtest/json_parse/bad-21.json create mode 100644 libtests/qtest/json_parse/bad-21.out create mode 100644 libtests/qtest/json_parse/bad-22.json create mode 100644 libtests/qtest/json_parse/bad-22.out create mode 100644 libtests/qtest/json_parse/bad-23.json create mode 100644 libtests/qtest/json_parse/bad-23.out create mode 100644 libtests/qtest/json_parse/bad-24.json create mode 100644 libtests/qtest/json_parse/bad-24.out create mode 100644 libtests/qtest/json_parse/bad-25.json create mode 100644 libtests/qtest/json_parse/bad-25.out create mode 100644 libtests/qtest/json_parse/bad-26.json create mode 100644 libtests/qtest/json_parse/bad-26.out create mode 100644 libtests/qtest/json_parse/bad-27.json create mode 100644 libtests/qtest/json_parse/bad-27.out create mode 100644 libtests/qtest/json_parse/bad-28.json create mode 100644 libtests/qtest/json_parse/bad-28.out create mode 100644 libtests/qtest/json_parse/bad-29.json create mode 100644 libtests/qtest/json_parse/bad-29.out create mode 100644 libtests/qtest/json_parse/bad-30.json create mode 100644 libtests/qtest/json_parse/bad-30.out create mode 100644 libtests/qtest/json_parse/bad-31.json create mode 100644 libtests/qtest/json_parse/bad-31.out create mode 100644 libtests/qtest/json_parse/bad-32.json create mode 100644 libtests/qtest/json_parse/bad-32.out create mode 100644 libtests/qtest/json_parse/bad-33.json create mode 100644 libtests/qtest/json_parse/bad-33.out create mode 100644 libtests/qtest/json_parse/bad-34.json create mode 100644 libtests/qtest/json_parse/bad-34.out create mode 100644 libtests/qtest/json_parse/bad-35.json create mode 100644 libtests/qtest/json_parse/bad-35.out create mode 100644 libtests/qtest/json_parse/good-01.json create mode 100644 libtests/qtest/json_parse/good-02.json create mode 100644 libtests/qtest/json_parse/good-03.json create mode 100644 libtests/qtest/json_parse/good-04.json create mode 100644 libtests/qtest/json_parse/good-05.json create mode 100644 libtests/qtest/json_parse/good-06.json create mode 100644 libtests/qtest/json_parse/good-07.json create mode 100644 libtests/qtest/json_parse/good-08.json create mode 100644 libtests/qtest/json_parse/good-09.json create mode 100644 libtests/qtest/json_parse/save-01.json create mode 100644 libtests/qtest/json_parse/save-02.json create mode 100644 libtests/qtest/json_parse/save-03.json create mode 100644 libtests/qtest/json_parse/save-04.json create mode 100644 libtests/qtest/json_parse/save-05.json create mode 100644 libtests/qtest/json_parse/save-06.json create mode 100644 libtests/qtest/json_parse/save-07.json create mode 100644 libtests/qtest/json_parse/save-08.json create mode 100644 libtests/qtest/json_parse/save-09.json (limited to 'libtests') diff --git a/libtests/build.mk b/libtests/build.mk index 1ae95196..a23b9c28 100644 --- a/libtests/build.mk +++ b/libtests/build.mk @@ -13,6 +13,7 @@ BINS_libtests = \ hex \ input_source \ json \ + json_parse \ lzw \ main_from_wmain \ matrix \ diff --git a/libtests/json.cc b/libtests/json.cc index d788ab4e..7bea5589 100644 --- a/libtests/json.cc +++ b/libtests/json.cc @@ -91,67 +91,83 @@ static void check_schema(JSON& obj, JSON& schema, bool exp, static void test_schema() { - // Since we don't have a JSON parser, use the PDF parser as a - // shortcut for creating a complex JSON structure. - JSON schema = QPDFObjectHandle::parse( - "<<" - " /one <<" - " /a <<" - " /q (queue)" - " /r <<" - " /x (ecks)" - " /y (why)" - " >>" - " /s [ (esses) ]" - " >>" - " >>" - " /two [" - " <<" - " /goose (gander)" - " /glarp (enspliel)" - " >>" - " ]" - ">>").getJSON(); - JSON three = JSON::makeDictionary(); - three.addDictionaryMember( - "", - QPDFObjectHandle::parse("<< /z (ebra) >>").getJSON()); - schema.addDictionaryMember("/three", three); - JSON a = QPDFObjectHandle::parse("[(not a) (dictionary)]").getJSON(); + JSON schema = JSON::parse(R"( +{ + "one": { + "a": { + "q": "queue", + "r": { + "x": "ecks", + "y": "(bool) why" + }, + "s": [ + "esses" + ] + } + }, + "two": [ + { + "goose": "gander", + "glarp": "enspliel" + } + ], + "three": { + "": { + "z": "ebra", + "o": "(optional, string) optional" + } + } +} +)"); + + JSON a = JSON::parse(R"(["not a", "dictionary"])"); check_schema(a, schema, false, "top-level type mismatch"); - JSON b = QPDFObjectHandle::parse( - "<<" - " /one <<" - " /a <<" - " /t (oops)" - " /r [" - " /x (ecks)" - " /y (why)" - " ]" - " /s << /z (esses) >>" - " >>" - " >>" - " /two [" - " <<" - " /goose (0 gander)" - " /glarp (0 enspliel)" - " >>" - " <<" - " /goose (1 gander)" - " /flarp (1 enspliel)" - " >>" - " 2" - " [ (three) ]" - " <<" - " /goose (4 gander)" - " /glarp (4 enspliel)" - " >>" - " ]" - " /three <<" - " /anything << /x (oops) >>" - " /else << /z (okay) >>" - " >>" - ">>").getJSON(); + JSON b = JSON::parse(R"( +{ + "one": { + "a": { + "t": "oops", + "r": [ + "x", + "ecks", + "y", + "why" + ], + "s": { + "z": "esses" + } + } + }, + "two": [ + { + "goose": "0 gander", + "glarp": "0 enspliel" + }, + { + "goose": "1 gander", + "flarp": "1 enspliel" + }, + 2, + [ + "three" + ], + { + "goose": "4 gander", + "glarp": 4 + } + ], + "three": { + "anything": { + "x": "oops", + "o": "okay" + }, + "else": { + "z": "okay" + } + } +} +)"); + check_schema(b, schema, false, "missing items"); check_schema(a, a, false, "top-level schema array error"); check_schema(b, b, false, "lower-level schema array error"); diff --git a/libtests/json_parse.cc b/libtests/json_parse.cc new file mode 100644 index 00000000..f0491723 --- /dev/null +++ b/libtests/json_parse.cc @@ -0,0 +1,27 @@ +#include +#include +#include + +int main(int argc, char* argv[]) +{ + if (argc != 2) + { + std::cerr << "Usage: json_parse file" << std::endl; + return 2; + } + char const* filename = argv[1]; + try + { + PointerHolder buf; + size_t size; + QUtil::read_file_into_memory(filename, buf, size); + std::string s(buf.getPointer(), size); + std::cout << JSON::parse(s).unparse() << std::endl; + } + catch (std::exception& e) + { + std::cerr << "exception: " << filename<< ": " << e.what() << std::endl; + return 2; + } + return 0; +} diff --git a/libtests/libtests.testcov b/libtests/libtests.testcov index 70aae578..5f36819a 100644 --- a/libtests/libtests.testcov +++ b/libtests/libtests.testcov @@ -61,3 +61,29 @@ QPDFArgParser duplicate option help 0 QPDFArgParser bad option for help 0 QPDFArgParser bad topic for help 0 QPDFArgParser invalid choice handler to unknown 0 +JSON parse junk after object 0 +JSON parse decimal with no digits 0 +JSON parse invalid keyword 0 +JSON parse expected colon 0 +JSON parse expected , or } 0 +JSON parse expected, or ] 0 +JSON parse string as dict key 0 +JSON parse unexpected } 0 +JSON parse unexpected ] 0 +JSON parse unexpected : 0 +JSON parse unexpected , 0 +JSON parse preature EOF 0 +JSON parse null character 0 +JSON parse bad character 0 +JSON parse point after e 0 +JSON parse duplicate point 0 +JSON parse duplicate e 0 +JSON parse unexpected sign 0 +JSON parse numeric bad character 0 +JSON parse keyword bad character 0 +JSON parse backslash bad character 0 +JSON parse unterminated string 0 +JSON parse leading zero 0 +JSON parse number no digits 0 +JSON parse premature end of u 0 +JSON parse bad hex after u 0 diff --git a/libtests/qtest/json/json.out b/libtests/qtest/json/json.out index ad668e51..1a320dcf 100644 --- a/libtests/qtest/json/json.out +++ b/libtests/qtest/json/json.out @@ -2,23 +2,24 @@ top-level object is supposed to be a dictionary --- --- missing items -json key "./one./a": key "/q" is present in schema but missing in object -json key "./one./a./r" is supposed to be a dictionary -json key "./one./a./s" is supposed to be an array -json key "./one./a": key "/t" is not present in schema but appears in object -json key "./three./anything": key "/z" is present in schema but missing in object -json key "./three./anything": key "/x" is not present in schema but appears in object -json key "./two.1": key "/glarp" is present in schema but missing in object -json key "./two.1": key "/flarp" is not present in schema but appears in object -json key "./two.2" is supposed to be a dictionary -json key "./two.3" is supposed to be a dictionary +json key ".one.a": key "q" is present in schema but missing in object +json key ".one.a.r" is supposed to be a dictionary +json key ".one.a.s" is supposed to be an array +json key ".one.a": key "t" is not present in schema but appears in object +json key ".three.anything": key "z" is present in schema but missing in object +json key ".three.anything": key "x" is not present in schema but appears in object +json key ".three.else": key "o" is present in schema but missing in object +json key ".two.1": key "glarp" is present in schema but missing in object +json key ".two.1": key "flarp" is not present in schema but appears in object +json key ".two.2" is supposed to be a dictionary +json key ".two.3" is supposed to be a dictionary --- --- top-level schema array error top-level object schema array contains other than one item --- --- lower-level schema array error -json key "./one./a./r" schema array contains other than one item -json key "./two" schema array contains other than one item +json key ".one.a.r" schema array contains other than one item +json key ".two" schema array contains other than one item --- --- pass --- diff --git a/libtests/qtest/json_parse.test b/libtests/qtest/json_parse.test new file mode 100644 index 00000000..7b1824e9 --- /dev/null +++ b/libtests/qtest/json_parse.test @@ -0,0 +1,137 @@ +#!/usr/bin/env perl +require 5.008; +use warnings; +use strict; +use File::Copy; +use File::Compare; + +chdir("json_parse") or die "chdir testdir failed: $!\n"; + +require TestDriver; + +my $td = new TestDriver('json_parse'); + +my $json_mod = 0; +eval { + require JSON; + $json_mod = 1; +}; +if ($@) +{ + $td->emphasize("JSON.pm not found -- using stored actual outputs"); +} + +cleanup(); + +my $good = 9; + +for (my $i = 1; $i <= $good; ++$i) +{ + my $n = sprintf("%02d", $i); + + unlink "out.json"; + my $r = system("json_parse good-$n.json > out.json 2>&1"); + if ($td->runtest("json_parse accepted $n", + {$td->STRING => "$r\n"}, + {$td->STRING => "0\n"}, + $td->NORMALIZE_NEWLINES)) + { + if ($json_mod) + { + if ($td->runtest("check output $n", + {$td->STRING => normalize_json("out.json")}, + {$td->STRING => normalize_json("good-$n.json")}, + $td->NORMALIZE_NEWLINES)) + { + if (compare("out.json", "save-$n.json")) + { + copy("out.json", "save-$n.json"); + $td->emphasize("updated save-$n.json from out.json"); + } + } + } + else + { + $td->runtest("check output $n against saved", + {$td->FILE => "out.json"}, + {$td->FILE => "save-$n.json"}, + $td->NORMALIZE_NEWLINES); + } + } + else + { + $td->runtest("skip checking output $n", + {$td->FILE => "out.json"}, + {$td->STRING => ""}); + } +} + +my @bad = ( + "junk after string", # 1 + "junk after array", # 2 + "junk after dictionary", # 3 + "bad number", # 4 + "invalid keyword", # 5 + "missing colon", # 6 + "missing comma in dict", # 7 + "missing comma in array", # 8 + "dict key not string", # 9 + "unexpected } in array", # 10 + "unexpected } at top", # 11 + "unexpected } in dict", # 12 + "unexpected ] in dict", # 13 + "unexpected ] at top", # 14 + "unexpected :", # 15 + "unexpected ,", # 16 + "premature end array", # 17 + "null character", # 18 + "unexpected character", # 19 + "point in exponent", # 20 + "duplicate point", # 21 + "duplicate e", # 22 + "stray +", # 23 + "bad character in number", # 24 + "bad character in keyword", # 25 + "bad backslash character", # 26 + "unterminated string", # 27 + "unterminated after \\", # 28 + "leading +", # 29 + "decimal with no digits", # 30 + "minus with no digits", # 31 + "leading zero", # 32 + "leading zero negative", # 33 + "premature end after u", # 34 + "bad hex digit", # 35 + ); + +my $i = 0; +foreach my $d (@bad) +{ + ++$i; + my $n = sprintf("%02d", $i); + $td->runtest("$n: $d", + {$td->COMMAND => "json_parse bad-$n.json"}, + {$td->FILE => "bad-$n.out", $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); +} + +cleanup(); + +$td->report((2 * $good) + scalar(@bad)); + +sub cleanup +{ + unlink "out.json"; +} + +sub normalize_json +{ + my $file = shift; + open(F, "<$file") or die "can't open $file: $file: $!\n"; + $/ = undef; + my $encoded = scalar(); + close(F); + my $j = JSON->new->allow_nonref; + $j->canonical(); + $j->utf8->pretty->encode($j->utf8->decode($encoded)); +} diff --git a/libtests/qtest/json_parse/bad-01.json b/libtests/qtest/json_parse/bad-01.json new file mode 100644 index 00000000..be8f5206 --- /dev/null +++ b/libtests/qtest/json_parse/bad-01.json @@ -0,0 +1 @@ +"a" junk diff --git a/libtests/qtest/json_parse/bad-01.out b/libtests/qtest/json_parse/bad-01.out new file mode 100644 index 00000000..a4254cff --- /dev/null +++ b/libtests/qtest/json_parse/bad-01.out @@ -0,0 +1 @@ +exception: bad-01.json: JSON: offset 9: material follows end of object: junk diff --git a/libtests/qtest/json_parse/bad-02.json b/libtests/qtest/json_parse/bad-02.json new file mode 100644 index 00000000..63dffebd --- /dev/null +++ b/libtests/qtest/json_parse/bad-02.json @@ -0,0 +1 @@ +["a"] junk diff --git a/libtests/qtest/json_parse/bad-02.out b/libtests/qtest/json_parse/bad-02.out new file mode 100644 index 00000000..485c9658 --- /dev/null +++ b/libtests/qtest/json_parse/bad-02.out @@ -0,0 +1 @@ +exception: bad-02.json: JSON: offset 11: material follows end of object: junk diff --git a/libtests/qtest/json_parse/bad-03.json b/libtests/qtest/json_parse/bad-03.json new file mode 100644 index 00000000..20769389 --- /dev/null +++ b/libtests/qtest/json_parse/bad-03.json @@ -0,0 +1 @@ +{"a": "b"} junk diff --git a/libtests/qtest/json_parse/bad-03.out b/libtests/qtest/json_parse/bad-03.out new file mode 100644 index 00000000..38f35119 --- /dev/null +++ b/libtests/qtest/json_parse/bad-03.out @@ -0,0 +1 @@ +exception: bad-03.json: JSON: offset 16: material follows end of object: junk diff --git a/libtests/qtest/json_parse/bad-04.json b/libtests/qtest/json_parse/bad-04.json new file mode 100644 index 00000000..cb5c9145 --- /dev/null +++ b/libtests/qtest/json_parse/bad-04.json @@ -0,0 +1,2 @@ +[1, .] + diff --git a/libtests/qtest/json_parse/bad-04.out b/libtests/qtest/json_parse/bad-04.out new file mode 100644 index 00000000..7fe71693 --- /dev/null +++ b/libtests/qtest/json_parse/bad-04.out @@ -0,0 +1 @@ +exception: bad-04.json: JSON: offset 5: decimal point with no digits diff --git a/libtests/qtest/json_parse/bad-05.json b/libtests/qtest/json_parse/bad-05.json new file mode 100644 index 00000000..632b1ab2 --- /dev/null +++ b/libtests/qtest/json_parse/bad-05.json @@ -0,0 +1 @@ +[true, potato] diff --git a/libtests/qtest/json_parse/bad-05.out b/libtests/qtest/json_parse/bad-05.out new file mode 100644 index 00000000..d94b4e62 --- /dev/null +++ b/libtests/qtest/json_parse/bad-05.out @@ -0,0 +1 @@ +exception: bad-05.json: JSON: offset 13: invalid keyword potato diff --git a/libtests/qtest/json_parse/bad-06.json b/libtests/qtest/json_parse/bad-06.json new file mode 100644 index 00000000..de355688 --- /dev/null +++ b/libtests/qtest/json_parse/bad-06.json @@ -0,0 +1 @@ +{"x" "y"} diff --git a/libtests/qtest/json_parse/bad-06.out b/libtests/qtest/json_parse/bad-06.out new file mode 100644 index 00000000..8ed262ce --- /dev/null +++ b/libtests/qtest/json_parse/bad-06.out @@ -0,0 +1 @@ +exception: bad-06.json: JSON: offset 8: expected ':' diff --git a/libtests/qtest/json_parse/bad-07.json b/libtests/qtest/json_parse/bad-07.json new file mode 100644 index 00000000..b24dc391 --- /dev/null +++ b/libtests/qtest/json_parse/bad-07.json @@ -0,0 +1 @@ +{"x": 3 "y"} diff --git a/libtests/qtest/json_parse/bad-07.out b/libtests/qtest/json_parse/bad-07.out new file mode 100644 index 00000000..06774722 --- /dev/null +++ b/libtests/qtest/json_parse/bad-07.out @@ -0,0 +1 @@ +exception: bad-07.json: JSON: offset 11: expected ',' or '}' diff --git a/libtests/qtest/json_parse/bad-08.json b/libtests/qtest/json_parse/bad-08.json new file mode 100644 index 00000000..b15acc57 --- /dev/null +++ b/libtests/qtest/json_parse/bad-08.json @@ -0,0 +1 @@ +["x" "y"] diff --git a/libtests/qtest/json_parse/bad-08.out b/libtests/qtest/json_parse/bad-08.out new file mode 100644 index 00000000..c597e60e --- /dev/null +++ b/libtests/qtest/json_parse/bad-08.out @@ -0,0 +1 @@ +exception: bad-08.json: JSON: offset 8: expected ',' or ']' diff --git a/libtests/qtest/json_parse/bad-09.json b/libtests/qtest/json_parse/bad-09.json new file mode 100644 index 00000000..d82de610 --- /dev/null +++ b/libtests/qtest/json_parse/bad-09.json @@ -0,0 +1 @@ +{5 : 5} diff --git a/libtests/qtest/json_parse/bad-09.out b/libtests/qtest/json_parse/bad-09.out new file mode 100644 index 00000000..21d2f1c1 --- /dev/null +++ b/libtests/qtest/json_parse/bad-09.out @@ -0,0 +1 @@ +exception: bad-09.json: JSON: offset 3: expect string as dictionary key diff --git a/libtests/qtest/json_parse/bad-10.json b/libtests/qtest/json_parse/bad-10.json new file mode 100644 index 00000000..f5cc41b6 --- /dev/null +++ b/libtests/qtest/json_parse/bad-10.json @@ -0,0 +1 @@ +["a"} diff --git a/libtests/qtest/json_parse/bad-10.out b/libtests/qtest/json_parse/bad-10.out new file mode 100644 index 00000000..d725d492 --- /dev/null +++ b/libtests/qtest/json_parse/bad-10.out @@ -0,0 +1 @@ +exception: bad-10.json: JSON: offset 5: unexpected dictionary end delimiter diff --git a/libtests/qtest/json_parse/bad-11.json b/libtests/qtest/json_parse/bad-11.json new file mode 100644 index 00000000..5c34318c --- /dev/null +++ b/libtests/qtest/json_parse/bad-11.json @@ -0,0 +1 @@ +} diff --git a/libtests/qtest/json_parse/bad-11.out b/libtests/qtest/json_parse/bad-11.out new file mode 100644 index 00000000..ae8fd636 --- /dev/null +++ b/libtests/qtest/json_parse/bad-11.out @@ -0,0 +1 @@ +exception: bad-11.json: JSON: offset 1: unexpected dictionary end delimiter diff --git a/libtests/qtest/json_parse/bad-12.json b/libtests/qtest/json_parse/bad-12.json new file mode 100644 index 00000000..c9c9b68f --- /dev/null +++ b/libtests/qtest/json_parse/bad-12.json @@ -0,0 +1 @@ +{""} diff --git a/libtests/qtest/json_parse/bad-12.out b/libtests/qtest/json_parse/bad-12.out new file mode 100644 index 00000000..0ff371a1 --- /dev/null +++ b/libtests/qtest/json_parse/bad-12.out @@ -0,0 +1 @@ +exception: bad-12.json: JSON: offset 4: unexpected dictionary end delimiter diff --git a/libtests/qtest/json_parse/bad-13.json b/libtests/qtest/json_parse/bad-13.json new file mode 100644 index 00000000..70312269 --- /dev/null +++ b/libtests/qtest/json_parse/bad-13.json @@ -0,0 +1 @@ +{"": "x"] diff --git a/libtests/qtest/json_parse/bad-13.out b/libtests/qtest/json_parse/bad-13.out new file mode 100644 index 00000000..8a53bd3f --- /dev/null +++ b/libtests/qtest/json_parse/bad-13.out @@ -0,0 +1 @@ +exception: bad-13.json: JSON: offset 9: unexpected array end delimiter diff --git a/libtests/qtest/json_parse/bad-14.json b/libtests/qtest/json_parse/bad-14.json new file mode 100644 index 00000000..079b5796 --- /dev/null +++ b/libtests/qtest/json_parse/bad-14.json @@ -0,0 +1 @@ +] diff --git a/libtests/qtest/json_parse/bad-14.out b/libtests/qtest/json_parse/bad-14.out new file mode 100644 index 00000000..8f619ef8 --- /dev/null +++ b/libtests/qtest/json_parse/bad-14.out @@ -0,0 +1 @@ +exception: bad-14.json: JSON: offset 1: unexpected array end delimiter diff --git a/libtests/qtest/json_parse/bad-15.json b/libtests/qtest/json_parse/bad-15.json new file mode 100644 index 00000000..aaac6657 --- /dev/null +++ b/libtests/qtest/json_parse/bad-15.json @@ -0,0 +1 @@ +["a": ] diff --git a/libtests/qtest/json_parse/bad-15.out b/libtests/qtest/json_parse/bad-15.out new file mode 100644 index 00000000..68153212 --- /dev/null +++ b/libtests/qtest/json_parse/bad-15.out @@ -0,0 +1 @@ +exception: bad-15.json: JSON: offset 5: unexpected colon diff --git a/libtests/qtest/json_parse/bad-16.json b/libtests/qtest/json_parse/bad-16.json new file mode 100644 index 00000000..12684fdb --- /dev/null +++ b/libtests/qtest/json_parse/bad-16.json @@ -0,0 +1 @@ +[,] diff --git a/libtests/qtest/json_parse/bad-16.out b/libtests/qtest/json_parse/bad-16.out new file mode 100644 index 00000000..1553e0b6 --- /dev/null +++ b/libtests/qtest/json_parse/bad-16.out @@ -0,0 +1 @@ +exception: bad-16.json: JSON: offset 2: unexpected comma diff --git a/libtests/qtest/json_parse/bad-17.json b/libtests/qtest/json_parse/bad-17.json new file mode 100644 index 00000000..0617cad4 --- /dev/null +++ b/libtests/qtest/json_parse/bad-17.json @@ -0,0 +1 @@ +[1, 2, diff --git a/libtests/qtest/json_parse/bad-17.out b/libtests/qtest/json_parse/bad-17.out new file mode 100644 index 00000000..d2bf40e2 --- /dev/null +++ b/libtests/qtest/json_parse/bad-17.out @@ -0,0 +1 @@ +exception: bad-17.json: JSON: premature end of input diff --git a/libtests/qtest/json_parse/bad-18.json b/libtests/qtest/json_parse/bad-18.json new file mode 100644 index 00000000..a0c81001 Binary files /dev/null and b/libtests/qtest/json_parse/bad-18.json differ diff --git a/libtests/qtest/json_parse/bad-18.out b/libtests/qtest/json_parse/bad-18.out new file mode 100644 index 00000000..0428b64f --- /dev/null +++ b/libtests/qtest/json_parse/bad-18.out @@ -0,0 +1 @@ +exception: bad-18.json: JSON: null character at offset 5 diff --git a/libtests/qtest/json_parse/bad-19.json b/libtests/qtest/json_parse/bad-19.json new file mode 100644 index 00000000..b498fd49 --- /dev/null +++ b/libtests/qtest/json_parse/bad-19.json @@ -0,0 +1 @@ +/ diff --git a/libtests/qtest/json_parse/bad-19.out b/libtests/qtest/json_parse/bad-19.out new file mode 100644 index 00000000..534ff943 --- /dev/null +++ b/libtests/qtest/json_parse/bad-19.out @@ -0,0 +1 @@ +exception: bad-19.json: JSON: offset 0: unexpected character / diff --git a/libtests/qtest/json_parse/bad-20.json b/libtests/qtest/json_parse/bad-20.json new file mode 100644 index 00000000..fb5264eb --- /dev/null +++ b/libtests/qtest/json_parse/bad-20.json @@ -0,0 +1 @@ +3.14e5.6 diff --git a/libtests/qtest/json_parse/bad-20.out b/libtests/qtest/json_parse/bad-20.out new file mode 100644 index 00000000..e761bf0c --- /dev/null +++ b/libtests/qtest/json_parse/bad-20.out @@ -0,0 +1 @@ +exception: bad-20.json: JSON: offset 6: numeric literal: decimal point after e diff --git a/libtests/qtest/json_parse/bad-21.json b/libtests/qtest/json_parse/bad-21.json new file mode 100644 index 00000000..bd87886b --- /dev/null +++ b/libtests/qtest/json_parse/bad-21.json @@ -0,0 +1 @@ +3.14.159 diff --git a/libtests/qtest/json_parse/bad-21.out b/libtests/qtest/json_parse/bad-21.out new file mode 100644 index 00000000..697fb0e3 --- /dev/null +++ b/libtests/qtest/json_parse/bad-21.out @@ -0,0 +1 @@ +exception: bad-21.json: JSON: offset 4: numeric literal: decimal point already seen diff --git a/libtests/qtest/json_parse/bad-22.json b/libtests/qtest/json_parse/bad-22.json new file mode 100644 index 00000000..38860be1 --- /dev/null +++ b/libtests/qtest/json_parse/bad-22.json @@ -0,0 +1 @@ +3e4e5 diff --git a/libtests/qtest/json_parse/bad-22.out b/libtests/qtest/json_parse/bad-22.out new file mode 100644 index 00000000..bb48715b --- /dev/null +++ b/libtests/qtest/json_parse/bad-22.out @@ -0,0 +1 @@ +exception: bad-22.json: JSON: offset 3: numeric literal: e already seen diff --git a/libtests/qtest/json_parse/bad-23.json b/libtests/qtest/json_parse/bad-23.json new file mode 100644 index 00000000..60def52f --- /dev/null +++ b/libtests/qtest/json_parse/bad-23.json @@ -0,0 +1 @@ +3+4 diff --git a/libtests/qtest/json_parse/bad-23.out b/libtests/qtest/json_parse/bad-23.out new file mode 100644 index 00000000..18872df5 --- /dev/null +++ b/libtests/qtest/json_parse/bad-23.out @@ -0,0 +1 @@ +exception: bad-23.json: JSON: offset 1: numeric literal: unexpected sign diff --git a/libtests/qtest/json_parse/bad-24.json b/libtests/qtest/json_parse/bad-24.json new file mode 100644 index 00000000..c863fc63 --- /dev/null +++ b/libtests/qtest/json_parse/bad-24.json @@ -0,0 +1 @@ +12x diff --git a/libtests/qtest/json_parse/bad-24.out b/libtests/qtest/json_parse/bad-24.out new file mode 100644 index 00000000..7d539267 --- /dev/null +++ b/libtests/qtest/json_parse/bad-24.out @@ -0,0 +1 @@ +exception: bad-24.json: JSON: offset 2: numeric literal: unexpected character x diff --git a/libtests/qtest/json_parse/bad-25.json b/libtests/qtest/json_parse/bad-25.json new file mode 100644 index 00000000..6fede091 --- /dev/null +++ b/libtests/qtest/json_parse/bad-25.json @@ -0,0 +1 @@ +abc1 diff --git a/libtests/qtest/json_parse/bad-25.out b/libtests/qtest/json_parse/bad-25.out new file mode 100644 index 00000000..f2572b25 --- /dev/null +++ b/libtests/qtest/json_parse/bad-25.out @@ -0,0 +1 @@ +exception: bad-25.json: JSON: offset 3: keyword: unexpected character 1 diff --git a/libtests/qtest/json_parse/bad-26.json b/libtests/qtest/json_parse/bad-26.json new file mode 100644 index 00000000..5c62a2f2 --- /dev/null +++ b/libtests/qtest/json_parse/bad-26.json @@ -0,0 +1 @@ +"abc\yd" diff --git a/libtests/qtest/json_parse/bad-26.out b/libtests/qtest/json_parse/bad-26.out new file mode 100644 index 00000000..33f536c1 --- /dev/null +++ b/libtests/qtest/json_parse/bad-26.out @@ -0,0 +1 @@ +exception: bad-26.json: JSON: offset 5: invalid character after backslash: y diff --git a/libtests/qtest/json_parse/bad-27.json b/libtests/qtest/json_parse/bad-27.json new file mode 100644 index 00000000..083d193e --- /dev/null +++ b/libtests/qtest/json_parse/bad-27.json @@ -0,0 +1 @@ +"abcd diff --git a/libtests/qtest/json_parse/bad-27.out b/libtests/qtest/json_parse/bad-27.out new file mode 100644 index 00000000..2c2df076 --- /dev/null +++ b/libtests/qtest/json_parse/bad-27.out @@ -0,0 +1 @@ +exception: bad-27.json: JSON: offset 6: unterminated string diff --git a/libtests/qtest/json_parse/bad-28.json b/libtests/qtest/json_parse/bad-28.json new file mode 100644 index 00000000..9b571f08 --- /dev/null +++ b/libtests/qtest/json_parse/bad-28.json @@ -0,0 +1 @@ +"abc-no-newline\ \ No newline at end of file diff --git a/libtests/qtest/json_parse/bad-28.out b/libtests/qtest/json_parse/bad-28.out new file mode 100644 index 00000000..d7db2aea --- /dev/null +++ b/libtests/qtest/json_parse/bad-28.out @@ -0,0 +1 @@ +exception: bad-28.json: JSON: offset 16: unterminated string diff --git a/libtests/qtest/json_parse/bad-29.json b/libtests/qtest/json_parse/bad-29.json new file mode 100644 index 00000000..c367cd81 --- /dev/null +++ b/libtests/qtest/json_parse/bad-29.json @@ -0,0 +1 @@ ++123. diff --git a/libtests/qtest/json_parse/bad-29.out b/libtests/qtest/json_parse/bad-29.out new file mode 100644 index 00000000..b7ee83fb --- /dev/null +++ b/libtests/qtest/json_parse/bad-29.out @@ -0,0 +1 @@ +exception: bad-29.json: JSON: offset 0: unexpected character + diff --git a/libtests/qtest/json_parse/bad-30.json b/libtests/qtest/json_parse/bad-30.json new file mode 100644 index 00000000..b8db69c7 --- /dev/null +++ b/libtests/qtest/json_parse/bad-30.json @@ -0,0 +1 @@ +123. diff --git a/libtests/qtest/json_parse/bad-30.out b/libtests/qtest/json_parse/bad-30.out new file mode 100644 index 00000000..bff961af --- /dev/null +++ b/libtests/qtest/json_parse/bad-30.out @@ -0,0 +1 @@ +exception: bad-30.json: JSON: offset 5: decimal point with no digits diff --git a/libtests/qtest/json_parse/bad-31.json b/libtests/qtest/json_parse/bad-31.json new file mode 100644 index 00000000..39cdd0de --- /dev/null +++ b/libtests/qtest/json_parse/bad-31.json @@ -0,0 +1 @@ +- diff --git a/libtests/qtest/json_parse/bad-31.out b/libtests/qtest/json_parse/bad-31.out new file mode 100644 index 00000000..344f42e8 --- /dev/null +++ b/libtests/qtest/json_parse/bad-31.out @@ -0,0 +1 @@ +exception: bad-31.json: JSON: offset 2: number with no digits diff --git a/libtests/qtest/json_parse/bad-32.json b/libtests/qtest/json_parse/bad-32.json new file mode 100644 index 00000000..40381e26 --- /dev/null +++ b/libtests/qtest/json_parse/bad-32.json @@ -0,0 +1 @@ +0123 diff --git a/libtests/qtest/json_parse/bad-32.out b/libtests/qtest/json_parse/bad-32.out new file mode 100644 index 00000000..4372e0cf --- /dev/null +++ b/libtests/qtest/json_parse/bad-32.out @@ -0,0 +1 @@ +exception: bad-32.json: JSON: offset 5: number with leading zero diff --git a/libtests/qtest/json_parse/bad-33.json b/libtests/qtest/json_parse/bad-33.json new file mode 100644 index 00000000..2e7a4b45 --- /dev/null +++ b/libtests/qtest/json_parse/bad-33.json @@ -0,0 +1 @@ +-0123 diff --git a/libtests/qtest/json_parse/bad-33.out b/libtests/qtest/json_parse/bad-33.out new file mode 100644 index 00000000..ae41e48b --- /dev/null +++ b/libtests/qtest/json_parse/bad-33.out @@ -0,0 +1 @@ +exception: bad-33.json: JSON: offset 6: number with leading zero diff --git a/libtests/qtest/json_parse/bad-34.json b/libtests/qtest/json_parse/bad-34.json new file mode 100644 index 00000000..fdefd9af --- /dev/null +++ b/libtests/qtest/json_parse/bad-34.json @@ -0,0 +1 @@ +"a\u123 \ No newline at end of file diff --git a/libtests/qtest/json_parse/bad-34.out b/libtests/qtest/json_parse/bad-34.out new file mode 100644 index 00000000..f9db587a --- /dev/null +++ b/libtests/qtest/json_parse/bad-34.out @@ -0,0 +1 @@ +exception: bad-34.json: JSON: offset 3: \u must be followed by four characters diff --git a/libtests/qtest/json_parse/bad-35.json b/libtests/qtest/json_parse/bad-35.json new file mode 100644 index 00000000..b7bea102 --- /dev/null +++ b/libtests/qtest/json_parse/bad-35.json @@ -0,0 +1 @@ +"a\u123qx" diff --git a/libtests/qtest/json_parse/bad-35.out b/libtests/qtest/json_parse/bad-35.out new file mode 100644 index 00000000..dabd6571 --- /dev/null +++ b/libtests/qtest/json_parse/bad-35.out @@ -0,0 +1 @@ +exception: bad-35.json: JSON: offset 3: \u must be followed by four hex digits diff --git a/libtests/qtest/json_parse/good-01.json b/libtests/qtest/json_parse/good-01.json new file mode 100644 index 00000000..3d6ce297 --- /dev/null +++ b/libtests/qtest/json_parse/good-01.json @@ -0,0 +1,3 @@ +{"a": "bcd", "e": [1, + 2, 3,4,"five", {"six": 7, "8": 9}, null, true, + false]} diff --git a/libtests/qtest/json_parse/good-02.json b/libtests/qtest/json_parse/good-02.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/libtests/qtest/json_parse/good-02.json @@ -0,0 +1 @@ +{} diff --git a/libtests/qtest/json_parse/good-03.json b/libtests/qtest/json_parse/good-03.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/libtests/qtest/json_parse/good-03.json @@ -0,0 +1 @@ +[] diff --git a/libtests/qtest/json_parse/good-04.json b/libtests/qtest/json_parse/good-04.json new file mode 100644 index 00000000..d6144800 --- /dev/null +++ b/libtests/qtest/json_parse/good-04.json @@ -0,0 +1 @@ +[[[{}], {"": {}}]] diff --git a/libtests/qtest/json_parse/good-05.json b/libtests/qtest/json_parse/good-05.json new file mode 100644 index 00000000..92232f69 --- /dev/null +++ b/libtests/qtest/json_parse/good-05.json @@ -0,0 +1 @@ +"x" diff --git a/libtests/qtest/json_parse/good-06.json b/libtests/qtest/json_parse/good-06.json new file mode 100644 index 00000000..190a1803 --- /dev/null +++ b/libtests/qtest/json_parse/good-06.json @@ -0,0 +1 @@ +123 diff --git a/libtests/qtest/json_parse/good-07.json b/libtests/qtest/json_parse/good-07.json new file mode 100644 index 00000000..3a437cdb --- /dev/null +++ b/libtests/qtest/json_parse/good-07.json @@ -0,0 +1 @@ +-123 diff --git a/libtests/qtest/json_parse/good-08.json b/libtests/qtest/json_parse/good-08.json new file mode 100644 index 00000000..5708ac7f --- /dev/null +++ b/libtests/qtest/json_parse/good-08.json @@ -0,0 +1 @@ +[1, -2, 3.4, -5.6, -9e1, 10e2, 12.3e5, 12.6e-7] diff --git a/libtests/qtest/json_parse/good-09.json b/libtests/qtest/json_parse/good-09.json new file mode 100644 index 00000000..91db9d20 --- /dev/null +++ b/libtests/qtest/json_parse/good-09.json @@ -0,0 +1 @@ +["aπb", "a\b\f\n\r\tc", "a\u03c0b\u03C0c", "\u03c0", "a\u0018b\u02acc"] diff --git a/libtests/qtest/json_parse/save-01.json b/libtests/qtest/json_parse/save-01.json new file mode 100644 index 00000000..2a9e3c20 --- /dev/null +++ b/libtests/qtest/json_parse/save-01.json @@ -0,0 +1,17 @@ +{ + "a": "bcd", + "e": [ + 1, + 2, + 3, + 4, + "five", + { + "8": 9, + "six": 7 + }, + null, + true, + false + ] +} diff --git a/libtests/qtest/json_parse/save-02.json b/libtests/qtest/json_parse/save-02.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/libtests/qtest/json_parse/save-02.json @@ -0,0 +1 @@ +{} diff --git a/libtests/qtest/json_parse/save-03.json b/libtests/qtest/json_parse/save-03.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/libtests/qtest/json_parse/save-03.json @@ -0,0 +1 @@ +[] diff --git a/libtests/qtest/json_parse/save-04.json b/libtests/qtest/json_parse/save-04.json new file mode 100644 index 00000000..9286cc19 --- /dev/null +++ b/libtests/qtest/json_parse/save-04.json @@ -0,0 +1,10 @@ +[ + [ + [ + {} + ], + { + "": {} + } + ] +] diff --git a/libtests/qtest/json_parse/save-05.json b/libtests/qtest/json_parse/save-05.json new file mode 100644 index 00000000..92232f69 --- /dev/null +++ b/libtests/qtest/json_parse/save-05.json @@ -0,0 +1 @@ +"x" diff --git a/libtests/qtest/json_parse/save-06.json b/libtests/qtest/json_parse/save-06.json new file mode 100644 index 00000000..190a1803 --- /dev/null +++ b/libtests/qtest/json_parse/save-06.json @@ -0,0 +1 @@ +123 diff --git a/libtests/qtest/json_parse/save-07.json b/libtests/qtest/json_parse/save-07.json new file mode 100644 index 00000000..3a437cdb --- /dev/null +++ b/libtests/qtest/json_parse/save-07.json @@ -0,0 +1 @@ +-123 diff --git a/libtests/qtest/json_parse/save-08.json b/libtests/qtest/json_parse/save-08.json new file mode 100644 index 00000000..30ceeba1 --- /dev/null +++ b/libtests/qtest/json_parse/save-08.json @@ -0,0 +1,10 @@ +[ + 1, + -2, + 3.4, + -5.6, + -9e1, + 10e2, + 12.3e5, + 12.6e-7 +] diff --git a/libtests/qtest/json_parse/save-09.json b/libtests/qtest/json_parse/save-09.json new file mode 100644 index 00000000..a064cbac --- /dev/null +++ b/libtests/qtest/json_parse/save-09.json @@ -0,0 +1,7 @@ +[ + "aπb", + "a\b\f\n\r\tc", + "aπbπc", + "π", + "a\u0018bʬc" +] -- cgit v1.2.3-54-g00ecf