| // Tencent is pleased to support the open source community by making RapidJSON available. |
| // |
| // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. |
| // |
| // Licensed under the MIT License (the "License"); you may not use this file except |
| // in compliance with the License. You may obtain a copy of the License at |
| // |
| // http://opensource.org/licenses/MIT |
| // |
| // Unless required by applicable law or agreed to in writing, software distributed |
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
| // CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations under the License. |
| |
| #include "unittest.h" |
| |
| #include "rapidjson/document.h" |
| |
| using namespace rapidjson; |
| |
| static char* ReadFile(const char* filename, size_t& length) { |
| const char *paths[] = { |
| "jsonchecker", |
| "bin/jsonchecker", |
| "../bin/jsonchecker", |
| "../../bin/jsonchecker", |
| "../../../bin/jsonchecker" |
| }; |
| char buffer[1024]; |
| FILE *fp = 0; |
| for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { |
| sprintf(buffer, "%s/%s", paths[i], filename); |
| fp = fopen(buffer, "rb"); |
| if (fp) |
| break; |
| } |
| |
| if (!fp) |
| return 0; |
| |
| fseek(fp, 0, SEEK_END); |
| length = static_cast<size_t>(ftell(fp)); |
| fseek(fp, 0, SEEK_SET); |
| char* json = static_cast<char*>(malloc(length + 1)); |
| size_t readLength = fread(json, 1, length, fp); |
| json[readLength] = '\0'; |
| fclose(fp); |
| return json; |
| } |
| |
| struct NoOpHandler { |
| bool Null() { return true; } |
| bool Bool(bool) { return true; } |
| bool Int(int) { return true; } |
| bool Uint(unsigned) { return true; } |
| bool Int64(int64_t) { return true; } |
| bool Uint64(uint64_t) { return true; } |
| bool Double(double) { return true; } |
| bool RawNumber(const char*, SizeType, bool) { return true; } |
| bool String(const char*, SizeType, bool) { return true; } |
| bool StartObject() { return true; } |
| bool Key(const char*, SizeType, bool) { return true; } |
| bool EndObject(SizeType) { return true; } |
| bool StartArray() { return true; } |
| bool EndArray(SizeType) { return true; } |
| }; |
| |
| |
| TEST(JsonChecker, Reader) { |
| char filename[256]; |
| |
| // jsonchecker/failXX.json |
| for (int i = 1; i <= 33; i++) { |
| if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159). |
| continue; |
| if (i == 18) // fail18.json is valid in rapidjson, which has no limitation on depth of nesting. |
| continue; |
| |
| sprintf(filename, "fail%d.json", i); |
| size_t length; |
| char* json = ReadFile(filename, length); |
| if (!json) { |
| printf("jsonchecker file %s not found", filename); |
| ADD_FAILURE(); |
| continue; |
| } |
| |
| // Test stack-based parsing. |
| GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) |
| document.Parse(json); |
| EXPECT_TRUE(document.HasParseError()) << filename; |
| |
| // Test iterative parsing. |
| document.Parse<kParseIterativeFlag>(json); |
| EXPECT_TRUE(document.HasParseError()) << filename; |
| |
| // Test iterative pull-parsing. |
| Reader reader; |
| StringStream ss(json); |
| NoOpHandler h; |
| reader.IterativeParseInit(); |
| while (!reader.IterativeParseComplete()) { |
| if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h)) |
| break; |
| } |
| EXPECT_TRUE(reader.HasParseError()) << filename; |
| |
| free(json); |
| } |
| |
| // passX.json |
| for (int i = 1; i <= 3; i++) { |
| sprintf(filename, "pass%d.json", i); |
| size_t length; |
| char* json = ReadFile(filename, length); |
| if (!json) { |
| printf("jsonchecker file %s not found", filename); |
| continue; |
| } |
| |
| // Test stack-based parsing. |
| GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) |
| document.Parse(json); |
| EXPECT_FALSE(document.HasParseError()) << filename; |
| |
| // Test iterative parsing. |
| document.Parse<kParseIterativeFlag>(json); |
| EXPECT_FALSE(document.HasParseError()) << filename; |
| |
| // Test iterative pull-parsing. |
| Reader reader; |
| StringStream ss(json); |
| NoOpHandler h; |
| reader.IterativeParseInit(); |
| while (!reader.IterativeParseComplete()) { |
| if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h)) |
| break; |
| } |
| EXPECT_FALSE(reader.HasParseError()) << filename; |
| |
| free(json); |
| } |
| } |