diff --git a/Makefile b/Makefile index d2fa8aba4..7b2c456ba 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,9 @@ EXECUTABLES=parse all: $(EXECUTABLES) + -./parse -parse: main.cpp common_defs.h vecdecode.h linux-perf-events.h +parse: main.cpp common_defs.h linux-perf-events.h $(CXX) $(CXXFLAGS) -o parse main.cpp diff --git a/jsonchecker/fail01_EXCLUDE.json b/jsonchecker/fail01_EXCLUDE.json new file mode 100644 index 000000000..6216b865f --- /dev/null +++ b/jsonchecker/fail01_EXCLUDE.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/jsonchecker/fail02.json b/jsonchecker/fail02.json new file mode 100644 index 000000000..6b7c11e5a --- /dev/null +++ b/jsonchecker/fail02.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/jsonchecker/fail03.json b/jsonchecker/fail03.json new file mode 100644 index 000000000..168c81eb7 --- /dev/null +++ b/jsonchecker/fail03.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/jsonchecker/fail04.json b/jsonchecker/fail04.json new file mode 100644 index 000000000..9de168bf3 --- /dev/null +++ b/jsonchecker/fail04.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/jsonchecker/fail05.json b/jsonchecker/fail05.json new file mode 100644 index 000000000..ddf3ce3d2 --- /dev/null +++ b/jsonchecker/fail05.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/jsonchecker/fail06.json b/jsonchecker/fail06.json new file mode 100644 index 000000000..ed91580e1 --- /dev/null +++ b/jsonchecker/fail06.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/jsonchecker/fail07.json b/jsonchecker/fail07.json new file mode 100644 index 000000000..8a96af3e4 --- /dev/null +++ b/jsonchecker/fail07.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/jsonchecker/fail08.json b/jsonchecker/fail08.json new file mode 100644 index 000000000..b28479c6e --- /dev/null +++ b/jsonchecker/fail08.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/jsonchecker/fail09.json b/jsonchecker/fail09.json new file mode 100644 index 000000000..5815574f3 --- /dev/null +++ b/jsonchecker/fail09.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/jsonchecker/fail10.json b/jsonchecker/fail10.json new file mode 100644 index 000000000..5d8c0047b --- /dev/null +++ b/jsonchecker/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/jsonchecker/fail11.json b/jsonchecker/fail11.json new file mode 100644 index 000000000..76eb95b45 --- /dev/null +++ b/jsonchecker/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/jsonchecker/fail12.json b/jsonchecker/fail12.json new file mode 100644 index 000000000..77580a452 --- /dev/null +++ b/jsonchecker/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/jsonchecker/fail13.json b/jsonchecker/fail13.json new file mode 100644 index 000000000..379406b59 --- /dev/null +++ b/jsonchecker/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/jsonchecker/fail14.json b/jsonchecker/fail14.json new file mode 100644 index 000000000..0ed366b38 --- /dev/null +++ b/jsonchecker/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/jsonchecker/fail15.json b/jsonchecker/fail15.json new file mode 100644 index 000000000..fc8376b60 --- /dev/null +++ b/jsonchecker/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/jsonchecker/fail16.json b/jsonchecker/fail16.json new file mode 100644 index 000000000..3fe21d4b5 --- /dev/null +++ b/jsonchecker/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/jsonchecker/fail17.json b/jsonchecker/fail17.json new file mode 100644 index 000000000..62b9214ae --- /dev/null +++ b/jsonchecker/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/jsonchecker/fail18_EXCLUDE.json b/jsonchecker/fail18_EXCLUDE.json new file mode 100644 index 000000000..edac92716 --- /dev/null +++ b/jsonchecker/fail18_EXCLUDE.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/jsonchecker/fail19.json b/jsonchecker/fail19.json new file mode 100644 index 000000000..3b9c46fa9 --- /dev/null +++ b/jsonchecker/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/jsonchecker/fail20.json b/jsonchecker/fail20.json new file mode 100644 index 000000000..27c1af3e7 --- /dev/null +++ b/jsonchecker/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/jsonchecker/fail21.json b/jsonchecker/fail21.json new file mode 100644 index 000000000..62474573b --- /dev/null +++ b/jsonchecker/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/jsonchecker/fail22.json b/jsonchecker/fail22.json new file mode 100644 index 000000000..a7752581b --- /dev/null +++ b/jsonchecker/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/jsonchecker/fail23.json b/jsonchecker/fail23.json new file mode 100644 index 000000000..494add1ca --- /dev/null +++ b/jsonchecker/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/jsonchecker/fail24.json b/jsonchecker/fail24.json new file mode 100644 index 000000000..caff239bf --- /dev/null +++ b/jsonchecker/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/jsonchecker/fail25.json b/jsonchecker/fail25.json new file mode 100644 index 000000000..8b7ad23e0 --- /dev/null +++ b/jsonchecker/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/jsonchecker/fail26.json b/jsonchecker/fail26.json new file mode 100644 index 000000000..845d26a6a --- /dev/null +++ b/jsonchecker/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/jsonchecker/fail27.json b/jsonchecker/fail27.json new file mode 100644 index 000000000..6b01a2ca4 --- /dev/null +++ b/jsonchecker/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/jsonchecker/fail28.json b/jsonchecker/fail28.json new file mode 100644 index 000000000..621a0101c --- /dev/null +++ b/jsonchecker/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/jsonchecker/fail29.json b/jsonchecker/fail29.json new file mode 100644 index 000000000..47ec421bb --- /dev/null +++ b/jsonchecker/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/jsonchecker/fail30.json b/jsonchecker/fail30.json new file mode 100644 index 000000000..8ab0bc4b8 --- /dev/null +++ b/jsonchecker/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/jsonchecker/fail31.json b/jsonchecker/fail31.json new file mode 100644 index 000000000..1cce602b5 --- /dev/null +++ b/jsonchecker/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/jsonchecker/fail32.json b/jsonchecker/fail32.json new file mode 100644 index 000000000..45cba7396 --- /dev/null +++ b/jsonchecker/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/jsonchecker/fail33.json b/jsonchecker/fail33.json new file mode 100644 index 000000000..ca5eb19dc --- /dev/null +++ b/jsonchecker/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/jsonchecker/pass01.json b/jsonchecker/pass01.json new file mode 100644 index 000000000..70e268543 --- /dev/null +++ b/jsonchecker/pass01.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/jsonchecker/pass02.json b/jsonchecker/pass02.json new file mode 100644 index 000000000..d3c63c7ad --- /dev/null +++ b/jsonchecker/pass02.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/jsonchecker/pass03.json b/jsonchecker/pass03.json new file mode 100644 index 000000000..4528d51f1 --- /dev/null +++ b/jsonchecker/pass03.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/main.cpp b/main.cpp index dd3d95b62..86ecc8f6a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,10 @@ +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -1160,9 +1167,81 @@ void colorfuldisplay(ParsedJson & pj, const u8 * buf) { } std::cout << std::endl; } + + +/** + * Does the file filename ends with the given extension. + */ +static bool hasExtension(const char *filename, const char *extension) { + const char *ext = strrchr(filename, '.'); + return (ext && !strcmp(ext, extension)); +} + +bool startsWith(const char *pre, const char *str) { + size_t lenpre = strlen(pre), + lenstr = strlen(str); + return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0; +} + +void validate() { + init_state_machine();// to be safe + const char *dirname = "jsonchecker/"; // ugly, hardcoded, brittle + const char *extension = ".json"; + size_t dirlen = strlen(dirname); + struct dirent **entry_list; + int c = scandir(dirname, &entry_list, 0, alphasort); + if (c < 0) { + printf("error accessing %s \n", dirname); + return; + } + if (c == 0) { + printf("nothing in dir %s \n", dirname); + return; + } + for (int i = 0; i < c; i++) { + const char *name = entry_list[i]->d_name; + if (hasExtension(name, extension)) { + size_t filelen = strlen(name); + char *fullpath = (char *)malloc(dirlen + filelen + 1); + strcpy(fullpath, dirname); + strcpy(fullpath + dirlen, name); + pair p = get_corpus(fullpath); + ParsedJson pj; + if (posix_memalign( (void **)&pj.structurals, 8, ROUNDUP_N(p.second, 64)/8)) { + cerr << "Could not allocate memory\n"; + return; + }; + pj.n_structural_indexes = 0; + u32 max_structures = ROUNDUP_N(p.second, 64) + 2 + 7; + pj.structural_indexes = new u32[max_structures]; + pj.nodes = new JsonNode[max_structures]; + find_structural_bits(p.first, p.second, pj); + flatten_indexes(p.second, pj); + bool isok = ape_machine(p.first, p.second, pj); + if(isok) + isok = shovel_machine(p.first, p.second, pj); + if(startsWith("pass",name)) { + if(!isok) printf("warning: file %s should pass but it fails.\n",name); + } + if(startsWith("fail",name)) { + if(isok) printf("warning: file %s should fail but it passes.\n",name); + } + free(pj.structurals); + free(p.first); + delete[] pj.structural_indexes; + delete[] pj.nodes; + free(fullpath); + } + } + for (int i = 0; i < c; ++i) free(entry_list[i]); + free(entry_list); +} + int main(int argc, char * argv[]) { if (argc != 2) { cerr << "Usage: " << argv[0] << " \n"; + cout << "We are going to validate:\n" << std::endl; + validate(); exit(1); } pair p = get_corpus(argv[1]);