// 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(ftell(fp)); fseek(fp, 0, SEEK_SET); char* json = static_cast(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, 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(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(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, 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(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(ss, h)) break; } EXPECT_FALSE(reader.HasParseError()) << filename; free(json); } }