ES-DE/external/rapidjson/test/unittest/schematest.cpp

3576 lines
147 KiB
C++
Raw Normal View History

// 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.
//
// 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.
#define RAPIDJSON_SCHEMA_VERBOSE 0
#define RAPIDJSON_HAS_STDSTRING 1
#include "unittest.h"
#include "rapidjson/schema.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "rapidjson/error/error.h"
#include "rapidjson/error/en.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(variadic-macros)
#elif defined(_MSC_VER)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4822) // local class member function does not have a body
#endif
using namespace rapidjson;
#define TEST_HASHER(json1, json2, expected) \
{\
Document d1, d2;\
d1.Parse(json1);\
ASSERT_FALSE(d1.HasParseError());\
d2.Parse(json2);\
ASSERT_FALSE(d2.HasParseError());\
internal::Hasher<Value, CrtAllocator> h1, h2;\
d1.Accept(h1);\
d2.Accept(h2);\
ASSERT_TRUE(h1.IsValid());\
ASSERT_TRUE(h2.IsValid());\
/*printf("%s: 0x%016llx\n%s: 0x%016llx\n\n", json1, h1.GetHashCode(), json2, h2.GetHashCode());*/\
EXPECT_TRUE(expected == (h1.GetHashCode() == h2.GetHashCode()));\
}
TEST(SchemaValidator, Hasher) {
TEST_HASHER("null", "null", true);
TEST_HASHER("true", "true", true);
TEST_HASHER("false", "false", true);
TEST_HASHER("true", "false", false);
TEST_HASHER("false", "true", false);
TEST_HASHER("true", "null", false);
TEST_HASHER("false", "null", false);
TEST_HASHER("1", "1", true);
TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
TEST_HASHER("-2147483649", "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
TEST_HASHER("2147483648", "2147483648", true); // 2^31 can only be fit in unsigned
TEST_HASHER("4294967296", "4294967296", true); // 2^32 can only be fit in int64_t
TEST_HASHER("9223372036854775808", "9223372036854775808", true); // 2^63 can only be fit in uint64_t
TEST_HASHER("1.5", "1.5", true);
TEST_HASHER("1", "1.0", true);
TEST_HASHER("1", "-1", false);
TEST_HASHER("0.0", "-0.0", false);
TEST_HASHER("1", "true", false);
TEST_HASHER("0", "false", false);
TEST_HASHER("0", "null", false);
TEST_HASHER("\"\"", "\"\"", true);
TEST_HASHER("\"\"", "\"\\u0000\"", false);
TEST_HASHER("\"Hello\"", "\"Hello\"", true);
TEST_HASHER("\"Hello\"", "\"World\"", false);
TEST_HASHER("\"Hello\"", "null", false);
TEST_HASHER("\"Hello\\u0000\"", "\"Hello\"", false);
TEST_HASHER("\"\"", "null", false);
TEST_HASHER("\"\"", "true", false);
TEST_HASHER("\"\"", "false", false);
TEST_HASHER("[]", "[ ]", true);
TEST_HASHER("[1, true, false]", "[1, true, false]", true);
TEST_HASHER("[1, true, false]", "[1, true]", false);
TEST_HASHER("[1, 2]", "[2, 1]", false);
TEST_HASHER("[[1], 2]", "[[1, 2]]", false);
TEST_HASHER("[1, 2]", "[1, [2]]", false);
TEST_HASHER("[]", "null", false);
TEST_HASHER("[]", "true", false);
TEST_HASHER("[]", "false", false);
TEST_HASHER("[]", "0", false);
TEST_HASHER("[]", "0.0", false);
TEST_HASHER("[]", "\"\"", false);
TEST_HASHER("{}", "{ }", true);
TEST_HASHER("{\"a\":1}", "{\"a\":1}", true);
TEST_HASHER("{\"a\":1}", "{\"b\":1}", false);
TEST_HASHER("{\"a\":1}", "{\"a\":2}", false);
TEST_HASHER("{\"a\":1, \"b\":2}", "{\"b\":2, \"a\":1}", true); // Member order insensitive
TEST_HASHER("{}", "null", false);
TEST_HASHER("{}", "false", false);
TEST_HASHER("{}", "true", false);
TEST_HASHER("{}", "0", false);
TEST_HASHER("{}", "0.0", false);
TEST_HASHER("{}", "\"\"", false);
}
// Test cases following http://spacetelescope.github.io/understanding-json-schema
#define VALIDATE(schema, json, expected) \
{\
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
VALIDATE_(schema, json, expected, true) \
}
#define VALIDATE_(schema, json, expected, expected2) \
{\
EXPECT_TRUE(expected2 == schema.GetError().ObjectEmpty());\
EXPECT_TRUE(schema.IsSupportedSpecification());\
SchemaValidator validator(schema);\
Document d;\
/*printf("\n%s\n", json);*/\
d.Parse(json);\
EXPECT_FALSE(d.HasParseError());\
EXPECT_TRUE(expected == d.Accept(validator));\
EXPECT_TRUE(expected == validator.IsValid());\
ValidateErrorCode code = validator.GetInvalidSchemaCode();\
if (expected) {\
EXPECT_TRUE(code == kValidateErrorNone);\
EXPECT_TRUE(validator.GetInvalidSchemaKeyword() == 0);\
}\
if ((expected) && !validator.IsValid()) {\
StringBuffer sb;\
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);\
printf("Invalid schema: %s\n", sb.GetString());\
printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());\
printf("Invalid code: %d\n", code);\
printf("Invalid message: %s\n", GetValidateError_En(code));\
sb.Clear();\
validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);\
printf("Invalid document: %s\n", sb.GetString());\
sb.Clear();\
Writer<StringBuffer> w(sb);\
validator.GetError().Accept(w);\
printf("Validation error: %s\n", sb.GetString());\
}\
}
#define INVALIDATE(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error) \
{\
INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, kValidateDefaultFlags, SchemaValidator, Pointer) \
}
#define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
flags, SchemaValidatorType, PointerType) \
{\
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
EXPECT_TRUE(schema.GetError().ObjectEmpty());\
EXPECT_TRUE(schema.IsSupportedSpecification());\
SchemaValidatorType validator(schema);\
validator.SetValidateFlags(flags);\
Document d;\
/*printf("\n%s\n", json);*/\
d.Parse(json);\
EXPECT_FALSE(d.HasParseError());\
d.Accept(validator);\
EXPECT_FALSE(validator.IsValid());\
ValidateErrorCode code = validator.GetInvalidSchemaCode();\
ASSERT_TRUE(code != kValidateErrorNone);\
ASSERT_TRUE(strcmp(GetValidateError_En(code), "Unknown error.") != 0);\
if (validator.GetInvalidSchemaPointer() != PointerType(invalidSchemaPointer)) {\
StringBuffer sb;\
validator.GetInvalidSchemaPointer().Stringify(sb);\
printf("GetInvalidSchemaPointer() Expected: %s Actual: %s\n", invalidSchemaPointer, sb.GetString());\
ADD_FAILURE();\
}\
ASSERT_TRUE(validator.GetInvalidSchemaKeyword() != 0);\
if (strcmp(validator.GetInvalidSchemaKeyword(), invalidSchemaKeyword) != 0) {\
printf("GetInvalidSchemaKeyword() Expected: %s Actual %s\n", invalidSchemaKeyword, validator.GetInvalidSchemaKeyword());\
ADD_FAILURE();\
}\
if (validator.GetInvalidDocumentPointer() != PointerType(invalidDocumentPointer)) {\
StringBuffer sb;\
validator.GetInvalidDocumentPointer().Stringify(sb);\
printf("GetInvalidDocumentPointer() Expected: %s Actual: %s\n", invalidDocumentPointer, sb.GetString());\
ADD_FAILURE();\
}\
Document e;\
e.Parse(error);\
if (validator.GetError() != e) {\
StringBuffer sb;\
Writer<StringBuffer> w(sb);\
validator.GetError().Accept(w);\
printf("GetError() Expected: %s Actual: %s\n", error, sb.GetString());\
ADD_FAILURE();\
}\
}
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
// Use for checking whether a compiled schema document contains errors
#define SCHEMAERROR(schema, error) \
{\
Document e;\
e.Parse(error);\
if (schema.GetError() != e) {\
StringBuffer sb;\
Writer<StringBuffer> w(sb);\
schema.GetError().Accept(w);\
printf("GetError() Expected: %s Actual: %s\n", error, sb.GetString());\
ADD_FAILURE();\
}\
}
TEST(SchemaValidator, Typeless) {
Document sd;
sd.Parse("{}");
SchemaDocument s(sd);
VALIDATE(s, "42", true);
VALIDATE(s, "\"I'm a string\"", true);
VALIDATE(s, "{ \"an\": [ \"arbitrarily\", \"nested\" ], \"data\": \"structure\" }", true);
}
TEST(SchemaValidator, MultiType) {
Document sd;
sd.Parse("{ \"type\": [\"number\", \"string\"] }");
SchemaDocument s(sd);
VALIDATE(s, "42", true);
VALIDATE(s, "\"Life, the universe, and everything\"", true);
INVALIDATE(s, "[\"Life\", \"the universe\", \"and everything\"]", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\", \"number\"], \"actual\": \"array\""
"}}");
}
TEST(SchemaValidator, Enum_Typed) {
Document sd;
sd.Parse("{ \"type\": \"string\", \"enum\" : [\"red\", \"amber\", \"green\"] }");
SchemaDocument s(sd);
VALIDATE(s, "\"red\"", true);
INVALIDATE(s, "\"blue\"", "", "enum", "",
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
TEST(SchemaValidator, Enum_Typeless) {
Document sd;
sd.Parse("{ \"enum\": [\"red\", \"amber\", \"green\", null, 42] }");
SchemaDocument s(sd);
VALIDATE(s, "\"red\"", true);
VALIDATE(s, "null", true);
VALIDATE(s, "42", true);
INVALIDATE(s, "0", "", "enum", "",
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
TEST(SchemaValidator, Enum_InvalidType) {
Document sd;
sd.Parse("{ \"type\": \"string\", \"enum\": [\"red\", \"amber\", \"green\", null] }");
SchemaDocument s(sd);
VALIDATE(s, "\"red\"", true);
INVALIDATE(s, "null", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"null\""
"}}");
}
TEST(SchemaValidator, AllOf) {
{
Document sd;
sd.Parse("{\"allOf\": [{ \"type\": \"string\" }, { \"type\": \"string\", \"maxLength\": 5 }]}");
SchemaDocument s(sd);
VALIDATE(s, "\"ok\"", true);
INVALIDATE(s, "\"too long\"", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" {},"
" {\"maxLength\": {\"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\", \"expected\": 5, \"actual\": \"too long\"}}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
}
{
Document sd;
sd.Parse("{\"allOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" } ] }");
SchemaDocument s(sd);
VALIDATE(s, "\"No way\"", false);
INVALIDATE(s, "-1", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" {\"type\": { \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\", \"errorCode\": 20, \"expected\": [\"string\"], \"actual\": \"integer\"}},"
" {}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
}
}
TEST(SchemaValidator, AnyOf) {
Document sd;
sd.Parse("{\"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" } ] }");
SchemaDocument s(sd);
VALIDATE(s, "\"Yes\"", true);
VALIDATE(s, "42", true);
INVALIDATE(s, "{ \"Not a\": \"string or number\" }", "", "anyOf", "",
"{ \"anyOf\": {"
" \"errorCode\": 24,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\", "
" \"errors\": ["
" { \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/0\","
" \"expected\": [\"string\"], \"actual\": \"object\""
" }},"
" { \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/1\","
" \"expected\": [\"number\"], \"actual\": \"object\""
" }}"
" ]"
"}}");
}
TEST(SchemaValidator, OneOf) {
Document sd;
sd.Parse("{\"oneOf\": [{ \"type\": \"number\", \"multipleOf\": 5 }, { \"type\": \"number\", \"multipleOf\": 3 } ] }");
SchemaDocument s(sd);
VALIDATE(s, "10", true);
VALIDATE(s, "9", true);
INVALIDATE(s, "2", "", "oneOf", "",
"{ \"oneOf\": {"
" \"errorCode\": 21,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"errors\": ["
" { \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/0\","
" \"expected\": 5, \"actual\": 2"
" }},"
" { \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/oneOf/1\","
" \"expected\": 3, \"actual\": 2"
" }}"
" ]"
"}}");
INVALIDATE(s, "15", "", "oneOf", "",
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
"{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"matches\": [0,1]}}");
}
TEST(SchemaValidator, Not) {
Document sd;
sd.Parse("{\"not\":{ \"type\": \"string\"}}");
SchemaDocument s(sd);
VALIDATE(s, "42", true);
VALIDATE(s, "{ \"key\": \"value\" }", true);
INVALIDATE(s, "\"I am a string\"", "", "not", "",
"{ \"not\": { \"errorCode\": 25, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
}
TEST(SchemaValidator, Ref) {
Document sd;
sd.Parse(
"{"
" \"$schema\": \"http://json-schema.org/draft-04/schema#\","
""
" \"definitions\": {"
" \"address\": {"
" \"type\": \"object\","
" \"properties\": {"
" \"street_address\": { \"type\": \"string\" },"
" \"city\": { \"type\": \"string\" },"
" \"state\": { \"type\": \"string\" }"
" },"
" \"required\": [\"street_address\", \"city\", \"state\"]"
" }"
" },"
" \"type\": \"object\","
" \"properties\": {"
" \"billing_address\": { \"$ref\": \"#/definitions/address\" },"
" \"shipping_address\": { \"$ref\": \"#/definitions/address\" }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\"}, \"billing_address\": {\"street_address\": \"1st Street SE\", \"city\": \"Washington\", \"state\": \"DC\"} }", true);
}
TEST(SchemaValidator, Ref_AllOf) {
Document sd;
sd.Parse(
"{"
" \"$schema\": \"http://json-schema.org/draft-04/schema#\","
""
" \"definitions\": {"
" \"address\": {"
" \"type\": \"object\","
" \"properties\": {"
" \"street_address\": { \"type\": \"string\" },"
" \"city\": { \"type\": \"string\" },"
" \"state\": { \"type\": \"string\" }"
" },"
" \"required\": [\"street_address\", \"city\", \"state\"]"
" }"
" },"
" \"type\": \"object\","
" \"properties\": {"
" \"billing_address\": { \"$ref\": \"#/definitions/address\" },"
" \"shipping_address\": {"
" \"allOf\": ["
" { \"$ref\": \"#/definitions/address\" },"
" { \"properties\":"
" { \"type\": { \"enum\": [ \"residential\", \"business\" ] } },"
" \"required\": [\"type\"]"
" }"
" ]"
" }"
" }"
"}");
SchemaDocument s(sd);
INVALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\"} }", "/properties/shipping_address", "allOf", "/shipping_address",
"{ \"allOf\": {"
" \"errors\": ["
" {},"
" {\"required\": {\"errorCode\": 15, \"instanceRef\": \"#/shipping_address\", \"schemaRef\": \"#/properties/shipping_address/allOf/1\", \"missing\": [\"type\"]}}"
" ],"
" \"errorCode\":23,\"instanceRef\":\"#/shipping_address\",\"schemaRef\":\"#/properties/shipping_address\""
"}}");
VALIDATE(s, "{\"shipping_address\": {\"street_address\": \"1600 Pennsylvania Avenue NW\", \"city\": \"Washington\", \"state\": \"DC\", \"type\": \"business\"} }", true);
}
TEST(SchemaValidator, String) {
Document sd;
sd.Parse("{\"type\":\"string\"}");
SchemaDocument s(sd);
VALIDATE(s, "\"I'm a string\"", true);
INVALIDATE(s, "42", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}");
INVALIDATE(s, "2147483648", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}"); // 2^31 can only be fit in unsigned
INVALIDATE(s, "-2147483649", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}"); // -2^31 - 1 can only be fit in int64_t
INVALIDATE(s, "4294967296", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}"); // 2^32 can only be fit in int64_t
INVALIDATE(s, "3.1415926", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"number\""
"}}");
}
TEST(SchemaValidator, String_LengthRange) {
Document sd;
sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}");
SchemaDocument s(sd);
INVALIDATE(s, "\"A\"", "", "minLength", "",
"{ \"minLength\": {"
" \"errorCode\": 7,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": \"A\""
"}}");
VALIDATE(s, "\"AB\"", true);
VALIDATE(s, "\"ABC\"", true);
INVALIDATE(s, "\"ABCD\"", "", "maxLength", "",
"{ \"maxLength\": {"
" \"errorCode\": 6,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": \"ABCD\""
"}}");
}
#if RAPIDJSON_SCHEMA_HAS_REGEX
TEST(SchemaValidator, String_Pattern) {
Document sd;
sd.Parse("{\"type\":\"string\",\"pattern\":\"^(\\\\([0-9]{3}\\\\))?[0-9]{3}-[0-9]{4}$\"}");
SchemaDocument s(sd);
VALIDATE(s, "\"555-1212\"", true);
VALIDATE(s, "\"(888)555-1212\"", true);
INVALIDATE(s, "\"(888)555-1212 ext. 532\"", "", "pattern", "",
"{ \"pattern\": {"
" \"errorCode\": 8,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"actual\": \"(888)555-1212 ext. 532\""
"}}");
INVALIDATE(s, "\"(800)FLOWERS\"", "", "pattern", "",
"{ \"pattern\": {"
" \"errorCode\": 8,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"actual\": \"(800)FLOWERS\""
"}}");
}
TEST(SchemaValidator, String_Pattern_Invalid) {
Document sd;
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}");
SchemaDocument s(sd);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
SCHEMAERROR(s, "{\"RegexInvalid\":{\"errorCode\":9,\"instanceRef\":\"#/pattern\",\"value\":\"a{0}\"}}");
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
VALIDATE_(s, "\"\"", true, false);
VALIDATE_(s, "\"a\"", true, false);
VALIDATE_(s, "\"aa\"", true, false);
}
#endif
TEST(SchemaValidator, Integer) {
Document sd;
sd.Parse("{\"type\":\"integer\"}");
SchemaDocument s(sd);
VALIDATE(s, "42", true);
VALIDATE(s, "-1", true);
VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
VALIDATE(s, "-2147483649", true); // -2^31 - 1 can only be fit in int64_t
VALIDATE(s, "2147483648", true); // 2^31 can only be fit in unsigned
VALIDATE(s, "4294967296", true); // 2^32 can only be fit in int64_t
INVALIDATE(s, "3.1415926", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"integer\"], \"actual\": \"number\""
"}}");
INVALIDATE(s, "\"42\"", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"integer\"], \"actual\": \"string\""
"}}");
}
TEST(SchemaValidator, Integer_Range) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"minimum\":0,\"maximum\":100,\"exclusiveMaximum\":true}");
SchemaDocument s(sd);
INVALIDATE(s, "-1", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0, \"actual\": -1"
"}}");
VALIDATE(s, "0", true);
VALIDATE(s, "10", true);
VALIDATE(s, "99", true);
INVALIDATE(s, "100", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100"
"}}");
INVALIDATE(s, "101", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 101"
"}}");
}
TEST(SchemaValidator, Integer_Range64Boundary) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775807,\"maximum\":9223372036854775806}");
SchemaDocument s(sd);
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -9223372036854775807, \"actual\": -9223372036854775808"
"}}");
VALIDATE(s, "-9223372036854775807", true);
VALIDATE(s, "-2147483648", true); // int min
VALIDATE(s, "0", true);
VALIDATE(s, "2147483647", true); // int max
VALIDATE(s, "2147483648", true); // unsigned first
VALIDATE(s, "4294967295", true); // unsigned max
VALIDATE(s, "9223372036854775806", true);
INVALIDATE(s, "9223372036854775807", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775806, \"actual\": 9223372036854775807"
"}}");
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775806, \"actual\": 18446744073709551615"
"}}"); // uint64_t max
}
TEST(SchemaValidator, Integer_RangeU64Boundary) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"minimum\":9223372036854775808,\"maximum\":18446744073709551614}");
SchemaDocument s(sd);
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": -9223372036854775808"
"}}");
INVALIDATE(s, "9223372036854775807", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": 9223372036854775807"
"}}");
INVALIDATE(s, "-2147483648", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": -2147483648"
"}}"); // int min
INVALIDATE(s, "0", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": 0"
"}}");
INVALIDATE(s, "2147483647", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": 2147483647"
"}}"); // int max
INVALIDATE(s, "2147483648", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": 2147483648"
"}}"); // unsigned first
INVALIDATE(s, "4294967295", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808, \"actual\": 4294967295"
"}}"); // unsigned max
VALIDATE(s, "9223372036854775808", true);
VALIDATE(s, "18446744073709551614", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551614, \"actual\": 18446744073709551615"
"}}");
}
TEST(SchemaValidator, Integer_Range64BoundaryExclusive) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"minimum\":-9223372036854775808,\"maximum\":18446744073709551615,\"exclusiveMinimum\":true,\"exclusiveMaximum\":true}");
SchemaDocument s(sd);
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 5,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -9223372036854775808, \"exclusiveMinimum\": true, "
" \"actual\": -9223372036854775808"
"}}");
VALIDATE(s, "-9223372036854775807", true);
VALIDATE(s, "18446744073709551614", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551615, \"exclusiveMaximum\": true, "
" \"actual\": 18446744073709551615"
"}}");
}
TEST(SchemaValidator, Integer_MultipleOf) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"multipleOf\":10}");
SchemaDocument s(sd);
VALIDATE(s, "0", true);
VALIDATE(s, "10", true);
VALIDATE(s, "-10", true);
VALIDATE(s, "20", true);
INVALIDATE(s, "23", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10, \"actual\": 23"
"}}");
INVALIDATE(s, "-23", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10, \"actual\": -23"
"}}");
}
TEST(SchemaValidator, Integer_MultipleOf64Boundary) {
Document sd;
sd.Parse("{\"type\":\"integer\",\"multipleOf\":18446744073709551615}");
SchemaDocument s(sd);
VALIDATE(s, "0", true);
VALIDATE(s, "18446744073709551615", true);
INVALIDATE(s, "18446744073709551614", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709551615, \"actual\": 18446744073709551614"
"}}");
}
TEST(SchemaValidator, Number_Range) {
Document sd;
sd.Parse("{\"type\":\"number\",\"minimum\":0,\"maximum\":100,\"exclusiveMaximum\":true}");
SchemaDocument s(sd);
INVALIDATE(s, "-1", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0, \"actual\": -1"
"}}");
VALIDATE(s, "0", true);
VALIDATE(s, "0.1", true);
VALIDATE(s, "10", true);
VALIDATE(s, "99", true);
VALIDATE(s, "99.9", true);
INVALIDATE(s, "100", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100"
"}}");
INVALIDATE(s, "100.0", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 100.0"
"}}");
INVALIDATE(s, "101.5", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100, \"exclusiveMaximum\": true, \"actual\": 101.5"
"}}");
}
TEST(SchemaValidator, Number_RangeInt) {
Document sd;
sd.Parse("{\"type\":\"number\",\"minimum\":-100,\"maximum\":-1,\"exclusiveMaximum\":true}");
SchemaDocument s(sd);
INVALIDATE(s, "-101", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -100, \"actual\": -101"
"}}");
INVALIDATE(s, "-100.1", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -100, \"actual\": -100.1"
"}}");
VALIDATE(s, "-100", true);
VALIDATE(s, "-2", true);
INVALIDATE(s, "-1", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -1"
"}}");
INVALIDATE(s, "-0.9", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": -0.9"
"}}");
INVALIDATE(s, "0", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 0"
"}}");
INVALIDATE(s, "2147483647", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483647"
"}}"); // int max
INVALIDATE(s, "2147483648", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 2147483648"
"}}"); // unsigned first
INVALIDATE(s, "4294967295", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 4294967295"
"}}"); // unsigned max
INVALIDATE(s, "9223372036854775808", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808"
"}}");
INVALIDATE(s, "18446744073709551614", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
"}}");
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": -1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615"
"}}");
}
TEST(SchemaValidator, Number_RangeDouble) {
Document sd;
sd.Parse("{\"type\":\"number\",\"minimum\":0.1,\"maximum\":100.1,\"exclusiveMaximum\":true}");
SchemaDocument s(sd);
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0.1, \"actual\": -9223372036854775808"
"}}");
INVALIDATE(s, "-2147483648", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0.1, \"actual\": -2147483648"
"}}"); // int min
INVALIDATE(s, "-1", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 0.1, \"actual\": -1"
"}}");
VALIDATE(s, "0.1", true);
VALIDATE(s, "10", true);
VALIDATE(s, "99", true);
VALIDATE(s, "100", true);
INVALIDATE(s, "101", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101"
"}}");
INVALIDATE(s, "101.5", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 101.5"
"}}");
INVALIDATE(s, "18446744073709551614", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
"}}");
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615"
"}}");
INVALIDATE(s, "2147483647", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483647"
"}}"); // int max
INVALIDATE(s, "2147483648", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 2147483648"
"}}"); // unsigned first
INVALIDATE(s, "4294967295", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 4294967295"
"}}"); // unsigned max
INVALIDATE(s, "9223372036854775808", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 9223372036854775808"
"}}");
INVALIDATE(s, "18446744073709551614", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551614"
"}}");
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 3,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 100.1, \"exclusiveMaximum\": true, \"actual\": 18446744073709551615"
"}}");
}
TEST(SchemaValidator, Number_RangeDoubleU64Boundary) {
Document sd;
sd.Parse("{\"type\":\"number\",\"minimum\":9223372036854775808.0,\"maximum\":18446744073709550000.0}");
SchemaDocument s(sd);
INVALIDATE(s, "-9223372036854775808", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": -9223372036854775808"
"}}");
INVALIDATE(s, "-2147483648", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": -2147483648"
"}}"); // int min
INVALIDATE(s, "0", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": 0"
"}}");
INVALIDATE(s, "2147483647", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": 2147483647"
"}}"); // int max
INVALIDATE(s, "2147483648", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": 2147483648"
"}}"); // unsigned first
INVALIDATE(s, "4294967295", "", "minimum", "",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 9223372036854775808.0, \"actual\": 4294967295"
"}}"); // unsigned max
VALIDATE(s, "9223372036854775808", true);
VALIDATE(s, "18446744073709540000", true);
INVALIDATE(s, "18446744073709551615", "", "maximum", "",
"{ \"maximum\": {"
" \"errorCode\": 2,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 18446744073709550000.0, \"actual\": 18446744073709551615"
"}}");
}
TEST(SchemaValidator, Number_MultipleOf) {
Document sd;
sd.Parse("{\"type\":\"number\",\"multipleOf\":10.0}");
SchemaDocument s(sd);
VALIDATE(s, "0", true);
VALIDATE(s, "10", true);
VALIDATE(s, "-10", true);
VALIDATE(s, "20", true);
INVALIDATE(s, "23", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10.0, \"actual\": 23"
"}}");
INVALIDATE(s, "-2147483648", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10.0, \"actual\": -2147483648"
"}}"); // int min
VALIDATE(s, "-2147483640", true);
INVALIDATE(s, "2147483647", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10.0, \"actual\": 2147483647"
"}}"); // int max
INVALIDATE(s, "2147483648", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10.0, \"actual\": 2147483648"
"}}"); // unsigned first
VALIDATE(s, "2147483650", true);
INVALIDATE(s, "4294967295", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 10.0, \"actual\": 4294967295"
"}}"); // unsigned max
VALIDATE(s, "4294967300", true);
}
TEST(SchemaValidator, Number_MultipleOfOne) {
Document sd;
sd.Parse("{\"type\":\"number\",\"multipleOf\":1}");
SchemaDocument s(sd);
VALIDATE(s, "42", true);
VALIDATE(s, "42.0", true);
INVALIDATE(s, "3.1415926", "", "multipleOf", "",
"{ \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 1, \"actual\": 3.1415926"
"}}");
}
TEST(SchemaValidator, Object) {
Document sd;
sd.Parse("{\"type\":\"object\"}");
SchemaDocument s(sd);
VALIDATE(s, "{\"key\":\"value\",\"another_key\":\"another_value\"}", true);
VALIDATE(s, "{\"Sun\":1.9891e30,\"Jupiter\":1.8986e27,\"Saturn\":5.6846e26,\"Neptune\":10.243e25,\"Uranus\":8.6810e25,\"Earth\":5.9736e24,\"Venus\":4.8685e24,\"Mars\":6.4185e23,\"Mercury\":3.3022e23,\"Moon\":7.349e22,\"Pluto\":1.25e22}", true);
INVALIDATE(s, "[\"An\", \"array\", \"not\", \"an\", \"object\"]", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"object\"], \"actual\": \"array\""
"}}");
INVALIDATE(s, "\"Not an object\"", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"object\"], \"actual\": \"string\""
"}}");
}
TEST(SchemaValidator, Object_Properties) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"number\": { \"type\": \"number\" },"
" \"street_name\" : { \"type\": \"string\" },"
" \"street_type\" : { \"type\": \"string\", \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"] }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true);
INVALIDATE(s, "{ \"number\": \"1600\", \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", "/properties/number", "type", "/number",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/number\", \"schemaRef\": \"#/properties/number\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}");
INVALIDATE(s, "{ \"number\": \"One\", \"street_name\": \"Microsoft\", \"street_type\": \"Way\" }",
"/properties/number", "type", "/number",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/number\", \"schemaRef\": \"#/properties/number\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}"); // fail fast
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\" }", true);
VALIDATE(s, "{}", true);
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", true);
}
TEST(SchemaValidator, Object_AdditionalPropertiesBoolean) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"number\": { \"type\": \"number\" },"
" \"street_name\" : { \"type\": \"string\" },"
" \"street_type\" : { \"type\": \"string\","
" \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"]"
" }"
" },"
" \"additionalProperties\": false"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true);
INVALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", "", "additionalProperties", "/direction",
"{ \"additionalProperties\": {"
" \"errorCode\": 16,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"disallowed\": \"direction\""
"}}");
}
TEST(SchemaValidator, Object_AdditionalPropertiesObject) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"number\": { \"type\": \"number\" },"
" \"street_name\" : { \"type\": \"string\" },"
" \"street_type\" : { \"type\": \"string\","
" \"enum\" : [\"Street\", \"Avenue\", \"Boulevard\"]"
" }"
" },"
" \"additionalProperties\": { \"type\": \"string\" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\" }", true);
VALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"direction\": \"NW\" }", true);
INVALIDATE(s, "{ \"number\": 1600, \"street_name\": \"Pennsylvania\", \"street_type\": \"Avenue\", \"office_number\": 201 }", "/additionalProperties", "type", "/office_number",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/office_number\", \"schemaRef\": \"#/additionalProperties\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}");
}
TEST(SchemaValidator, Object_Required) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"name\": { \"type\": \"string\" },"
" \"email\" : { \"type\": \"string\" },"
" \"address\" : { \"type\": \"string\" },"
" \"telephone\" : { \"type\": \"string\" }"
" },"
" \"required\":[\"name\", \"email\"]"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"name\": \"William Shakespeare\", \"email\" : \"bill@stratford-upon-avon.co.uk\" }", true);
VALIDATE(s, "{ \"name\": \"William Shakespeare\", \"email\" : \"bill@stratford-upon-avon.co.uk\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\", \"authorship\" : \"in question\"}", true);
INVALIDATE(s, "{ \"name\": \"William Shakespeare\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\" }", "", "required", "",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"email\"]"
"}}");
INVALIDATE(s, "{}", "", "required", "",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"name\", \"email\"]"
"}}");
}
TEST(SchemaValidator, Object_Required_PassWithDefault) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"name\": { \"type\": \"string\", \"default\": \"William Shakespeare\" },"
" \"email\" : { \"type\": \"string\", \"default\": \"\" },"
" \"address\" : { \"type\": \"string\" },"
" \"telephone\" : { \"type\": \"string\" }"
" },"
" \"required\":[\"name\", \"email\"]"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"email\" : \"bill@stratford-upon-avon.co.uk\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\", \"authorship\" : \"in question\"}", true);
INVALIDATE(s, "{ \"name\": \"William Shakespeare\", \"address\" : \"Henley Street, Stratford-upon-Avon, Warwickshire, England\" }", "", "required", "",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"email\"]"
"}}");
INVALIDATE(s, "{}", "", "required", "",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"email\"]"
"}}");
}
TEST(SchemaValidator, Object_PropertiesRange) {
Document sd;
sd.Parse("{\"type\":\"object\", \"minProperties\":2, \"maxProperties\":3}");
SchemaDocument s(sd);
INVALIDATE(s, "{}", "", "minProperties", "",
"{ \"minProperties\": {"
" \"errorCode\": 14,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": 0"
"}}");
INVALIDATE(s, "{\"a\":0}", "", "minProperties", "",
"{ \"minProperties\": {"
" \"errorCode\": 14,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": 1"
"}}");
VALIDATE(s, "{\"a\":0,\"b\":1}", true);
VALIDATE(s, "{\"a\":0,\"b\":1,\"c\":2}", true);
INVALIDATE(s, "{\"a\":0,\"b\":1,\"c\":2,\"d\":3}", "", "maxProperties", "",
"{ \"maxProperties\": {"
" \"errorCode\": 13,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\", "
" \"expected\": 3, \"actual\": 4"
"}}");
}
TEST(SchemaValidator, Object_PropertyDependencies) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"name\": { \"type\": \"string\" },"
" \"credit_card\": { \"type\": \"number\" },"
" \"cvv_code\": { \"type\": \"number\" },"
" \"billing_address\": { \"type\": \"string\" }"
" },"
" \"required\": [\"name\"],"
" \"dependencies\": {"
" \"credit_card\": [\"cvv_code\", \"billing_address\"]"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"name\": \"John Doe\", \"credit_card\": 5555555555555555, \"cvv_code\": 777, "
"\"billing_address\": \"555 Debtor's Lane\" }", true);
INVALIDATE(s, "{ \"name\": \"John Doe\", \"credit_card\": 5555555555555555 }", "", "dependencies", "",
"{ \"dependencies\": {"
" \"errorCode\": 18,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"errors\": {"
" \"credit_card\": {"
" \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/credit_card\","
" \"missing\": [\"cvv_code\", \"billing_address\"]"
" } } }"
"}}");
VALIDATE(s, "{ \"name\": \"John Doe\"}", true);
VALIDATE(s, "{ \"name\": \"John Doe\", \"cvv_code\": 777, \"billing_address\": \"555 Debtor's Lane\" }", true);
}
TEST(SchemaValidator, Object_SchemaDependencies) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\" : {"
" \"name\": { \"type\": \"string\" },"
" \"credit_card\" : { \"type\": \"number\" }"
" },"
" \"required\" : [\"name\"],"
" \"dependencies\" : {"
" \"credit_card\": {"
" \"properties\": {"
" \"billing_address\": { \"type\": \"string\" }"
" },"
" \"required\" : [\"billing_address\"]"
" }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{\"name\": \"John Doe\", \"credit_card\" : 5555555555555555,\"billing_address\" : \"555 Debtor's Lane\"}", true);
INVALIDATE(s, "{\"name\": \"John Doe\", \"credit_card\" : 5555555555555555 }", "", "dependencies", "",
"{ \"dependencies\": {"
" \"errorCode\": 18,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"errors\": {"
" \"credit_card\": {"
" \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/credit_card\","
" \"missing\": [\"billing_address\"]"
" } } }"
"}}");
VALIDATE(s, "{\"name\": \"John Doe\", \"billing_address\" : \"555 Debtor's Lane\"}", true);
}
#if RAPIDJSON_SCHEMA_HAS_REGEX
TEST(SchemaValidator, Object_PatternProperties) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"patternProperties\": {"
" \"^S_\": { \"type\": \"string\" },"
" \"^I_\": { \"type\": \"integer\" }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"S_25\": \"This is a string\" }", true);
VALIDATE(s, "{ \"I_0\": 42 }", true);
INVALIDATE(s, "{ \"S_0\": 42 }", "", "patternProperties", "/S_0",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/S_0\", \"schemaRef\": \"#/patternProperties/%5ES_\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}");
INVALIDATE(s, "{ \"I_42\": \"This is a string\" }", "", "patternProperties", "/I_42",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\","
" \"expected\": [\"integer\"], \"actual\": \"string\""
"}}");
VALIDATE(s, "{ \"keyword\": \"value\" }", true);
}
TEST(SchemaValidator, Object_PatternProperties_ErrorConflict) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"patternProperties\": {"
" \"^I_\": { \"multipleOf\": 5 },"
" \"30$\": { \"multipleOf\": 6 }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"I_30\": 30 }", true);
INVALIDATE(s, "{ \"I_30\": 7 }", "", "patternProperties", "/I_30",
"{ \"multipleOf\": ["
" {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#/I_30\", \"schemaRef\": \"#/patternProperties/%5EI_\","
" \"expected\": 5, \"actual\": 7"
" }, {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#/I_30\", \"schemaRef\": \"#/patternProperties/30%24\","
" \"expected\": 6, \"actual\": 7"
" }"
"]}");
}
TEST(SchemaValidator, Object_Properties_PatternProperties) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"I_42\": { \"type\": \"integer\", \"minimum\": 73 }"
" },"
" \"patternProperties\": {"
" \"^I_\": { \"type\": \"integer\", \"multipleOf\": 6 }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"I_6\": 6 }", true);
VALIDATE(s, "{ \"I_42\": 78 }", true);
INVALIDATE(s, "{ \"I_42\": 42 }", "", "patternProperties", "/I_42",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\","
" \"expected\": 73, \"actual\": 42"
"}}");
INVALIDATE(s, "{ \"I_42\": 7 }", "", "patternProperties", "/I_42",
"{ \"minimum\": {"
" \"errorCode\": 4,"
" \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/properties/I_42\","
" \"expected\": 73, \"actual\": 7"
" },"
" \"multipleOf\": {"
" \"errorCode\": 1,"
" \"instanceRef\": \"#/I_42\", \"schemaRef\": \"#/patternProperties/%5EI_\","
" \"expected\": 6, \"actual\": 7"
" }"
"}");
}
TEST(SchemaValidator, Object_PatternProperties_AdditionalPropertiesObject) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"builtin\": { \"type\": \"number\" }"
" },"
" \"patternProperties\": {"
" \"^S_\": { \"type\": \"string\" },"
" \"^I_\": { \"type\": \"integer\" }"
" },"
" \"additionalProperties\": { \"type\": \"string\" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"builtin\": 42 }", true);
VALIDATE(s, "{ \"keyword\": \"value\" }", true);
INVALIDATE(s, "{ \"keyword\": 42 }", "/additionalProperties", "type", "/keyword",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/keyword\", \"schemaRef\": \"#/additionalProperties\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}");
}
// Replaces test Issue285 and tests failure as well as success
TEST(SchemaValidator, Object_PatternProperties_AdditionalPropertiesBoolean) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"patternProperties\": {"
" \"^S_\": { \"type\": \"string\" },"
" \"^I_\": { \"type\": \"integer\" }"
" },"
" \"additionalProperties\": false"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"S_25\": \"This is a string\" }", true);
VALIDATE(s, "{ \"I_0\": 42 }", true);
INVALIDATE(s, "{ \"keyword\": \"value\" }", "", "additionalProperties", "/keyword",
"{ \"additionalProperties\": {"
" \"errorCode\": 16,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"disallowed\": \"keyword\""
"}}");
}
#endif
TEST(SchemaValidator, Array) {
Document sd;
sd.Parse("{\"type\":\"array\"}");
SchemaDocument s(sd);
VALIDATE(s, "[1, 2, 3, 4, 5]", true);
VALIDATE(s, "[3, \"different\", { \"types\" : \"of values\" }]", true);
INVALIDATE(s, "{\"Not\": \"an array\"}", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"array\"], \"actual\": \"object\""
"}}");
}
TEST(SchemaValidator, Array_ItemsList) {
Document sd;
sd.Parse(
"{"
" \"type\": \"array\","
" \"items\" : {"
" \"type\": \"number\""
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "[1, 2, 3, 4, 5]", true);
INVALIDATE(s, "[1, 2, \"3\", 4, 5]", "/items", "type", "/2",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}");
VALIDATE(s, "[]", true);
}
TEST(SchemaValidator, Array_ItemsTuple) {
Document sd;
sd.Parse(
"{"
" \"type\": \"array\","
" \"items\": ["
" {"
" \"type\": \"number\""
" },"
" {"
" \"type\": \"string\""
" },"
" {"
" \"type\": \"string\","
" \"enum\": [\"Street\", \"Avenue\", \"Boulevard\"]"
" },"
" {"
" \"type\": \"string\","
" \"enum\": [\"NW\", \"NE\", \"SW\", \"SE\"]"
" }"
" ]"
"}");
SchemaDocument s(sd);
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true);
INVALIDATE(s, "[24, \"Sussex\", \"Drive\"]", "/items/2", "enum", "/2",
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#/2\", \"schemaRef\": \"#/items/2\" }}");
INVALIDATE(s, "[\"Palais de l'Elysee\"]", "/items/0", "type", "/0",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items/0\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}");
INVALIDATE(s, "[\"Twenty-four\", \"Sussex\", \"Drive\"]", "/items/0", "type", "/0",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items/0\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}"); // fail fast
VALIDATE(s, "[10, \"Downing\", \"Street\"]", true);
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", true);
}
TEST(SchemaValidator, Array_AdditionalItems) {
Document sd;
sd.Parse(
"{"
" \"type\": \"array\","
" \"items\": ["
" {"
" \"type\": \"number\""
" },"
" {"
" \"type\": \"string\""
" },"
" {"
" \"type\": \"string\","
" \"enum\": [\"Street\", \"Avenue\", \"Boulevard\"]"
" },"
" {"
" \"type\": \"string\","
" \"enum\": [\"NW\", \"NE\", \"SW\", \"SE\"]"
" }"
" ],"
" \"additionalItems\": false"
"}");
SchemaDocument s(sd);
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\"]", true);
VALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\"]", true);
INVALIDATE(s, "[1600, \"Pennsylvania\", \"Avenue\", \"NW\", \"Washington\"]", "", "additionalItems", "/4",
"{ \"additionalItems\": {"
" \"errorCode\": 12,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"disallowed\": 4"
"}}");
}
TEST(SchemaValidator, Array_ItemsRange) {
Document sd;
sd.Parse("{\"type\": \"array\",\"minItems\": 2,\"maxItems\" : 3}");
SchemaDocument s(sd);
INVALIDATE(s, "[]", "", "minItems", "",
"{ \"minItems\": {"
" \"errorCode\": 10,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": 0"
"}}");
INVALIDATE(s, "[1]", "", "minItems", "",
"{ \"minItems\": {"
" \"errorCode\": 10,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 2, \"actual\": 1"
"}}");
VALIDATE(s, "[1, 2]", true);
VALIDATE(s, "[1, 2, 3]", true);
INVALIDATE(s, "[1, 2, 3, 4]", "", "maxItems", "",
"{ \"maxItems\": {"
" \"errorCode\": 9,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": 4"
"}}");
}
TEST(SchemaValidator, Array_UniqueItems) {
Document sd;
sd.Parse("{\"type\": \"array\", \"uniqueItems\": true}");
SchemaDocument s(sd);
VALIDATE(s, "[1, 2, 3, 4, 5]", true);
INVALIDATE(s, "[1, 2, 3, 3, 4]", "", "uniqueItems", "/3",
"{ \"uniqueItems\": {"
" \"errorCode\": 11,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"duplicates\": [2, 3]"
"}}");
INVALIDATE(s, "[1, 2, 3, 3, 3]", "", "uniqueItems", "/3",
"{ \"uniqueItems\": {"
" \"errorCode\": 11,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"duplicates\": [2, 3]"
"}}"); // fail fast
VALIDATE(s, "[]", true);
}
TEST(SchemaValidator, Boolean) {
Document sd;
sd.Parse("{\"type\":\"boolean\"}");
SchemaDocument s(sd);
VALIDATE(s, "true", true);
VALIDATE(s, "false", true);
INVALIDATE(s, "\"true\"", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"boolean\"], \"actual\": \"string\""
"}}");
INVALIDATE(s, "0", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"boolean\"], \"actual\": \"integer\""
"}}");
}
TEST(SchemaValidator, Null) {
Document sd;
sd.Parse("{\"type\":\"null\"}");
SchemaDocument s(sd);
VALIDATE(s, "null", true);
INVALIDATE(s, "false", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"null\"], \"actual\": \"boolean\""
"}}");
INVALIDATE(s, "0", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"null\"], \"actual\": \"integer\""
"}}");
INVALIDATE(s, "\"\"", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"null\"], \"actual\": \"string\""
"}}");
}
// Additional tests
TEST(SchemaValidator, ObjectInArray) {
Document sd;
sd.Parse("{\"type\":\"array\", \"items\": { \"type\":\"string\" }}");
SchemaDocument s(sd);
VALIDATE(s, "[\"a\"]", true);
INVALIDATE(s, "[1]", "/items", "type", "/0",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items\","
" \"expected\": [\"string\"], \"actual\": \"integer\""
"}}");
INVALIDATE(s, "[{}]", "/items", "type", "/0",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/0\", \"schemaRef\": \"#/items\","
" \"expected\": [\"string\"], \"actual\": \"object\""
"}}");
}
TEST(SchemaValidator, MultiTypeInObject) {
Document sd;
sd.Parse(
"{"
" \"type\":\"object\","
" \"properties\": {"
" \"tel\" : {"
" \"type\":[\"integer\", \"string\"]"
" }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "{ \"tel\": 999 }", true);
VALIDATE(s, "{ \"tel\": \"123-456\" }", true);
INVALIDATE(s, "{ \"tel\": true }", "/properties/tel", "type", "/tel",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/tel\", \"schemaRef\": \"#/properties/tel\","
" \"expected\": [\"string\", \"integer\"], \"actual\": \"boolean\""
"}}");
}
TEST(SchemaValidator, MultiTypeWithObject) {
Document sd;
sd.Parse(
"{"
" \"type\": [\"object\",\"string\"],"
" \"properties\": {"
" \"tel\" : {"
" \"type\": \"integer\""
" }"
" }"
"}");
SchemaDocument s(sd);
VALIDATE(s, "\"Hello\"", true);
VALIDATE(s, "{ \"tel\": 999 }", true);
INVALIDATE(s, "{ \"tel\": \"fail\" }", "/properties/tel", "type", "/tel",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/tel\", \"schemaRef\": \"#/properties/tel\","
" \"expected\": [\"integer\"], \"actual\": \"string\""
"}}");
}
TEST(SchemaValidator, AllOf_Nested) {
Document sd;
sd.Parse(
"{"
" \"allOf\": ["
" { \"type\": \"string\", \"minLength\": 2 },"
" { \"type\": \"string\", \"maxLength\": 5 },"
" { \"allOf\": [ { \"enum\" : [\"ok\", \"okay\", \"OK\", \"o\"] }, { \"enum\" : [\"ok\", \"OK\", \"o\"]} ] }"
" ]"
"}");
SchemaDocument s(sd);
VALIDATE(s, "\"ok\"", true);
VALIDATE(s, "\"OK\"", true);
INVALIDATE(s, "\"okay\"", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" {},{},"
" { \"allOf\": {"
" \"errors\": ["
" {},"
" { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\" }}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\""
" }}],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
INVALIDATE(s, "\"o\"", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" { \"minLength\": {\"actual\": \"o\", \"expected\": 2, \"errorCode\": 7, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\" }},"
" {},{}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
"}}");
INVALIDATE(s, "\"n\"", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" { \"minLength\": {\"actual\": \"n\", \"expected\": 2, \"errorCode\": 7, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\" }},"
" {},"
" { \"allOf\": {"
" \"errors\": ["
" { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}},"
" { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\""
" }}"
" ],"
" \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\""
"}}");
INVALIDATE(s, "\"too long\"", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" {},"
" { \"maxLength\": {\"actual\": \"too long\", \"expected\": 5, \"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\" }},"
" { \"allOf\": {"
" \"errors\": ["
" { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}},"
" { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\""
" }}"
" ],"
" \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\""
"}}");
INVALIDATE(s, "123", "", "allOf", "",
"{ \"allOf\": {"
" \"errors\": ["
" {\"type\": {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/0\"}},"
" {\"type\": {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/1\"}},"
" { \"allOf\": {"
" \"errors\": ["
" { \"enum\": {\"errorCode\": 19 ,\"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/0\"}},"
" { \"enum\": {\"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2/allOf/1\"}}"
" ],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#/allOf/2\""
" }}"
" ],"
" \"errorCode\":23,\"instanceRef\":\"#\",\"schemaRef\":\"#\""
"}}");
}
TEST(SchemaValidator, EscapedPointer) {
Document sd;
sd.Parse(
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"~/\": { \"type\": \"number\" }"
" }"
"}");
SchemaDocument s(sd);
INVALIDATE(s, "{\"~/\":true}", "/properties/~0~1", "type", "/~0~1",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/~0~1\", \"schemaRef\": \"#/properties/~0~1\","
" \"expected\": [\"number\"], \"actual\": \"boolean\""
"}}");
}
TEST(SchemaValidator, SchemaPointer) {
Document sd;
sd.Parse(
"{"
" \"swagger\": \"2.0\","
" \"paths\": {"
" \"/some/path\": {"
" \"post\": {"
" \"parameters\": ["
" {"
" \"in\": \"body\","
" \"name\": \"body\","
" \"schema\": {"
" \"properties\": {"
" \"a\": {"
" \"$ref\": \"#/definitions/Prop_a\""
" },"
" \"b\": {"
" \"type\": \"integer\""
" }"
" },"
" \"type\": \"object\""
" }"
" }"
" ],"
" \"responses\": {"
" \"200\": {"
" \"schema\": {"
" \"$ref\": \"#/definitions/Resp_200\""
" }"
" }"
" }"
" }"
" }"
" },"
" \"definitions\": {"
" \"Prop_a\": {"
" \"properties\": {"
" \"c\": {"
" \"enum\": ["
" \"C1\","
" \"C2\","
" \"C3\""
" ],"
" \"type\": \"string\""
" },"
" \"d\": {"
" \"$ref\": \"#/definitions/Prop_d\""
" },"
" \"s\": {"
" \"type\": \"string\""
" }"
" },"
" \"required\": [\"c\"],"
" \"type\": \"object\""
" },"
" \"Prop_d\": {"
" \"properties\": {"
" \"a\": {"
" \"$ref\": \"#/definitions/Prop_a\""
" },"
" \"c\": {"
" \"$ref\": \"#/definitions/Prop_a/properties/c\""
" }"
" },"
" \"type\": \"object\""
" },"
" \"Resp_200\": {"
" \"properties\": {"
" \"e\": {"
" \"type\": \"string\""
" },"
" \"f\": {"
" \"type\": \"boolean\""
" }"
" },"
" \"type\": \"object\""
" }"
" }"
"}");
SchemaDocument s1(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/parameters/0/schema"));
VALIDATE(s1,
"{"
" \"a\": {"
" \"c\": \"C1\","
" \"d\": {"
" \"a\": {"
" \"c\": \"C2\""
" },"
" \"c\": \"C3\""
" }"
" },"
" \"b\": 123"
"}",
true);
INVALIDATE(s1,
"{"
" \"a\": {"
" \"c\": \"C1\","
" \"d\": {"
" \"a\": {"
" \"c\": \"C2\""
" },"
" \"c\": \"C3\""
" }"
" },"
" \"b\": \"should be an int\""
"}",
"#/paths/~1some~1path/post/parameters/0/schema/properties/b", "type", "#/b",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\":\"#/b\","
" \"schemaRef\":\"#/paths/~1some~1path/post/parameters/0/schema/properties/b\","
" \"expected\": [\"integer\"], \"actual\":\"string\""
"}}");
INVALIDATE(s1,
"{"
" \"a\": {"
" \"c\": \"C1\","
" \"d\": {"
" \"a\": {"
" \"c\": \"should be within enum\""
" },"
" \"c\": \"C3\""
" }"
" },"
" \"b\": 123"
"}",
"#/definitions/Prop_a/properties/c", "enum", "#/a/d/a/c",
"{ \"enum\": {"
" \"errorCode\": 19,"
" \"instanceRef\":\"#/a/d/a/c\","
" \"schemaRef\":\"#/definitions/Prop_a/properties/c\""
"}}");
INVALIDATE(s1,
"{"
" \"a\": {"
" \"c\": \"C1\","
" \"d\": {"
" \"a\": {"
" \"s\": \"required 'c' is missing\""
" }"
" }"
" },"
" \"b\": 123"
"}",
"#/definitions/Prop_a", "required", "#/a/d/a",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"missing\":[\"c\"],"
" \"instanceRef\":\"#/a/d/a\","
" \"schemaRef\":\"#/definitions/Prop_a\""
"}}");
SchemaDocument s2(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/responses/200/schema"));
VALIDATE(s2,
"{ \"e\": \"some string\", \"f\": false }",
true);
INVALIDATE(s2,
"{ \"e\": true, \"f\": false }",
"#/definitions/Resp_200/properties/e", "type", "#/e",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\":\"#/e\","
" \"schemaRef\":\"#/definitions/Resp_200/properties/e\","
" \"expected\": [\"string\"], \"actual\":\"boolean\""
"}}");
INVALIDATE(s2,
"{ \"e\": \"some string\", \"f\": 123 }",
"#/definitions/Resp_200/properties/f", "type", "#/f",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\":\"#/f\","
" \"schemaRef\":\"#/definitions/Resp_200/properties/f\","
" \"expected\": [\"boolean\"], \"actual\":\"integer\""
"}}");
}
template <typename Allocator>
static char* ReadFile(const char* filename, Allocator& allocator) {
const char *paths[] = {
"",
"bin/",
"../bin/",
"../../bin/",
"../../../bin/"
};
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);
size_t length = static_cast<size_t>(ftell(fp));
fseek(fp, 0, SEEK_SET);
char* json = reinterpret_cast<char*>(allocator.Malloc(length + 1));
size_t readLength = fread(json, 1, length, fp);
json[readLength] = '\0';
fclose(fp);
return json;
}
TEST(SchemaValidator, ValidateMetaSchema) {
CrtAllocator allocator;
char* json = ReadFile("draft-04/schema", allocator);
Document d;
d.Parse(json);
ASSERT_FALSE(d.HasParseError());
SchemaDocument sd(d);
SchemaValidator validator(sd);
d.Accept(validator);
if (!validator.IsValid()) {
StringBuffer sb;
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
printf("Invalid schema: %s\n", sb.GetString());
printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
printf("Invalid code: %d\n", validator.GetInvalidSchemaCode());
printf("Invalid message: %s\n", GetValidateError_En(validator.GetInvalidSchemaCode()));
sb.Clear();
validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
printf("Invalid document: %s\n", sb.GetString());
sb.Clear();
Writer<StringBuffer> w(sb);
validator.GetError().Accept(w);
printf("Validation error: %s\n", sb.GetString());
ADD_FAILURE();
}
CrtAllocator::Free(json);
}
TEST(SchemaValidator, ValidateMetaSchema_UTF16) {
typedef GenericDocument<UTF16<> > D;
typedef GenericSchemaDocument<D::ValueType> SD;
typedef GenericSchemaValidator<SD> SV;
CrtAllocator allocator;
char* json = ReadFile("draft-04/schema", allocator);
D d;
StringStream ss(json);
d.ParseStream<0, UTF8<> >(ss);
ASSERT_FALSE(d.HasParseError());
SD sd(d);
SV validator(sd);
d.Accept(validator);
if (!validator.IsValid()) {
GenericStringBuffer<UTF16<> > sb;
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
wprintf(L"Invalid schema: %ls\n", sb.GetString());
wprintf(L"Invalid keyword: %ls\n", validator.GetInvalidSchemaKeyword());
sb.Clear();
validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
wprintf(L"Invalid document: %ls\n", sb.GetString());
sb.Clear();
Writer<GenericStringBuffer<UTF16<> >, UTF16<> > w(sb);
validator.GetError().Accept(w);
printf("Validation error: %ls\n", sb.GetString());
ADD_FAILURE();
}
CrtAllocator::Free(json);
}
template <typename SchemaDocumentType = SchemaDocument>
class RemoteSchemaDocumentProvider : public IGenericRemoteSchemaDocumentProvider<SchemaDocumentType> {
public:
RemoteSchemaDocumentProvider() :
documentAllocator_(documentBuffer_, sizeof(documentBuffer_)),
schemaAllocator_(schemaBuffer_, sizeof(schemaBuffer_))
{
const char* filenames[kCount] = {
"jsonschema/remotes/integer.json",
"jsonschema/remotes/subSchemas.json",
"jsonschema/remotes/folder/folderInteger.json",
"draft-04/schema",
"unittestschema/address.json"
};
const char* uris[kCount] = {
"http://localhost:1234/integer.json",
"http://localhost:1234/subSchemas.json",
"http://localhost:1234/folder/folderInteger.json",
"http://json-schema.org/draft-04/schema",
"http://localhost:1234/address.json"
};
for (size_t i = 0; i < kCount; i++) {
sd_[i] = 0;
char jsonBuffer[8192];
MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
char* json = ReadFile(filenames[i], jsonAllocator);
if (!json) {
printf("json remote file %s not found", filenames[i]);
ADD_FAILURE();
}
else {
char stackBuffer[4096];
MemoryPoolAllocator<> stackAllocator(stackBuffer, sizeof(stackBuffer));
DocumentType d(&documentAllocator_, 1024, &stackAllocator);
d.Parse(json);
sd_[i] = new SchemaDocumentType(d, uris[i], static_cast<SizeType>(strlen(uris[i])), 0, &schemaAllocator_);
MemoryPoolAllocator<>::Free(json);
}
};
}
~RemoteSchemaDocumentProvider() {
for (size_t i = 0; i < kCount; i++)
delete sd_[i];
}
virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) {
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
//printf("GetRemoteDocument : %s\n", uri);
for (size_t i = 0; i < kCount; i++)
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
if (typename SchemaDocumentType::GValue(uri, length) == sd_[i]->GetURI()) {
//printf("Matched document");
return sd_[i];
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
}
//printf("No matched document");
return 0;
}
private:
typedef GenericDocument<typename SchemaDocumentType::EncodingType, MemoryPoolAllocator<>, MemoryPoolAllocator<> > DocumentType;
RemoteSchemaDocumentProvider(const RemoteSchemaDocumentProvider&);
RemoteSchemaDocumentProvider& operator=(const RemoteSchemaDocumentProvider&);
static const size_t kCount = 5;
SchemaDocumentType* sd_[kCount];
typename DocumentType::AllocatorType documentAllocator_;
typename SchemaDocumentType::AllocatorType schemaAllocator_;
char documentBuffer_[16384];
char schemaBuffer_[128u * 1024];
};
TEST(SchemaValidator, TestSuite) {
const char* filenames[] = {
"additionalItems.json",
"additionalProperties.json",
"allOf.json",
"anyOf.json",
"default.json",
"definitions.json",
"dependencies.json",
"enum.json",
"items.json",
"maximum.json",
"maxItems.json",
"maxLength.json",
"maxProperties.json",
"minimum.json",
"minItems.json",
"minLength.json",
"minProperties.json",
"multipleOf.json",
"not.json",
"oneOf.json",
"pattern.json",
"patternProperties.json",
"properties.json",
"ref.json",
"refRemote.json",
"required.json",
"type.json",
"uniqueItems.json"
};
const char* onlyRunDescription = 0;
//const char* onlyRunDescription = "a string is a string";
unsigned testCount = 0;
unsigned passCount = 0;
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
char jsonBuffer[65536];
char documentBuffer[65536];
char documentStackBuffer[65536];
char schemaBuffer[65536];
char validatorBuffer[65536];
MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
MemoryPoolAllocator<> documentAllocator(documentBuffer, sizeof(documentBuffer));
MemoryPoolAllocator<> documentStackAllocator(documentStackBuffer, sizeof(documentStackBuffer));
MemoryPoolAllocator<> schemaAllocator(schemaBuffer, sizeof(schemaBuffer));
MemoryPoolAllocator<> validatorAllocator(validatorBuffer, sizeof(validatorBuffer));
for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) {
char filename[FILENAME_MAX];
sprintf(filename, "jsonschema/tests/draft4/%s", filenames[i]);
char* json = ReadFile(filename, jsonAllocator);
if (!json) {
printf("json test suite file %s not found", filename);
ADD_FAILURE();
}
else {
//printf("\njson test suite file %s parsed ok\n", filename);
GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<> > d(&documentAllocator, 1024, &documentStackAllocator);
d.Parse(json);
if (d.HasParseError()) {
printf("json test suite file %s has parse error", filename);
ADD_FAILURE();
}
else {
for (Value::ConstValueIterator schemaItr = d.Begin(); schemaItr != d.End(); ++schemaItr) {
{
const char* description1 = (*schemaItr)["description"].GetString();
//printf("\ncompiling schema for json test %s \n", description1);
SchemaDocumentType schema((*schemaItr)["schema"], filenames[i], static_cast<SizeType>(strlen(filenames[i])), &provider, &schemaAllocator);
GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(schema, &validatorAllocator);
const Value& tests = (*schemaItr)["tests"];
for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
const char* description2 = (*testItr)["description"].GetString();
//printf("running json test %s \n", description2);
if (!onlyRunDescription || strcmp(description2, onlyRunDescription) == 0) {
const Value& data = (*testItr)["data"];
bool expected = (*testItr)["valid"].GetBool();
testCount++;
validator.Reset();
data.Accept(validator);
bool actual = validator.IsValid();
if (expected != actual)
printf("Fail: %30s \"%s\" \"%s\"\n", filename, description1, description2);
else {
//printf("Passed: %30s \"%s\" \"%s\"\n", filename, description1, description2);
passCount++;
}
}
}
//printf("%zu %zu %zu\n", documentAllocator.Size(), schemaAllocator.Size(), validatorAllocator.Size());
}
schemaAllocator.Clear();
validatorAllocator.Clear();
}
}
}
documentAllocator.Clear();
MemoryPoolAllocator<>::Free(json);
jsonAllocator.Clear();
}
printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount);
if (passCount != testCount)
ADD_FAILURE();
}
TEST(SchemaValidatingReader, Simple) {
Document sd;
sd.Parse("{ \"type\": \"string\", \"enum\" : [\"red\", \"amber\", \"green\"] }");
SchemaDocument s(sd);
Document d;
StringStream ss("\"red\"");
SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s);
d.Populate(reader);
EXPECT_TRUE(reader.GetParseResult());
EXPECT_TRUE(reader.IsValid());
EXPECT_TRUE(d.IsString());
EXPECT_STREQ("red", d.GetString());
}
TEST(SchemaValidatingReader, Invalid) {
Document sd;
sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}");
SchemaDocument s(sd);
Document d;
StringStream ss("\"ABCD\"");
SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s);
d.Populate(reader);
EXPECT_FALSE(reader.GetParseResult());
EXPECT_FALSE(reader.IsValid());
EXPECT_EQ(kParseErrorTermination, reader.GetParseResult().Code());
EXPECT_STREQ("maxLength", reader.GetInvalidSchemaKeyword());
EXPECT_TRUE(reader.GetInvalidSchemaCode() == kValidateErrorMaxLength);
EXPECT_TRUE(reader.GetInvalidSchemaPointer() == SchemaDocument::PointerType(""));
EXPECT_TRUE(reader.GetInvalidDocumentPointer() == SchemaDocument::PointerType(""));
EXPECT_TRUE(d.IsNull());
Document e;
e.Parse(
"{ \"maxLength\": {"
" \"errorCode\": 6,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": \"ABCD\""
"}}");
if (e != reader.GetError()) {
ADD_FAILURE();
}
}
TEST(SchemaValidatingWriter, Simple) {
Document sd;
sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}");
SchemaDocument s(sd);
Document d;
StringBuffer sb;
Writer<StringBuffer> writer(sb);
GenericSchemaValidator<SchemaDocument, Writer<StringBuffer> > validator(s, writer);
d.Parse("\"red\"");
EXPECT_TRUE(d.Accept(validator));
EXPECT_TRUE(validator.IsValid());
EXPECT_STREQ("\"red\"", sb.GetString());
sb.Clear();
validator.Reset();
d.Parse("\"ABCD\"");
EXPECT_FALSE(d.Accept(validator));
EXPECT_FALSE(validator.IsValid());
EXPECT_TRUE(validator.GetInvalidSchemaPointer() == SchemaDocument::PointerType(""));
EXPECT_TRUE(validator.GetInvalidDocumentPointer() == SchemaDocument::PointerType(""));
EXPECT_TRUE(validator.GetInvalidSchemaCode() == kValidateErrorMaxLength);
Document e;
e.Parse(
"{ \"maxLength\": {"
" \"errorCode\": 6,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": 3, \"actual\": \"ABCD\""
"}}");
EXPECT_EQ(e, validator.GetError());
}
TEST(Schema, Issue848) {
rapidjson::Document d;
rapidjson::SchemaDocument s(d);
rapidjson::GenericSchemaValidator<rapidjson::SchemaDocument, rapidjson::Document> v(s);
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
static SchemaDocument ReturnSchemaDocument() {
Document sd;
sd.Parse("{ \"type\": [\"number\", \"string\"] }");
SchemaDocument s(sd);
return s;
}
TEST(Schema, Issue552) {
SchemaDocument s = ReturnSchemaDocument();
VALIDATE(s, "42", true);
VALIDATE(s, "\"Life, the universe, and everything\"", true);
INVALIDATE(s, "[\"Life\", \"the universe\", \"and everything\"]", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\", \"number\"], \"actual\": \"array\""
"}}");
}
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(SchemaValidator, Issue608) {
Document sd;
sd.Parse("{\"required\": [\"a\", \"b\"] }");
SchemaDocument s(sd);
VALIDATE(s, "{\"a\" : null, \"b\": null}", true);
INVALIDATE(s, "{\"a\" : null, \"a\" : null}", "", "required", "",
"{ \"required\": {"
" \"errorCode\": 15,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"missing\": [\"b\"]"
"}}");
}
// Fail to resolve $ref in allOf causes crash in SchemaValidator::StartObject()
TEST(SchemaValidator, Issue728_AllOfRef) {
Document sd;
sd.Parse("{\"allOf\": [{\"$ref\": \"#/abc\"}]}");
SchemaDocument s(sd);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/allOf/0\",\"value\":\"#/abc\"}}");
VALIDATE_(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true, false);
}
TEST(SchemaValidator, Issue1017_allOfHandler) {
Document sd;
sd.Parse("{\"allOf\": [{\"type\": \"object\",\"properties\": {\"cyanArray2\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}}},{\"type\": \"object\",\"properties\": {\"blackArray\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}},\"required\": [ \"blackArray\" ]}]}");
SchemaDocument s(sd);
StringBuffer sb;
Writer<StringBuffer> writer(sb);
GenericSchemaValidator<SchemaDocument, Writer<StringBuffer> > validator(s, writer);
EXPECT_TRUE(validator.StartObject());
EXPECT_TRUE(validator.Key("cyanArray2", 10, false));
EXPECT_TRUE(validator.StartArray());
EXPECT_TRUE(validator.EndArray(0));
EXPECT_TRUE(validator.Key("blackArray", 10, false));
EXPECT_TRUE(validator.StartArray());
EXPECT_TRUE(validator.EndArray(0));
EXPECT_TRUE(validator.EndObject(0));
EXPECT_TRUE(validator.IsValid());
EXPECT_STREQ("{\"cyanArray2\":[],\"blackArray\":[]}", sb.GetString());
}
TEST(SchemaValidator, Ref_remote) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"$ref\": \"http://localhost:1234/subSchemas.json#/integer\"}");
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "null", "/integer", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\","
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// Merge with id where $ref is full URI
TEST(SchemaValidator, Ref_remote_change_resolution_scope_uri) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"id\": \"http://ignore/blah#/ref\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"http://localhost:1234/subSchemas.json#/integer\"}}}");
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt\","
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// Merge with id where $ref is a relative path
TEST(SchemaValidator, Ref_remote_change_resolution_scope_relative_path) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"id\": \"http://localhost:1234/\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"subSchemas.json#/integer\"}}}");
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt\","
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// Merge with id where $ref is an absolute path
TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"id\": \"http://localhost:1234/xxxx\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}");
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt\","
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// Merge with id where $ref is an absolute path, and the document has a base URI
TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path_document) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt\","
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// $ref is a non-JSON pointer fragment and there a matching id
TEST(SchemaValidator, Ref_internal_id_1) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}");
SchemaDocumentType s(sd);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt1\","
" \"schemaRef\": \"#/properties/myInt2\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// $ref is a non-JSON pointer fragment and there are two matching ids so we take the first
TEST(SchemaValidator, Ref_internal_id_2) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myId\"}}}");
SchemaDocumentType s(sd);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt1\","
" \"schemaRef\": \"#/properties/myInt2\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// $ref is a non-JSON pointer fragment and there is a matching id within array
TEST(SchemaValidator, Ref_internal_id_in_array) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"string\", \"id\": \"#myStrId\"}, {\"type\": \"integer\", \"id\": \"#myId\"}]}}}");
SchemaDocumentType s(sd);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2/anyOf/1", "type", "/myInt1",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt1\","
" \"schemaRef\": \"#/properties/myInt2/anyOf/1\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// $ref is a non-JSON pointer fragment and there is a matching id, and the schema is embedded in the document
TEST(SchemaValidator, Ref_internal_id_and_schema_pointer) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{ \"schema\": {\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"integer\", \"id\": \"#myId\"}]}}}}");
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
SchemaDocumentType s(sd, 0, 0, 0, 0, PointerType("/schema"));
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
INVALIDATE_(s, "{\"myInt1\": null}", "/schema/properties/myInt2/anyOf/0", "type", "/myInt1",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#/myInt1\","
" \"schemaRef\": \"#/schema/properties/myInt2/anyOf/0\","
" \"expected\": [\"integer\"], \"actual\": \"null\""
"}}",
kValidateDefaultFlags, SchemaValidatorType, PointerType);
}
// Test that $refs are correctly resolved when intermediate multiple ids are present
// Includes $ref to a part of the document with a different in-scope id, which also contains $ref..
TEST(SchemaValidator, Ref_internal_multiple_ids) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
//RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/idandref.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocumentType s(sd, "http://xyz", 10/*, &provider*/);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"PA1\": \"s\", \"PA2\": \"t\", \"PA3\": \"r\", \"PX1\": 1, \"PX2Y\": 2, \"PX3Z\": 3, \"PX4\": 4, \"PX5\": 5, \"PX6\": 6, \"PX7W\": 7, \"PX8N\": { \"NX\": 8}}", "#", "errors", "#",
"{ \"type\": ["
" {\"errorCode\": 20, \"instanceRef\": \"#/PA1\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PA2\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PA3\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX1\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX2Y\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX3Z\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX4\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX5\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX6\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX7W\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
" {\"errorCode\": 20, \"instanceRef\": \"#/PX8N/NX\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}"
"]}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType);
CrtAllocator::Free(schema);
}
TEST(SchemaValidator, Ref_remote_issue1210) {
class SchemaDocumentProvider : public IRemoteSchemaDocumentProvider {
SchemaDocument** collection;
// Dummy private copy constructor & assignment operator.
// Function bodies added so that they compile in MSVC 2019.
SchemaDocumentProvider(const SchemaDocumentProvider&) : collection(NULL) {
}
SchemaDocumentProvider& operator=(const SchemaDocumentProvider&) {
return *this;
}
public:
SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
int i = 0;
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
while (collection[i] && SchemaDocument::GValue(uri, length) != collection[i]->GetURI()) ++i;
return collection[i];
}
};
SchemaDocument* collection[] = { 0, 0, 0 };
SchemaDocumentProvider provider(collection);
Document x, y, z;
x.Parse("{\"properties\":{\"country\":{\"$ref\":\"y.json#/definitions/country_remote\"}},\"type\":\"object\"}");
y.Parse("{\"definitions\":{\"country_remote\":{\"$ref\":\"z.json#/definitions/country_list\"}}}");
z.Parse("{\"definitions\":{\"country_list\":{\"enum\":[\"US\"]}}}");
SchemaDocument sz(z, "z.json", 6, &provider);
collection[0] = &sz;
SchemaDocument sy(y, "y.json", 6, &provider);
collection[1] = &sy;
SchemaDocument sx(x, "x.json", 6, &provider);
VALIDATE(sx, "{\"country\":\"UK\"}", false);
VALIDATE(sx, "{\"country\":\"US\"}", true);
}
// Test that when kValidateContinueOnErrorFlag is set, all errors are reported.
TEST(SchemaValidator, ContinueOnErrors) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
VALIDATE(s, "{\"version\": 1.0, \"address\": {\"number\": 24, \"street1\": \"The Woodlands\", \"street3\": \"Ham\", \"city\": \"Romsey\", \"area\": \"Kent\", \"country\": \"UK\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\"], \"names\": [\"Fred\", \"Bloggs\"]}", true);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"Narnia\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
"{ \"multipleOf\": {"
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
" },"
" \"minimum\": {"
" \"errorCode\": 5, \"instanceRef\": \"#/address/number\", \"schemaRef\": \"#/definitions/positiveInt_type\", \"expected\": 0, \"actual\": 0, \"exclusiveMinimum\": true"
" },"
" \"type\": ["
" {\"expected\": [\"null\", \"string\"], \"actual\": \"boolean\", \"errorCode\": 20, \"instanceRef\": \"#/address/street2\", \"schemaRef\": \"#/definitions/address_type/properties/street2\"},"
" {\"expected\": [\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#/extra/S_xxx\", \"schemaRef\": \"#/properties/extra/patternProperties/%5ES_\"}"
" ],"
" \"maxLength\": {"
" \"actual\": \"RomseyTownFC\", \"expected\": 10, \"errorCode\": 6, \"instanceRef\": \"#/address/city\", \"schemaRef\": \"#/definitions/address_type/properties/city\""
" },"
" \"anyOf\": {"
" \"errors\":["
" {\"pattern\": {\"actual\": \"999ABC\", \"errorCode\": 8, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode/anyOf/0\"}},"
" {\"pattern\": {\"actual\": \"999ABC\", \"errorCode\": 8, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode/anyOf/1\"}}"
" ],"
" \"errorCode\": 24, \"instanceRef\": \"#/address/postcode\", \"schemaRef\": \"#/definitions/address_type/properties/postcode\""
" },"
" \"allOf\": {"
" \"errors\":["
" {\"enum\":{\"errorCode\":19,\"instanceRef\":\"#/address/country\",\"schemaRef\":\"#/definitions/country_type\"}}"
" ],"
" \"errorCode\":23,\"instanceRef\":\"#/address/country\",\"schemaRef\":\"#/definitions/address_type/properties/country\""
" },"
" \"minItems\": {"
" \"actual\": 0, \"expected\": 1, \"errorCode\": 10, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\""
" },"
" \"additionalProperties\": {"
" \"disallowed\": \"planet\", \"errorCode\": 16, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" },"
" \"required\": {"
" \"missing\": [\"street1\"], \"errorCode\": 15, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\""
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
" },"
" \"oneOf\": {"
" \"matches\": [0, 1], \"errorCode\": 22, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
INVALIDATE_(s, "{\"address\": {\"number\": 200, \"street1\": {}, \"street3\": null, \"city\": \"Rom\", \"area\": \"Dorset\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\", \"0777-666888\"], \"names\": [\"Fred\", \"S\", \"M\", \"Bloggs\"]}", "#", "errors", "#",
"{ \"maximum\": {"
" \"errorCode\": 3, \"instanceRef\": \"#/address/number\", \"schemaRef\": \"#/definitions/positiveInt_type\", \"expected\": 100, \"actual\": 200, \"exclusiveMaximum\": true"
" },"
" \"type\": {"
" \"expected\": [\"string\"], \"actual\": \"object\", \"errorCode\": 20, \"instanceRef\": \"#/address/street1\", \"schemaRef\": \"#/definitions/address_type/properties/street1\""
" },"
" \"not\": {"
" \"errorCode\": 25, \"instanceRef\": \"#/address/street3\", \"schemaRef\": \"#/definitions/address_type/properties/street3\""
" },"
" \"minLength\": {"
" \"actual\": \"Rom\", \"expected\": 4, \"errorCode\": 7, \"instanceRef\": \"#/address/city\", \"schemaRef\": \"#/definitions/address_type/properties/city\""
" },"
" \"maxItems\": {"
" \"actual\": 3, \"expected\": 2, \"errorCode\": 9, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\""
" },"
" \"uniqueItems\": {"
" \"duplicates\": [1, 2], \"errorCode\": 11, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\""
" },"
" \"minProperties\": {\"actual\": 6, \"expected\": 7, \"errorCode\": 14, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\""
" },"
" \"additionalItems\": ["
" {\"disallowed\": 2, \"errorCode\": 12, \"instanceRef\": \"#/names\", \"schemaRef\": \"#/properties/names\"},"
" {\"disallowed\": 3, \"errorCode\": 12, \"instanceRef\": \"#/names\", \"schemaRef\": \"#/properties/names\"}"
" ],"
" \"dependencies\": {"
" \"errors\": {"
" \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}},"
" \"names\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/names\"}}"
" },"
" \"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" },"
" \"oneOf\": {"
" \"errors\": ["
" {\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/county_type\"}},"
" {\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/province_type\"}}"
" ],"
" \"errorCode\": 21, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, it is not propagated to oneOf sub-validator so we only get the first error.
TEST(SchemaValidator, ContinueOnErrors_OneOf) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/oneOf_address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
"{ \"oneOf\": {"
" \"errors\": [{"
" \"multipleOf\": {"
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
" }"
" }],"
" \"errorCode\": 21, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, it is not propagated to allOf sub-validator so we only get the first error.
TEST(SchemaValidator, ContinueOnErrors_AllOf) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/allOf_address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
"{ \"allOf\": {"
" \"errors\": [{"
" \"multipleOf\": {"
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
" }"
" }],"
" \"errorCode\": 23, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, it is not propagated to anyOf sub-validator so we only get the first error.
TEST(SchemaValidator, ContinueOnErrors_AnyOf) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/anyOf_address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocumentType s(sd, 0, 0, &provider);
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
"{ \"anyOf\": {"
" \"errors\": [{"
" \"multipleOf\": {"
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"http://localhost:1234/address.json#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
" }"
" }],"
" \"errorCode\": 24, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, arrays with uniqueItems:true are correctly processed when an item is invalid.
// This tests that we don't blow up if a hasher does not get created.
TEST(SchemaValidator, ContinueOnErrors_UniqueItems) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
VALIDATE(s, "{\"phones\":[\"12-34\",\"56-78\"]}", true);
INVALIDATE_(s, "{\"phones\":[\"12-34\",\"12-34\"]}", "#", "errors", "#",
"{\"uniqueItems\": {\"duplicates\": [0,1], \"errorCode\": 11, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
INVALIDATE_(s, "{\"phones\":[\"ab-34\",\"cd-78\"]}", "#", "errors", "#",
"{\"pattern\": ["
" {\"actual\": \"ab-34\", \"errorCode\": 8, \"instanceRef\": \"#/phones/0\", \"schemaRef\": \"#/definitions/phone_type\"},"
" {\"actual\": \"cd-78\", \"errorCode\": 8, \"instanceRef\": \"#/phones/1\", \"schemaRef\": \"#/definitions/phone_type\"}"
"]}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, an enum field is correctly processed when it has an invalid value.
// This tests that we don't blow up if a hasher does not get created.
TEST(SchemaValidator, ContinueOnErrors_Enum) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
VALIDATE(s, "{\"gender\":\"M\"}", true);
INVALIDATE_(s, "{\"gender\":\"X\"}", "#", "errors", "#",
"{\"enum\": {\"errorCode\": 19, \"instanceRef\": \"#/gender\", \"schemaRef\": \"#/properties/gender\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
INVALIDATE_(s, "{\"gender\":1}", "#", "errors", "#",
"{\"type\": {\"expected\":[\"string\"], \"actual\": \"integer\", \"errorCode\": 20, \"instanceRef\": \"#/gender\", \"schemaRef\": \"#/properties/gender\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, an array appearing for an object property is handled
// This tests that we don't blow up when there is a type mismatch.
TEST(SchemaValidator, ContinueOnErrors_RogueArray) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
INVALIDATE_(s, "{\"address\":[{\"number\": 0}]}", "#", "errors", "#",
"{\"type\": {\"expected\":[\"object\"], \"actual\": \"array\", \"errorCode\": 20, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"},"
" \"dependencies\": {"
" \"errors\": {"
" \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}}"
" },\"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, an object appearing for an array property is handled
// This tests that we don't blow up when there is a type mismatch.
TEST(SchemaValidator, ContinueOnErrors_RogueObject) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
INVALIDATE_(s, "{\"phones\":{\"number\": 0}}", "#", "errors", "#",
"{\"type\": {\"expected\":[\"array\"], \"actual\": \"object\", \"errorCode\": 20, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, a string appearing for an array or object property is handled
// This tests that we don't blow up when there is a type mismatch.
TEST(SchemaValidator, ContinueOnErrors_RogueString) {
CrtAllocator allocator;
char* schema = ReadFile("unittestschema/address.json", allocator);
Document sd;
sd.Parse(schema);
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
INVALIDATE_(s, "{\"address\":\"number\"}", "#", "errors", "#",
"{\"type\": {\"expected\":[\"object\"], \"actual\": \"string\", \"errorCode\": 20, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\"},"
" \"dependencies\": {"
" \"errors\": {"
" \"address\": {\"required\": {\"missing\": [\"version\"], \"errorCode\": 15, \"instanceRef\": \"#\", \"schemaRef\": \"#/dependencies/address\"}}"
" },\"errorCode\": 18, \"instanceRef\": \"#\", \"schemaRef\": \"#\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
INVALIDATE_(s, "{\"phones\":\"number\"}", "#", "errors", "#",
"{\"type\": {\"expected\":[\"array\"], \"actual\": \"string\", \"errorCode\": 20, \"instanceRef\": \"#/phones\", \"schemaRef\": \"#/properties/phones\"}}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
CrtAllocator::Free(schema);
}
// Test that when kValidateContinueOnErrorFlag is set, an incorrect simple type with a sub-schema is handled correctly.
// This tests that we don't blow up when there is a type mismatch but there is a sub-schema present
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
TEST(SchemaValidator, ContinueOnErrors_BadSimpleType) {
Document sd;
sd.Parse("{\"type\":\"string\", \"anyOf\":[{\"maxLength\":2}]}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
VALIDATE(s, "\"AB\"", true);
INVALIDATE_(s, "\"ABC\"", "#", "errors", "#",
"{ \"anyOf\": {"
" \"errors\": [{"
" \"maxLength\": {"
" \"errorCode\": 6, \"instanceRef\": \"#\", \"schemaRef\": \"#/anyOf/0\", \"expected\": 2, \"actual\": \"ABC\""
" }"
" }],"
" \"errorCode\": 24, \"instanceRef\": \"#\", \"schemaRef\": \"#\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
// Invalid type
INVALIDATE_(s, "333", "#", "errors", "#",
"{ \"type\": {"
" \"errorCode\": 20, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"expected\": [\"string\"], \"actual\": \"integer\""
" }"
"}",
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
}
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
TEST(SchemaValidator, UnknownValidationError) {
ASSERT_TRUE(SchemaValidator::SchemaType::GetValidateErrorKeyword(kValidateErrors).GetString() == std::string("null"));
}
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
// The first occurrence of a duplicate keyword is taken
TEST(SchemaValidator, DuplicateKeyword) {
Document sd;
sd.Parse("{ \"title\": \"test\",\"type\": \"number\", \"type\": \"string\" }");
EXPECT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
VALIDATE(s, "42", true);
INVALIDATE(s, "\"Life, the universe, and everything\"", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"number\"], \"actual\": \"string\""
"}}");
}
// SchemaDocument tests
// Specification (schema draft, open api version)
TEST(SchemaValidator, Schema_SupportedNotObject) {
Document sd;
sd.Parse("true");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedNoSpec) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedNoSpecStatic) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
Specification spec = SchemaDocumentType::GetSpecification(sd);
ASSERT_FALSE(spec.IsSupported());
ASSERT_TRUE(spec.draft == kDraftNone);
ASSERT_TRUE(spec.oapi == kVersionNone);
}
TEST(SchemaValidator, Schema_SupportedDraft5Static) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
Specification spec = SchemaDocumentType::GetSpecification(sd);
ASSERT_TRUE(spec.IsSupported());
ASSERT_TRUE(spec.draft == kDraft05);
ASSERT_TRUE(spec.oapi == kVersionNone);
}
TEST(SchemaValidator, Schema_SupportedDraft4) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedDraft4NoFrag) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedDraft5) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedDraft5NoFrag) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_IgnoreDraftEmbedded) {
Document sd;
sd.Parse("{\"root\": {\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/root"));
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedDraftOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft04));
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_UnknownDraftOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraftUnknown));
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraftOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft03));
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft03);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnknownDraft) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-xxx/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnknownDraftNotString) {
Document sd;
sd.Parse("{\"$schema\": 4, \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraft3) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-03/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft03);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraft6) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-06/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft06);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraft7) {
Document sd;
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-07/schema#\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft07);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraft2019_09) {
Document sd;
sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft2019_09);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedDraft2020_12) {
Document sd;
sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\", \"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_SupportedVersion20Static) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"swagger\":\"2.0\"}");
ASSERT_FALSE(sd.HasParseError());
Specification spec = SchemaDocumentType::GetSpecification(sd);
ASSERT_TRUE(spec.IsSupported());
ASSERT_TRUE(spec.draft == kDraft04);
ASSERT_TRUE(spec.oapi == kVersion20);
}
TEST(SchemaValidator, Schema_SupportedVersion20) {
Document sd;
sd.Parse("{\"swagger\":\"2.0\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersion20);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedVersion30x) {
Document sd;
sd.Parse("{\"openapi\":\"3.0.0\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersion30);
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_SupportedVersionOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20));
ASSERT_TRUE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersion20);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
EXPECT_TRUE(s.GetError().ObjectEmpty());
}
TEST(SchemaValidator, Schema_UnknownVersionOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersionUnknown));
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedVersionOverride) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion31));
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersion31);
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnknownVersion) {
Document sd;
sd.Parse("{\"openapi\":\"1.0\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnknownVersionShort) {
Document sd;
sd.Parse("{\"openapi\":\"3.0.\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnknownVersionNotString) {
Document sd;
sd.Parse("{\"swagger\": 2}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_UnsupportedVersion31) {
Document sd;
sd.Parse("{\"openapi\":\"3.1.0\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_FALSE(s.IsSupportedSpecification());
ASSERT_TRUE(s.GetSpecification().oapi == kVersion31);
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_DraftAndVersion) {
Document sd;
sd.Parse("{\"swagger\": \"2.0\", \"$schema\": \"http://json-schema.org/draft-04/schema#\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
ASSERT_TRUE(s.IsSupportedSpecification());
SCHEMAERROR(s, "{\"SpecIllegal\":{\"errorCode\":12,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, Schema_StartUnknown) {
Document sd;
sd.Parse("{\"type\": \"integer\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/nowhere"));
SCHEMAERROR(s, "{\"StartUnknown\":{\"errorCode\":1,\"instanceRef\":\"#\", \"value\":\"#/nowhere\"}}");
}
TEST(SchemaValidator, Schema_MultipleErrors) {
Document sd;
sd.Parse("{\"swagger\": \"foo\", \"$schema\": \"bar\"}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s(sd);
SCHEMAERROR(s, "{ \"SpecUnknown\": {\"errorCode\":10,\"instanceRef\":\"#\"},"
" \"SpecIllegal\": {\"errorCode\":12,\"instanceRef\":\"#\"}"
"}");
}
// $ref is a non-JSON pointer fragment - not allowed when OpenAPI
TEST(SchemaValidator, Schema_RefPlainNameOpenApi) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"swagger\": \"2.0\", \"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt1\",\"value\":\"#myId\"}}");
}
// $ref is a non-JSON pointer fragment - not allowed when remote document
TEST(SchemaValidator, Schema_RefPlainNameRemote) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}");
}
// $ref is an empty string
TEST(SchemaValidator, Schema_RefEmptyString) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"\"}}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefInvalid\":{\"errorCode\":3,\"instanceRef\":\"#/properties/myInt1\"}}");
}
// $ref is remote but no provider
TEST(SchemaValidator, Schema_RefNoRemoteProvider) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, 0);
SCHEMAERROR(s, "{\"RefNoRemoteProvider\":{\"errorCode\":7,\"instanceRef\":\"#/properties/myInt\"}}");
}
// $ref is remote but no schema returned
TEST(SchemaValidator, Schema_RefNoRemoteSchema) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/will-not-resolve.json\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
SCHEMAERROR(s, "{\"RefNoRemoteSchema\":{\"errorCode\":8,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/will-not-resolve.json\"}}");
}
// $ref pointer is invalid
TEST(SchemaValidator, Schema_RefPointerInvalid) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/&&&&&\"}}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/&&&&&\",\"offset\":2}}");
}
// $ref is remote and pointer is invalid
TEST(SchemaValidator, Schema_RefPointerInvalidRemote) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/abc&&&&&\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/abc&&&&&\",\"offset\":5}}");
}
// $ref is unknown non-pointer
TEST(SchemaValidator, Schema_RefUnknownPlainName) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#plainname\"}}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}");
}
/// $ref is unknown pointer
TEST(SchemaValidator, Schema_RefUnknownPointer) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/a/b\"}}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/a/b\"}}");
}
// $ref is remote and unknown pointer
TEST(SchemaValidator, Schema_RefUnknownPointerRemote) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/a/b\"}}}");
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/subSchemas.json#/a/b\"}}");
}
// $ref is cyclical
TEST(SchemaValidator, Schema_RefCyclical) {
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
Document sd;
sd.Parse("{\"type\": \"object\", \"properties\": {"
" \"cyclic_source\": {"
" \"$ref\": \"#/properties/cyclic_target\""
" },"
" \"cyclic_target\": {"
" \"$ref\": \"#/properties/cyclic_source\""
" }"
"}}");
SchemaDocumentType s(sd);
SCHEMAERROR(s, "{\"RefCyclical\":{\"errorCode\":6,\"instanceRef\":\"#/properties/cyclic_target\",\"value\":\"#/properties/cyclic_source\"}}");
}
TEST(SchemaValidator, Schema_ReadOnlyAndWriteOnly) {
Document sd;
sd.Parse("{\"type\": \"integer\", \"readOnly\": true, \"writeOnly\": true}");
ASSERT_FALSE(sd.HasParseError());
SchemaDocument s1(sd, 0, 0, 0, 0, 0, Specification(kDraft04));
EXPECT_TRUE(s1.GetError().ObjectEmpty());
SchemaDocument s2(sd, 0, 0, 0, 0, 0, Specification(kVersion30));
SCHEMAERROR(s2, "{\"ReadOnlyAndWriteOnly\":{\"errorCode\":13,\"instanceRef\":\"#\"}}");
}
TEST(SchemaValidator, ReadOnlyWhenWriting) {
Document sd;
sd.Parse(
"{"
" \"type\":\"object\","
" \"properties\": {"
" \"rprop\" : {"
" \"type\": \"string\","
" \"readOnly\": true"
" }"
" }"
"}");
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20));
VALIDATE(s, "{ \"rprop\": \"hello\" }", true);
INVALIDATE_(s, "{ \"rprop\": \"hello\" }", "/properties/rprop", "readOnly", "/rprop",
"{ \"readOnly\": {"
" \"errorCode\": 26, \"instanceRef\": \"#/rprop\", \"schemaRef\": \"#/properties/rprop\""
" }"
"}",
kValidateDefaultFlags | kValidateWriteFlag, SchemaValidator, Pointer);
}
TEST(SchemaValidator, WriteOnlyWhenReading) {
Document sd;
sd.Parse(
"{"
" \"type\":\"object\","
" \"properties\": {"
" \"wprop\" : {"
" \"type\": \"boolean\","
" \"writeOnly\": true"
" }"
" }"
"}");
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion30));
VALIDATE(s, "{ \"wprop\": true }", true);
INVALIDATE_(s, "{ \"wprop\": true }", "/properties/wprop", "writeOnly", "/wprop",
"{ \"writeOnly\": {"
" \"errorCode\": 27, \"instanceRef\": \"#/wprop\", \"schemaRef\": \"#/properties/wprop\""
" }"
"}",
kValidateDefaultFlags | kValidateReadFlag, SchemaValidator, Pointer);
}
TEST(SchemaValidator, NullableTrue) {
Document sd;
sd.Parse("{\"type\": \"string\", \"nullable\": true}");
SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20);
VALIDATE(s, "\"hello\"", true);
INVALIDATE(s, "null", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"null\""
"}}");
INVALIDATE(s, "false", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"boolean\""
"}}");
SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30);
VALIDATE(s30, "\"hello\"", true);
VALIDATE(s30, "null", true);
INVALIDATE(s30, "false", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"null\", \"string\"], \"actual\": \"boolean\""
"}}");
}
TEST(SchemaValidator, NullableFalse) {
Document sd;
sd.Parse("{\"type\": \"string\", \"nullable\": false}");
SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20);
VALIDATE(s, "\"hello\"", true);
INVALIDATE(s, "null", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"null\""
"}}");
INVALIDATE(s, "false", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"boolean\""
"}}");
SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30);
VALIDATE(s30, "\"hello\"", true);
INVALIDATE(s, "null", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"null\""
"}}");
INVALIDATE(s30, "false", "", "type", "",
"{ \"type\": {"
" \"errorCode\": 20,"
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
" \"expected\": [\"string\"], \"actual\": \"boolean\""
"}}");
}
#if defined(_MSC_VER) || defined(__clang__)
RAPIDJSON_DIAG_POP
#endif