rj_schema 0.2.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rj_schema/rapidjson/bin/unittestschema/address.json +139 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/allOf_address.json +7 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/anyOf_address.json +7 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/oneOf_address.json +7 -0
- data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +118 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +5 -5
- data/ext/rj_schema/rapidjson/include/rapidjson/cursorstreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/document.h +17 -12
- data/ext/rj_schema/rapidjson/include/rapidjson/encodedstream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/encodings.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/error/en.h +49 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/error/error.h +56 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/filereadstream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/filewritestream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/fwd.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/biginteger.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/clzll.h +4 -4
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/diyfp.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/dtoa.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/ieee754.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/itoa.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/meta.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/pow10.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/regex.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/stack.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strtod.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/swap.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/istreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/memorybuffer.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/memorystream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/ostreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/prettywriter.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +17 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/reader.h +17 -9
- data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +311 -159
- data/ext/rj_schema/rapidjson/include/rapidjson/stream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/stringbuffer.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/writer.h +3 -3
- data/ext/rj_schema/rapidjson/readme.md +3 -3
- data/ext/rj_schema/rapidjson/readme.zh-cn.md +2 -2
- data/ext/rj_schema/rapidjson/test/perftest/misctest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/perftest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/perftest.h +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/platformtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +1 -0
- data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/bigintegertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/clzlltest.cpp +34 -0
- data/ext/rj_schema/rapidjson/test/unittest/cursorstreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/dtoatest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/encodedstreamtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/encodingstest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/filestreamtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/fwdtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/istreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/itoatest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/jsoncheckertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/namespacetest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/ostreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +33 -1
- data/ext/rj_schema/rapidjson/test/unittest/prettywritertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/readertest.cpp +4 -1
- data/ext/rj_schema/rapidjson/test/unittest/regextest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +593 -78
- data/ext/rj_schema/rapidjson/test/unittest/simdtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/strfunctest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/stringbuffertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/strtodtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/unittest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/unittest.h +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/writertest.cpp +1 -1
- data/ext/rj_schema/rj_schema.cpp +160 -16
- data/lib/rj_schema.rb +1 -1
- metadata +8 -3
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -65,6 +65,54 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
|
65
65
|
}
|
66
66
|
}
|
67
67
|
|
68
|
+
//! Maps error code of validation into error message.
|
69
|
+
/*!
|
70
|
+
\ingroup RAPIDJSON_ERRORS
|
71
|
+
\param validateErrorCode Error code obtained from validator.
|
72
|
+
\return the error message.
|
73
|
+
\note User can make a copy of this function for localization.
|
74
|
+
Using switch-case is safer for future modification of error codes.
|
75
|
+
*/
|
76
|
+
inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode validateErrorCode) {
|
77
|
+
switch (validateErrorCode) {
|
78
|
+
case kValidateErrors: return RAPIDJSON_ERROR_STRING("One or more validation errors have occurred");
|
79
|
+
case kValidateErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
80
|
+
|
81
|
+
case kValidateErrorMultipleOf: return RAPIDJSON_ERROR_STRING("Number '%actual' is not a multiple of the 'multipleOf' value '%expected'.");
|
82
|
+
case kValidateErrorMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than the 'maximum' value '%expected'.");
|
83
|
+
case kValidateErrorExclusiveMaximum: return RAPIDJSON_ERROR_STRING("Number '%actual' is greater than or equal to the 'exclusiveMaximum' value '%expected'.");
|
84
|
+
case kValidateErrorMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than the 'minimum' value '%expected'.");
|
85
|
+
case kValidateErrorExclusiveMinimum: return RAPIDJSON_ERROR_STRING("Number '%actual' is less than or equal to the 'exclusiveMinimum' value '%expected'.");
|
86
|
+
|
87
|
+
case kValidateErrorMaxLength: return RAPIDJSON_ERROR_STRING("String '%actual' is longer than the 'maxLength' value '%expected'.");
|
88
|
+
case kValidateErrorMinLength: return RAPIDJSON_ERROR_STRING("String '%actual' is shorter than the 'minLength' value '%expected'.");
|
89
|
+
case kValidateErrorPattern: return RAPIDJSON_ERROR_STRING("String '%actual' does not match the 'pattern' regular expression.");
|
90
|
+
|
91
|
+
case kValidateErrorMaxItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is longer than the 'maxItems' value '%expected'.");
|
92
|
+
case kValidateErrorMinItems: return RAPIDJSON_ERROR_STRING("Array of length '%actual' is shorter than the 'minItems' value '%expected'.");
|
93
|
+
case kValidateErrorUniqueItems: return RAPIDJSON_ERROR_STRING("Array has duplicate items at indices '%duplicates' but 'uniqueItems' is true.");
|
94
|
+
case kValidateErrorAdditionalItems: return RAPIDJSON_ERROR_STRING("Array has an additional item at index '%disallowed' that is not allowed by the schema.");
|
95
|
+
|
96
|
+
case kValidateErrorMaxProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is more than 'maxProperties' value '%expected'.");
|
97
|
+
case kValidateErrorMinProperties: return RAPIDJSON_ERROR_STRING("Object has '%actual' members which is less than 'minProperties' value '%expected'.");
|
98
|
+
case kValidateErrorRequired: return RAPIDJSON_ERROR_STRING("Object is missing the following members required by the schema: '%missing'.");
|
99
|
+
case kValidateErrorAdditionalProperties: return RAPIDJSON_ERROR_STRING("Object has an additional member '%disallowed' that is not allowed by the schema.");
|
100
|
+
case kValidateErrorPatternProperties: return RAPIDJSON_ERROR_STRING("Object has 'patternProperties' that are not allowed by the schema.");
|
101
|
+
case kValidateErrorDependencies: return RAPIDJSON_ERROR_STRING("Object has missing property or schema dependencies, refer to following errors.");
|
102
|
+
|
103
|
+
case kValidateErrorEnum: return RAPIDJSON_ERROR_STRING("Property has a value that is not one of its allowed enumerated values.");
|
104
|
+
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
105
|
+
|
106
|
+
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
107
|
+
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
|
108
|
+
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
109
|
+
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
110
|
+
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
111
|
+
|
112
|
+
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
68
116
|
RAPIDJSON_NAMESPACE_END
|
69
117
|
|
70
118
|
#ifdef __clang__
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -152,6 +152,61 @@ private:
|
|
152
152
|
*/
|
153
153
|
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
154
154
|
|
155
|
+
///////////////////////////////////////////////////////////////////////////////
|
156
|
+
// ValidateErrorCode
|
157
|
+
|
158
|
+
//! Error codes when validating.
|
159
|
+
/*! \ingroup RAPIDJSON_ERRORS
|
160
|
+
\see GenericSchemaValidator
|
161
|
+
*/
|
162
|
+
enum ValidateErrorCode {
|
163
|
+
kValidateErrors = -1, //!< Top level error code when kValidateContinueOnErrorsFlag set.
|
164
|
+
kValidateErrorNone = 0, //!< No error.
|
165
|
+
|
166
|
+
kValidateErrorMultipleOf, //!< Number is not a multiple of the 'multipleOf' value.
|
167
|
+
kValidateErrorMaximum, //!< Number is greater than the 'maximum' value.
|
168
|
+
kValidateErrorExclusiveMaximum, //!< Number is greater than or equal to the 'maximum' value.
|
169
|
+
kValidateErrorMinimum, //!< Number is less than the 'minimum' value.
|
170
|
+
kValidateErrorExclusiveMinimum, //!< Number is less than or equal to the 'minimum' value.
|
171
|
+
|
172
|
+
kValidateErrorMaxLength, //!< String is longer than the 'maxLength' value.
|
173
|
+
kValidateErrorMinLength, //!< String is longer than the 'maxLength' value.
|
174
|
+
kValidateErrorPattern, //!< String does not match the 'pattern' regular expression.
|
175
|
+
|
176
|
+
kValidateErrorMaxItems, //!< Array is longer than the 'maxItems' value.
|
177
|
+
kValidateErrorMinItems, //!< Array is shorter than the 'minItems' value.
|
178
|
+
kValidateErrorUniqueItems, //!< Array has duplicate items but 'uniqueItems' is true.
|
179
|
+
kValidateErrorAdditionalItems, //!< Array has additional items that are not allowed by the schema.
|
180
|
+
|
181
|
+
kValidateErrorMaxProperties, //!< Object has more members than 'maxProperties' value.
|
182
|
+
kValidateErrorMinProperties, //!< Object has less members than 'minProperties' value.
|
183
|
+
kValidateErrorRequired, //!< Object is missing one or more members required by the schema.
|
184
|
+
kValidateErrorAdditionalProperties, //!< Object has additional members that are not allowed by the schema.
|
185
|
+
kValidateErrorPatternProperties, //!< See other errors.
|
186
|
+
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
|
187
|
+
|
188
|
+
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values
|
189
|
+
kValidateErrorType, //!< Property has a type that is not allowed by the schema..
|
190
|
+
|
191
|
+
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
|
192
|
+
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
|
193
|
+
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
|
194
|
+
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
|
195
|
+
kValidateErrorNot //!< Property matched the sub-schema specified by 'not'.
|
196
|
+
};
|
197
|
+
|
198
|
+
//! Function pointer type of GetValidateError().
|
199
|
+
/*! \ingroup RAPIDJSON_ERRORS
|
200
|
+
|
201
|
+
This is the prototype for \c GetValidateError_X(), where \c X is a locale.
|
202
|
+
User can dynamically change locale in runtime, e.g.:
|
203
|
+
\code
|
204
|
+
GetValidateErrorFunc GetValidateError = GetValidateError_En; // or whatever
|
205
|
+
const RAPIDJSON_ERROR_CHARTYPE* s = GetValidateError(validator.GetInvalidSchemaCode());
|
206
|
+
\endcode
|
207
|
+
*/
|
208
|
+
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
|
209
|
+
|
155
210
|
RAPIDJSON_NAMESPACE_END
|
156
211
|
|
157
212
|
#ifdef __clang__
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
#include "../rapidjson.h"
|
19
19
|
|
20
|
-
#if defined(_MSC_VER)
|
20
|
+
#if defined(_MSC_VER) && !defined(UNDER_CE)
|
21
21
|
#include <intrin.h>
|
22
22
|
#if defined(_WIN64)
|
23
23
|
#pragma intrinsic(_BitScanReverse64)
|
@@ -34,7 +34,7 @@ inline uint32_t clzll(uint64_t x) {
|
|
34
34
|
// infinite loop in the software implementation.
|
35
35
|
RAPIDJSON_ASSERT(x != 0);
|
36
36
|
|
37
|
-
#if defined(_MSC_VER)
|
37
|
+
#if defined(_MSC_VER) && !defined(UNDER_CE)
|
38
38
|
unsigned long r = 0;
|
39
39
|
#if defined(_WIN64)
|
40
40
|
_BitScanReverse64(&r, x);
|
@@ -53,7 +53,7 @@ inline uint32_t clzll(uint64_t x) {
|
|
53
53
|
return static_cast<uint32_t>(__builtin_clzll(x));
|
54
54
|
#else
|
55
55
|
// naive version
|
56
|
-
uint32_t r;
|
56
|
+
uint32_t r = 0;
|
57
57
|
while (!(x & (static_cast<uint64_t>(1) << 63))) {
|
58
58
|
x <<= 1;
|
59
59
|
++r;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -639,6 +639,22 @@ RAPIDJSON_NAMESPACE_END
|
|
639
639
|
#endif // RAPIDJSON_ASSERT_THROWS
|
640
640
|
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
641
641
|
|
642
|
+
///////////////////////////////////////////////////////////////////////////////
|
643
|
+
// malloc/realloc/free
|
644
|
+
|
645
|
+
#ifndef RAPIDJSON_MALLOC
|
646
|
+
///! customization point for global \c malloc
|
647
|
+
#define RAPIDJSON_MALLOC(size) std::malloc(size)
|
648
|
+
#endif
|
649
|
+
#ifndef RAPIDJSON_REALLOC
|
650
|
+
///! customization point for global \c realloc
|
651
|
+
#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
|
652
|
+
#endif
|
653
|
+
#ifndef RAPIDJSON_FREE
|
654
|
+
///! customization point for global \c free
|
655
|
+
#define RAPIDJSON_FREE(ptr) std::free(ptr)
|
656
|
+
#endif
|
657
|
+
|
642
658
|
///////////////////////////////////////////////////////////////////////////////
|
643
659
|
// new/delete
|
644
660
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
2
|
//
|
3
|
-
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
3
|
+
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
4
|
//
|
5
5
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
6
|
// in compliance with the License. You may obtain a copy of the License at
|
@@ -1023,15 +1023,23 @@ private:
|
|
1023
1023
|
is.Take();
|
1024
1024
|
unsigned codepoint = ParseHex4(is, escapeOffset);
|
1025
1025
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
1026
|
-
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <=
|
1027
|
-
//
|
1028
|
-
if (
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1026
|
+
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
|
1027
|
+
// high surrogate, check if followed by valid low surrogate
|
1028
|
+
if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) {
|
1029
|
+
// Handle UTF-16 surrogate pair
|
1030
|
+
if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
|
1031
|
+
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
1032
|
+
unsigned codepoint2 = ParseHex4(is, escapeOffset);
|
1033
|
+
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
1034
|
+
if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
|
1035
|
+
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
1036
|
+
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
|
1037
|
+
}
|
1038
|
+
// single low surrogate
|
1039
|
+
else
|
1040
|
+
{
|
1033
1041
|
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
|
1034
|
-
|
1042
|
+
}
|
1035
1043
|
}
|
1036
1044
|
TEncoding::Encode(os, codepoint);
|
1037
1045
|
}
|
@@ -18,6 +18,7 @@
|
|
18
18
|
#include "document.h"
|
19
19
|
#include "pointer.h"
|
20
20
|
#include "stringbuffer.h"
|
21
|
+
#include "error/en.h"
|
21
22
|
#include <cmath> // abs, floor
|
22
23
|
|
23
24
|
#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)
|
@@ -113,13 +114,36 @@ inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar
|
|
113
114
|
#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)
|
114
115
|
#endif
|
115
116
|
|
116
|
-
#define RAPIDJSON_INVALID_KEYWORD_RETURN(
|
117
|
+
#define RAPIDJSON_INVALID_KEYWORD_RETURN(code)\
|
117
118
|
RAPIDJSON_MULTILINEMACRO_BEGIN\
|
118
|
-
context.
|
119
|
-
|
119
|
+
context.invalidCode = code;\
|
120
|
+
context.invalidKeyword = SchemaType::GetValidateErrorKeyword(code).GetString();\
|
121
|
+
RAPIDJSON_INVALID_KEYWORD_VERBOSE(context.invalidKeyword);\
|
120
122
|
return false;\
|
121
123
|
RAPIDJSON_MULTILINEMACRO_END
|
122
124
|
|
125
|
+
///////////////////////////////////////////////////////////////////////////////
|
126
|
+
// ValidateFlag
|
127
|
+
|
128
|
+
/*! \def RAPIDJSON_VALIDATE_DEFAULT_FLAGS
|
129
|
+
\ingroup RAPIDJSON_CONFIG
|
130
|
+
\brief User-defined kValidateDefaultFlags definition.
|
131
|
+
|
132
|
+
User can define this as any \c ValidateFlag combinations.
|
133
|
+
*/
|
134
|
+
#ifndef RAPIDJSON_VALIDATE_DEFAULT_FLAGS
|
135
|
+
#define RAPIDJSON_VALIDATE_DEFAULT_FLAGS kValidateNoFlags
|
136
|
+
#endif
|
137
|
+
|
138
|
+
//! Combination of validate flags
|
139
|
+
/*! \see
|
140
|
+
*/
|
141
|
+
enum ValidateFlag {
|
142
|
+
kValidateNoFlags = 0, //!< No flags are set.
|
143
|
+
kValidateContinueOnErrorFlag = 1, //!< Don't stop after first validation error.
|
144
|
+
kValidateDefaultFlags = RAPIDJSON_VALIDATE_DEFAULT_FLAGS //!< Default validate flags. Can be customized by defining RAPIDJSON_VALIDATE_DEFAULT_FLAGS
|
145
|
+
};
|
146
|
+
|
123
147
|
///////////////////////////////////////////////////////////////////////////////
|
124
148
|
// Forward declarations
|
125
149
|
|
@@ -138,6 +162,8 @@ class ISchemaValidator {
|
|
138
162
|
public:
|
139
163
|
virtual ~ISchemaValidator() {}
|
140
164
|
virtual bool IsValid() const = 0;
|
165
|
+
virtual void SetValidateFlags(unsigned flags) = 0;
|
166
|
+
virtual unsigned GetValidateFlags() const = 0;
|
141
167
|
};
|
142
168
|
|
143
169
|
///////////////////////////////////////////////////////////////////////////////
|
@@ -147,7 +173,7 @@ template <typename SchemaType>
|
|
147
173
|
class ISchemaStateFactory {
|
148
174
|
public:
|
149
175
|
virtual ~ISchemaStateFactory() {}
|
150
|
-
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType
|
176
|
+
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&, const bool inheritContinueOnErrors) = 0;
|
151
177
|
virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;
|
152
178
|
virtual void* CreateHasher() = 0;
|
153
179
|
virtual uint64_t GetHashCode(void* hasher) = 0;
|
@@ -201,13 +227,13 @@ public:
|
|
201
227
|
virtual void AddDependencySchemaError(const SValue& souceName, ISchemaValidator* subvalidator) = 0;
|
202
228
|
virtual bool EndDependencyErrors() = 0;
|
203
229
|
|
204
|
-
virtual void DisallowedValue() = 0;
|
230
|
+
virtual void DisallowedValue(const ValidateErrorCode code) = 0;
|
205
231
|
virtual void StartDisallowedType() = 0;
|
206
232
|
virtual void AddExpectedType(const typename SchemaType::ValueType& expectedType) = 0;
|
207
233
|
virtual void EndDisallowedType(const typename SchemaType::ValueType& actualType) = 0;
|
208
234
|
virtual void NotAllOf(ISchemaValidator** subvalidators, SizeType count) = 0;
|
209
235
|
virtual void NoneOf(ISchemaValidator** subvalidators, SizeType count) = 0;
|
210
|
-
virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count) = 0;
|
236
|
+
virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count, bool matched) = 0;
|
211
237
|
virtual void Disallowed() = 0;
|
212
238
|
};
|
213
239
|
|
@@ -332,6 +358,7 @@ struct SchemaValidationContext {
|
|
332
358
|
schema(s),
|
333
359
|
valueSchema(),
|
334
360
|
invalidKeyword(),
|
361
|
+
invalidCode(),
|
335
362
|
hasher(),
|
336
363
|
arrayElementHashCodes(),
|
337
364
|
validators(),
|
@@ -372,6 +399,7 @@ struct SchemaValidationContext {
|
|
372
399
|
const SchemaType* schema;
|
373
400
|
const SchemaType* valueSchema;
|
374
401
|
const Ch* invalidKeyword;
|
402
|
+
ValidateErrorCode invalidCode;
|
375
403
|
void* hasher; // Only validator access
|
376
404
|
void* arrayElementHashCodes; // Only validator access this
|
377
405
|
ISchemaValidator** validators;
|
@@ -458,7 +486,7 @@ public:
|
|
458
486
|
AddType(*itr);
|
459
487
|
}
|
460
488
|
|
461
|
-
if (const ValueType* v = GetMember(value, GetEnumString()))
|
489
|
+
if (const ValueType* v = GetMember(value, GetEnumString())) {
|
462
490
|
if (v->IsArray() && v->Size() > 0) {
|
463
491
|
enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));
|
464
492
|
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
|
@@ -470,6 +498,7 @@ public:
|
|
470
498
|
enum_[enumCount_++] = h.GetHashCode();
|
471
499
|
}
|
472
500
|
}
|
501
|
+
}
|
473
502
|
|
474
503
|
if (schemaDocument) {
|
475
504
|
AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
|
@@ -688,7 +717,11 @@ public:
|
|
688
717
|
context.valueSchema = typeless_;
|
689
718
|
else {
|
690
719
|
context.error_handler.DisallowedItem(context.arrayElementIndex);
|
691
|
-
|
720
|
+
// Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error
|
721
|
+
context.valueSchema = typeless_;
|
722
|
+
// Must bump arrayElementIndex for when kValidateContinueOnErrorFlag is set
|
723
|
+
context.arrayElementIndex++;
|
724
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalItems);
|
692
725
|
}
|
693
726
|
}
|
694
727
|
else
|
@@ -700,6 +733,7 @@ public:
|
|
700
733
|
}
|
701
734
|
|
702
735
|
RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {
|
736
|
+
// Only check pattern properties if we have validators
|
703
737
|
if (context.patternPropertiesValidatorCount > 0) {
|
704
738
|
bool otherValid = false;
|
705
739
|
SizeType count = context.patternPropertiesValidatorCount;
|
@@ -716,66 +750,70 @@ public:
|
|
716
750
|
if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
|
717
751
|
if (!patternValid) {
|
718
752
|
context.error_handler.PropertyViolations(context.patternPropertiesValidators, count);
|
719
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
753
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties);
|
720
754
|
}
|
721
755
|
}
|
722
756
|
else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
|
723
757
|
if (!patternValid || !otherValid) {
|
724
758
|
context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
|
725
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
759
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties);
|
726
760
|
}
|
727
761
|
}
|
728
762
|
else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty)
|
729
763
|
context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1);
|
730
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
764
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPatternProperties);
|
731
765
|
}
|
732
766
|
}
|
733
767
|
|
734
|
-
if
|
768
|
+
// For enums only check if we have a hasher
|
769
|
+
if (enum_ && context.hasher) {
|
735
770
|
const uint64_t h = context.factory.GetHashCode(context.hasher);
|
736
771
|
for (SizeType i = 0; i < enumCount_; i++)
|
737
772
|
if (enum_[i] == h)
|
738
773
|
goto foundEnum;
|
739
|
-
context.error_handler.DisallowedValue();
|
740
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
774
|
+
context.error_handler.DisallowedValue(kValidateErrorEnum);
|
775
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorEnum);
|
741
776
|
foundEnum:;
|
742
777
|
}
|
743
778
|
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
779
|
+
// Only check allOf etc if we have validators
|
780
|
+
if (context.validatorCount > 0) {
|
781
|
+
if (allOf_.schemas)
|
782
|
+
for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
|
783
|
+
if (!context.validators[i]->IsValid()) {
|
784
|
+
context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count);
|
785
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAllOf);
|
786
|
+
}
|
787
|
+
|
788
|
+
if (anyOf_.schemas) {
|
789
|
+
for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
|
790
|
+
if (context.validators[i]->IsValid())
|
791
|
+
goto foundAny;
|
792
|
+
context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count);
|
793
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAnyOf);
|
794
|
+
foundAny:;
|
795
|
+
}
|
796
|
+
|
797
|
+
if (oneOf_.schemas) {
|
798
|
+
bool oneValid = false;
|
799
|
+
for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
|
800
|
+
if (context.validators[i]->IsValid()) {
|
801
|
+
if (oneValid) {
|
802
|
+
context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count, true);
|
803
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOfMatch);
|
804
|
+
} else
|
805
|
+
oneValid = true;
|
806
|
+
}
|
807
|
+
if (!oneValid) {
|
808
|
+
context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count, false);
|
809
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorOneOf);
|
769
810
|
}
|
770
|
-
if (!oneValid) {
|
771
|
-
context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count);
|
772
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
|
773
811
|
}
|
774
|
-
}
|
775
812
|
|
776
|
-
|
777
|
-
|
778
|
-
|
813
|
+
if (not_ && context.validators[notValidatorIndex_]->IsValid()) {
|
814
|
+
context.error_handler.Disallowed();
|
815
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorNot);
|
816
|
+
}
|
779
817
|
}
|
780
818
|
|
781
819
|
return true;
|
@@ -784,7 +822,7 @@ public:
|
|
784
822
|
bool Null(Context& context) const {
|
785
823
|
if (!(type_ & (1 << kNullSchemaType))) {
|
786
824
|
DisallowedType(context, GetNullString());
|
787
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
825
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
788
826
|
}
|
789
827
|
return CreateParallelValidator(context);
|
790
828
|
}
|
@@ -792,7 +830,7 @@ public:
|
|
792
830
|
bool Bool(Context& context, bool) const {
|
793
831
|
if (!(type_ & (1 << kBooleanSchemaType))) {
|
794
832
|
DisallowedType(context, GetBooleanString());
|
795
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
833
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
796
834
|
}
|
797
835
|
return CreateParallelValidator(context);
|
798
836
|
}
|
@@ -824,7 +862,7 @@ public:
|
|
824
862
|
bool Double(Context& context, double d) const {
|
825
863
|
if (!(type_ & (1 << kNumberSchemaType))) {
|
826
864
|
DisallowedType(context, GetNumberString());
|
827
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
865
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
828
866
|
}
|
829
867
|
|
830
868
|
if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
|
@@ -842,7 +880,7 @@ public:
|
|
842
880
|
bool String(Context& context, const Ch* str, SizeType length, bool) const {
|
843
881
|
if (!(type_ & (1 << kStringSchemaType))) {
|
844
882
|
DisallowedType(context, GetStringString());
|
845
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
883
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
846
884
|
}
|
847
885
|
|
848
886
|
if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
|
@@ -850,18 +888,18 @@ public:
|
|
850
888
|
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
|
851
889
|
if (count < minLength_) {
|
852
890
|
context.error_handler.TooShort(str, length, minLength_);
|
853
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
891
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength);
|
854
892
|
}
|
855
893
|
if (count > maxLength_) {
|
856
894
|
context.error_handler.TooLong(str, length, maxLength_);
|
857
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
895
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength);
|
858
896
|
}
|
859
897
|
}
|
860
898
|
}
|
861
899
|
|
862
900
|
if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
|
863
901
|
context.error_handler.DoesNotMatch(str, length);
|
864
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
902
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern);
|
865
903
|
}
|
866
904
|
|
867
905
|
return CreateParallelValidator(context);
|
@@ -870,7 +908,7 @@ public:
|
|
870
908
|
bool StartObject(Context& context) const {
|
871
909
|
if (!(type_ & (1 << kObjectSchemaType))) {
|
872
910
|
DisallowedType(context, GetObjectString());
|
873
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
911
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
874
912
|
}
|
875
913
|
|
876
914
|
if (hasDependencies_ || hasRequired_) {
|
@@ -930,8 +968,10 @@ public:
|
|
930
968
|
}
|
931
969
|
|
932
970
|
if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties
|
971
|
+
// Must set valueSchema for when kValidateContinueOnErrorFlag is set, else reports spurious type error
|
972
|
+
context.valueSchema = typeless_;
|
933
973
|
context.error_handler.DisallowedProperty(str, len);
|
934
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
974
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorAdditionalProperties);
|
935
975
|
}
|
936
976
|
|
937
977
|
return true;
|
@@ -945,17 +985,17 @@ public:
|
|
945
985
|
if (properties_[index].schema->defaultValueLength_ == 0 )
|
946
986
|
context.error_handler.AddMissingProperty(properties_[index].name);
|
947
987
|
if (context.error_handler.EndMissingProperties())
|
948
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
988
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorRequired);
|
949
989
|
}
|
950
990
|
|
951
991
|
if (memberCount < minProperties_) {
|
952
992
|
context.error_handler.TooFewProperties(memberCount, minProperties_);
|
953
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
993
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinProperties);
|
954
994
|
}
|
955
995
|
|
956
996
|
if (memberCount > maxProperties_) {
|
957
997
|
context.error_handler.TooManyProperties(memberCount, maxProperties_);
|
958
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
998
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxProperties);
|
959
999
|
}
|
960
1000
|
|
961
1001
|
if (hasDependencies_) {
|
@@ -978,21 +1018,21 @@ public:
|
|
978
1018
|
}
|
979
1019
|
}
|
980
1020
|
if (context.error_handler.EndDependencyErrors())
|
981
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1021
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorDependencies);
|
982
1022
|
}
|
983
1023
|
|
984
1024
|
return true;
|
985
1025
|
}
|
986
1026
|
|
987
1027
|
bool StartArray(Context& context) const {
|
1028
|
+
context.arrayElementIndex = 0;
|
1029
|
+
context.inArray = true; // Ensure we note that we are in an array
|
1030
|
+
|
988
1031
|
if (!(type_ & (1 << kArraySchemaType))) {
|
989
1032
|
DisallowedType(context, GetArrayString());
|
990
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1033
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
991
1034
|
}
|
992
1035
|
|
993
|
-
context.arrayElementIndex = 0;
|
994
|
-
context.inArray = true;
|
995
|
-
|
996
1036
|
return CreateParallelValidator(context);
|
997
1037
|
}
|
998
1038
|
|
@@ -1001,17 +1041,55 @@ public:
|
|
1001
1041
|
|
1002
1042
|
if (elementCount < minItems_) {
|
1003
1043
|
context.error_handler.TooFewItems(elementCount, minItems_);
|
1004
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1044
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinItems);
|
1005
1045
|
}
|
1006
1046
|
|
1007
1047
|
if (elementCount > maxItems_) {
|
1008
1048
|
context.error_handler.TooManyItems(elementCount, maxItems_);
|
1009
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1049
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxItems);
|
1010
1050
|
}
|
1011
1051
|
|
1012
1052
|
return true;
|
1013
1053
|
}
|
1014
1054
|
|
1055
|
+
static const ValueType& GetValidateErrorKeyword(ValidateErrorCode validateErrorCode) {
|
1056
|
+
switch (validateErrorCode) {
|
1057
|
+
case kValidateErrorMultipleOf: return GetMultipleOfString();
|
1058
|
+
case kValidateErrorMaximum: return GetMaximumString();
|
1059
|
+
case kValidateErrorExclusiveMaximum: return GetMaximumString(); // Same
|
1060
|
+
case kValidateErrorMinimum: return GetMinimumString();
|
1061
|
+
case kValidateErrorExclusiveMinimum: return GetMinimumString(); // Same
|
1062
|
+
|
1063
|
+
case kValidateErrorMaxLength: return GetMaxLengthString();
|
1064
|
+
case kValidateErrorMinLength: return GetMinLengthString();
|
1065
|
+
case kValidateErrorPattern: return GetPatternString();
|
1066
|
+
|
1067
|
+
case kValidateErrorMaxItems: return GetMaxItemsString();
|
1068
|
+
case kValidateErrorMinItems: return GetMinItemsString();
|
1069
|
+
case kValidateErrorUniqueItems: return GetUniqueItemsString();
|
1070
|
+
case kValidateErrorAdditionalItems: return GetAdditionalItemsString();
|
1071
|
+
|
1072
|
+
case kValidateErrorMaxProperties: return GetMaxPropertiesString();
|
1073
|
+
case kValidateErrorMinProperties: return GetMinPropertiesString();
|
1074
|
+
case kValidateErrorRequired: return GetRequiredString();
|
1075
|
+
case kValidateErrorAdditionalProperties: return GetAdditionalPropertiesString();
|
1076
|
+
case kValidateErrorPatternProperties: return GetPatternPropertiesString();
|
1077
|
+
case kValidateErrorDependencies: return GetDependenciesString();
|
1078
|
+
|
1079
|
+
case kValidateErrorEnum: return GetEnumString();
|
1080
|
+
case kValidateErrorType: return GetTypeString();
|
1081
|
+
|
1082
|
+
case kValidateErrorOneOf: return GetOneOfString();
|
1083
|
+
case kValidateErrorOneOfMatch: return GetOneOfString(); // Same
|
1084
|
+
case kValidateErrorAllOf: return GetAllOfString();
|
1085
|
+
case kValidateErrorAnyOf: return GetAnyOfString();
|
1086
|
+
case kValidateErrorNot: return GetNotString();
|
1087
|
+
|
1088
|
+
default: return GetNullString();
|
1089
|
+
}
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
|
1015
1093
|
// Generate functions for string literal according to Ch
|
1016
1094
|
#define RAPIDJSON_STRING_(name, ...) \
|
1017
1095
|
static const ValueType& Get##name##String() {\
|
@@ -1190,31 +1268,32 @@ private:
|
|
1190
1268
|
context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));
|
1191
1269
|
context.validatorCount = validatorCount_;
|
1192
1270
|
|
1271
|
+
// Always return after first failure for these sub-validators
|
1193
1272
|
if (allOf_.schemas)
|
1194
|
-
CreateSchemaValidators(context, allOf_);
|
1273
|
+
CreateSchemaValidators(context, allOf_, false);
|
1195
1274
|
|
1196
1275
|
if (anyOf_.schemas)
|
1197
|
-
CreateSchemaValidators(context, anyOf_);
|
1276
|
+
CreateSchemaValidators(context, anyOf_, false);
|
1198
1277
|
|
1199
1278
|
if (oneOf_.schemas)
|
1200
|
-
CreateSchemaValidators(context, oneOf_);
|
1279
|
+
CreateSchemaValidators(context, oneOf_, false);
|
1201
1280
|
|
1202
1281
|
if (not_)
|
1203
|
-
context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_);
|
1204
|
-
|
1282
|
+
context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_, false);
|
1283
|
+
|
1205
1284
|
if (hasSchemaDependencies_) {
|
1206
1285
|
for (SizeType i = 0; i < propertyCount_; i++)
|
1207
1286
|
if (properties_[i].dependenciesSchema)
|
1208
|
-
context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);
|
1287
|
+
context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema, false);
|
1209
1288
|
}
|
1210
1289
|
}
|
1211
1290
|
|
1212
1291
|
return true;
|
1213
1292
|
}
|
1214
1293
|
|
1215
|
-
void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {
|
1294
|
+
void CreateSchemaValidators(Context& context, const SchemaArray& schemas, const bool inheritContinueOnErrors) const {
|
1216
1295
|
for (SizeType i = 0; i < schemas.count; i++)
|
1217
|
-
context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);
|
1296
|
+
context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i], inheritContinueOnErrors);
|
1218
1297
|
}
|
1219
1298
|
|
1220
1299
|
// O(n)
|
@@ -1234,19 +1313,19 @@ private:
|
|
1234
1313
|
bool CheckInt(Context& context, int64_t i) const {
|
1235
1314
|
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
|
1236
1315
|
DisallowedType(context, GetIntegerString());
|
1237
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1316
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
1238
1317
|
}
|
1239
1318
|
|
1240
1319
|
if (!minimum_.IsNull()) {
|
1241
1320
|
if (minimum_.IsInt64()) {
|
1242
1321
|
if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) {
|
1243
1322
|
context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
|
1244
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1323
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum);
|
1245
1324
|
}
|
1246
1325
|
}
|
1247
1326
|
else if (minimum_.IsUint64()) {
|
1248
1327
|
context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
|
1249
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1328
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum); // i <= max(int64_t) < minimum.GetUint64()
|
1250
1329
|
}
|
1251
1330
|
else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
|
1252
1331
|
return false;
|
@@ -1256,7 +1335,7 @@ private:
|
|
1256
1335
|
if (maximum_.IsInt64()) {
|
1257
1336
|
if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) {
|
1258
1337
|
context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
|
1259
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1338
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum);
|
1260
1339
|
}
|
1261
1340
|
}
|
1262
1341
|
else if (maximum_.IsUint64()) { }
|
@@ -1269,7 +1348,7 @@ private:
|
|
1269
1348
|
if (multipleOf_.IsUint64()) {
|
1270
1349
|
if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) {
|
1271
1350
|
context.error_handler.NotMultipleOf(i, multipleOf_);
|
1272
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1351
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf);
|
1273
1352
|
}
|
1274
1353
|
}
|
1275
1354
|
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
|
@@ -1282,14 +1361,14 @@ private:
|
|
1282
1361
|
bool CheckUint(Context& context, uint64_t i) const {
|
1283
1362
|
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) {
|
1284
1363
|
DisallowedType(context, GetIntegerString());
|
1285
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1364
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
|
1286
1365
|
}
|
1287
1366
|
|
1288
1367
|
if (!minimum_.IsNull()) {
|
1289
1368
|
if (minimum_.IsUint64()) {
|
1290
1369
|
if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) {
|
1291
1370
|
context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_);
|
1292
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1371
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum);
|
1293
1372
|
}
|
1294
1373
|
}
|
1295
1374
|
else if (minimum_.IsInt64())
|
@@ -1302,12 +1381,12 @@ private:
|
|
1302
1381
|
if (maximum_.IsUint64()) {
|
1303
1382
|
if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) {
|
1304
1383
|
context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
|
1305
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1384
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum);
|
1306
1385
|
}
|
1307
1386
|
}
|
1308
1387
|
else if (maximum_.IsInt64()) {
|
1309
1388
|
context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_);
|
1310
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1389
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum); // i >= 0 > maximum_
|
1311
1390
|
}
|
1312
1391
|
else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
|
1313
1392
|
return false;
|
@@ -1317,7 +1396,7 @@ private:
|
|
1317
1396
|
if (multipleOf_.IsUint64()) {
|
1318
1397
|
if (i % multipleOf_.GetUint64() != 0) {
|
1319
1398
|
context.error_handler.NotMultipleOf(i, multipleOf_);
|
1320
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1399
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf);
|
1321
1400
|
}
|
1322
1401
|
}
|
1323
1402
|
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
|
@@ -1330,7 +1409,7 @@ private:
|
|
1330
1409
|
bool CheckDoubleMinimum(Context& context, double d) const {
|
1331
1410
|
if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) {
|
1332
1411
|
context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_);
|
1333
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1412
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMinimum_ ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum);
|
1334
1413
|
}
|
1335
1414
|
return true;
|
1336
1415
|
}
|
@@ -1338,7 +1417,7 @@ private:
|
|
1338
1417
|
bool CheckDoubleMaximum(Context& context, double d) const {
|
1339
1418
|
if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) {
|
1340
1419
|
context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_);
|
1341
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1420
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(exclusiveMaximum_ ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum);
|
1342
1421
|
}
|
1343
1422
|
return true;
|
1344
1423
|
}
|
@@ -1349,7 +1428,7 @@ private:
|
|
1349
1428
|
double r = a - q * b;
|
1350
1429
|
if (r > 0.0) {
|
1351
1430
|
context.error_handler.NotMultipleOf(d, multipleOf_);
|
1352
|
-
RAPIDJSON_INVALID_KEYWORD_RETURN(
|
1431
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMultipleOf);
|
1353
1432
|
}
|
1354
1433
|
return true;
|
1355
1434
|
}
|
@@ -1763,8 +1842,7 @@ template <
|
|
1763
1842
|
class GenericSchemaValidator :
|
1764
1843
|
public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
|
1765
1844
|
public internal::ISchemaValidator,
|
1766
|
-
public internal::IValidationErrorHandler<typename SchemaDocumentType::SchemaType>
|
1767
|
-
{
|
1845
|
+
public internal::IValidationErrorHandler<typename SchemaDocumentType::SchemaType> {
|
1768
1846
|
public:
|
1769
1847
|
typedef typename SchemaDocumentType::SchemaType SchemaType;
|
1770
1848
|
typedef typename SchemaDocumentType::PointerType PointerType;
|
@@ -1797,7 +1875,8 @@ public:
|
|
1797
1875
|
error_(kObjectType),
|
1798
1876
|
currentError_(),
|
1799
1877
|
missingDependents_(),
|
1800
|
-
valid_(true)
|
1878
|
+
valid_(true),
|
1879
|
+
flags_(kValidateDefaultFlags)
|
1801
1880
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
1802
1881
|
, depth_(0)
|
1803
1882
|
#endif
|
@@ -1828,7 +1907,8 @@ public:
|
|
1828
1907
|
error_(kObjectType),
|
1829
1908
|
currentError_(),
|
1830
1909
|
missingDependents_(),
|
1831
|
-
valid_(true)
|
1910
|
+
valid_(true),
|
1911
|
+
flags_(kValidateDefaultFlags)
|
1832
1912
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
1833
1913
|
, depth_(0)
|
1834
1914
|
#endif
|
@@ -1846,31 +1926,61 @@ public:
|
|
1846
1926
|
while (!schemaStack_.Empty())
|
1847
1927
|
PopSchema();
|
1848
1928
|
documentStack_.Clear();
|
1929
|
+
ResetError();
|
1930
|
+
}
|
1931
|
+
|
1932
|
+
//! Reset the error state.
|
1933
|
+
void ResetError() {
|
1849
1934
|
error_.SetObject();
|
1850
1935
|
currentError_.SetNull();
|
1851
1936
|
missingDependents_.SetNull();
|
1852
1937
|
valid_ = true;
|
1853
1938
|
}
|
1854
1939
|
|
1940
|
+
//! Implementation of ISchemaValidator
|
1941
|
+
void SetValidateFlags(unsigned flags) {
|
1942
|
+
flags_ = flags;
|
1943
|
+
}
|
1944
|
+
virtual unsigned GetValidateFlags() const {
|
1945
|
+
return flags_;
|
1946
|
+
}
|
1947
|
+
|
1855
1948
|
//! Checks whether the current state is valid.
|
1856
1949
|
// Implementation of ISchemaValidator
|
1857
|
-
virtual bool IsValid() const {
|
1950
|
+
virtual bool IsValid() const {
|
1951
|
+
if (!valid_) return false;
|
1952
|
+
if (GetContinueOnErrors() && !error_.ObjectEmpty()) return false;
|
1953
|
+
return true;
|
1954
|
+
}
|
1858
1955
|
|
1859
1956
|
//! Gets the error object.
|
1860
1957
|
ValueType& GetError() { return error_; }
|
1861
1958
|
const ValueType& GetError() const { return error_; }
|
1862
1959
|
|
1863
1960
|
//! Gets the JSON pointer pointed to the invalid schema.
|
1961
|
+
// If reporting all errors, the stack will be empty.
|
1864
1962
|
PointerType GetInvalidSchemaPointer() const {
|
1865
1963
|
return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer();
|
1866
1964
|
}
|
1867
1965
|
|
1868
1966
|
//! Gets the keyword of invalid schema.
|
1967
|
+
// If reporting all errors, the stack will be empty, so return "errors".
|
1869
1968
|
const Ch* GetInvalidSchemaKeyword() const {
|
1870
|
-
|
1969
|
+
if (!schemaStack_.Empty()) return CurrentContext().invalidKeyword;
|
1970
|
+
if (GetContinueOnErrors() && !error_.ObjectEmpty()) return (const Ch*)GetErrorsString();
|
1971
|
+
return 0;
|
1972
|
+
}
|
1973
|
+
|
1974
|
+
//! Gets the error code of invalid schema.
|
1975
|
+
// If reporting all errors, the stack will be empty, so return kValidateErrors.
|
1976
|
+
ValidateErrorCode GetInvalidSchemaCode() const {
|
1977
|
+
if (!schemaStack_.Empty()) return CurrentContext().invalidCode;
|
1978
|
+
if (GetContinueOnErrors() && !error_.ObjectEmpty()) return kValidateErrors;
|
1979
|
+
return kValidateErrorNone;
|
1871
1980
|
}
|
1872
1981
|
|
1873
1982
|
//! Gets the JSON pointer pointed to the invalid value.
|
1983
|
+
// If reporting all errors, the stack will be empty.
|
1874
1984
|
PointerType GetInvalidDocumentPointer() const {
|
1875
1985
|
if (documentStack_.Empty()) {
|
1876
1986
|
return PointerType();
|
@@ -1881,64 +1991,64 @@ public:
|
|
1881
1991
|
}
|
1882
1992
|
|
1883
1993
|
void NotMultipleOf(int64_t actual, const SValue& expected) {
|
1884
|
-
AddNumberError(
|
1994
|
+
AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected);
|
1885
1995
|
}
|
1886
1996
|
void NotMultipleOf(uint64_t actual, const SValue& expected) {
|
1887
|
-
AddNumberError(
|
1997
|
+
AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected);
|
1888
1998
|
}
|
1889
1999
|
void NotMultipleOf(double actual, const SValue& expected) {
|
1890
|
-
AddNumberError(
|
2000
|
+
AddNumberError(kValidateErrorMultipleOf, ValueType(actual).Move(), expected);
|
1891
2001
|
}
|
1892
2002
|
void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) {
|
1893
|
-
AddNumberError(
|
2003
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected,
|
1894
2004
|
exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
|
1895
2005
|
}
|
1896
2006
|
void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) {
|
1897
|
-
AddNumberError(
|
2007
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected,
|
1898
2008
|
exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
|
1899
2009
|
}
|
1900
2010
|
void AboveMaximum(double actual, const SValue& expected, bool exclusive) {
|
1901
|
-
AddNumberError(
|
2011
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMaximum : kValidateErrorMaximum, ValueType(actual).Move(), expected,
|
1902
2012
|
exclusive ? &SchemaType::GetExclusiveMaximumString : 0);
|
1903
2013
|
}
|
1904
2014
|
void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) {
|
1905
|
-
AddNumberError(
|
2015
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected,
|
1906
2016
|
exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
|
1907
2017
|
}
|
1908
2018
|
void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) {
|
1909
|
-
AddNumberError(
|
2019
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected,
|
1910
2020
|
exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
|
1911
2021
|
}
|
1912
2022
|
void BelowMinimum(double actual, const SValue& expected, bool exclusive) {
|
1913
|
-
AddNumberError(
|
2023
|
+
AddNumberError(exclusive ? kValidateErrorExclusiveMinimum : kValidateErrorMinimum, ValueType(actual).Move(), expected,
|
1914
2024
|
exclusive ? &SchemaType::GetExclusiveMinimumString : 0);
|
1915
2025
|
}
|
1916
2026
|
|
1917
2027
|
void TooLong(const Ch* str, SizeType length, SizeType expected) {
|
1918
|
-
AddNumberError(
|
2028
|
+
AddNumberError(kValidateErrorMaxLength,
|
1919
2029
|
ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
|
1920
2030
|
}
|
1921
2031
|
void TooShort(const Ch* str, SizeType length, SizeType expected) {
|
1922
|
-
AddNumberError(
|
2032
|
+
AddNumberError(kValidateErrorMinLength,
|
1923
2033
|
ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move());
|
1924
2034
|
}
|
1925
2035
|
void DoesNotMatch(const Ch* str, SizeType length) {
|
1926
2036
|
currentError_.SetObject();
|
1927
2037
|
currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator());
|
1928
|
-
AddCurrentError(
|
2038
|
+
AddCurrentError(kValidateErrorPattern);
|
1929
2039
|
}
|
1930
2040
|
|
1931
2041
|
void DisallowedItem(SizeType index) {
|
1932
2042
|
currentError_.SetObject();
|
1933
2043
|
currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator());
|
1934
|
-
AddCurrentError(
|
2044
|
+
AddCurrentError(kValidateErrorAdditionalItems, true);
|
1935
2045
|
}
|
1936
2046
|
void TooFewItems(SizeType actualCount, SizeType expectedCount) {
|
1937
|
-
AddNumberError(
|
2047
|
+
AddNumberError(kValidateErrorMinItems,
|
1938
2048
|
ValueType(actualCount).Move(), SValue(expectedCount).Move());
|
1939
2049
|
}
|
1940
2050
|
void TooManyItems(SizeType actualCount, SizeType expectedCount) {
|
1941
|
-
AddNumberError(
|
2051
|
+
AddNumberError(kValidateErrorMaxItems,
|
1942
2052
|
ValueType(actualCount).Move(), SValue(expectedCount).Move());
|
1943
2053
|
}
|
1944
2054
|
void DuplicateItems(SizeType index1, SizeType index2) {
|
@@ -1947,15 +2057,15 @@ public:
|
|
1947
2057
|
duplicates.PushBack(index2, GetStateAllocator());
|
1948
2058
|
currentError_.SetObject();
|
1949
2059
|
currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator());
|
1950
|
-
AddCurrentError(
|
2060
|
+
AddCurrentError(kValidateErrorUniqueItems, true);
|
1951
2061
|
}
|
1952
2062
|
|
1953
2063
|
void TooManyProperties(SizeType actualCount, SizeType expectedCount) {
|
1954
|
-
AddNumberError(
|
2064
|
+
AddNumberError(kValidateErrorMaxProperties,
|
1955
2065
|
ValueType(actualCount).Move(), SValue(expectedCount).Move());
|
1956
2066
|
}
|
1957
2067
|
void TooFewProperties(SizeType actualCount, SizeType expectedCount) {
|
1958
|
-
AddNumberError(
|
2068
|
+
AddNumberError(kValidateErrorMinProperties,
|
1959
2069
|
ValueType(actualCount).Move(), SValue(expectedCount).Move());
|
1960
2070
|
}
|
1961
2071
|
void StartMissingProperties() {
|
@@ -1970,7 +2080,7 @@ public:
|
|
1970
2080
|
ValueType error(kObjectType);
|
1971
2081
|
error.AddMember(GetMissingString(), currentError_, GetStateAllocator());
|
1972
2082
|
currentError_ = error;
|
1973
|
-
AddCurrentError(
|
2083
|
+
AddCurrentError(kValidateErrorRequired);
|
1974
2084
|
return true;
|
1975
2085
|
}
|
1976
2086
|
void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) {
|
@@ -1980,7 +2090,7 @@ public:
|
|
1980
2090
|
void DisallowedProperty(const Ch* name, SizeType length) {
|
1981
2091
|
currentError_.SetObject();
|
1982
2092
|
currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator());
|
1983
|
-
AddCurrentError(
|
2093
|
+
AddCurrentError(kValidateErrorAdditionalProperties, true);
|
1984
2094
|
}
|
1985
2095
|
|
1986
2096
|
void StartDependencyErrors() {
|
@@ -1993,9 +2103,20 @@ public:
|
|
1993
2103
|
missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator());
|
1994
2104
|
}
|
1995
2105
|
void EndMissingDependentProperties(const SValue& sourceName) {
|
1996
|
-
if (!missingDependents_.Empty())
|
1997
|
-
|
1998
|
-
|
2106
|
+
if (!missingDependents_.Empty()) {
|
2107
|
+
// Create equivalent 'required' error
|
2108
|
+
ValueType error(kObjectType);
|
2109
|
+
ValidateErrorCode code = kValidateErrorRequired;
|
2110
|
+
error.AddMember(GetMissingString(), missingDependents_.Move(), GetStateAllocator());
|
2111
|
+
AddErrorCode(error, code);
|
2112
|
+
AddErrorInstanceLocation(error, false);
|
2113
|
+
// When appending to a pointer ensure its allocator is used
|
2114
|
+
PointerType schemaRef = GetInvalidSchemaPointer().Append(SchemaType::GetValidateErrorKeyword(kValidateErrorDependencies), &GetInvalidSchemaPointer().GetAllocator());
|
2115
|
+
AddErrorSchemaLocation(error, schemaRef.Append(sourceName.GetString(), sourceName.GetStringLength(), &GetInvalidSchemaPointer().GetAllocator()));
|
2116
|
+
ValueType wrapper(kObjectType);
|
2117
|
+
wrapper.AddMember(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator()).Move(), error, GetStateAllocator());
|
2118
|
+
currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), wrapper, GetStateAllocator());
|
2119
|
+
}
|
1999
2120
|
}
|
2000
2121
|
void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) {
|
2001
2122
|
currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(),
|
@@ -2007,13 +2128,13 @@ public:
|
|
2007
2128
|
ValueType error(kObjectType);
|
2008
2129
|
error.AddMember(GetErrorsString(), currentError_, GetStateAllocator());
|
2009
2130
|
currentError_ = error;
|
2010
|
-
AddCurrentError(
|
2131
|
+
AddCurrentError(kValidateErrorDependencies);
|
2011
2132
|
return true;
|
2012
2133
|
}
|
2013
2134
|
|
2014
|
-
void DisallowedValue() {
|
2135
|
+
void DisallowedValue(const ValidateErrorCode code = kValidateErrorEnum) {
|
2015
2136
|
currentError_.SetObject();
|
2016
|
-
AddCurrentError(
|
2137
|
+
AddCurrentError(code);
|
2017
2138
|
}
|
2018
2139
|
void StartDisallowedType() {
|
2019
2140
|
currentError_.SetArray();
|
@@ -2026,22 +2147,24 @@ public:
|
|
2026
2147
|
error.AddMember(GetExpectedString(), currentError_, GetStateAllocator());
|
2027
2148
|
error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator());
|
2028
2149
|
currentError_ = error;
|
2029
|
-
AddCurrentError(
|
2150
|
+
AddCurrentError(kValidateErrorType);
|
2030
2151
|
}
|
2031
2152
|
void NotAllOf(ISchemaValidator** subvalidators, SizeType count) {
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2153
|
+
// Treat allOf like oneOf and anyOf to match https://rapidjson.org/md_doc_schema.html#allOf-anyOf-oneOf
|
2154
|
+
AddErrorArray(kValidateErrorAllOf, subvalidators, count);
|
2155
|
+
//for (SizeType i = 0; i < count; ++i) {
|
2156
|
+
// MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
|
2157
|
+
//}
|
2035
2158
|
}
|
2036
2159
|
void NoneOf(ISchemaValidator** subvalidators, SizeType count) {
|
2037
|
-
AddErrorArray(
|
2160
|
+
AddErrorArray(kValidateErrorAnyOf, subvalidators, count);
|
2038
2161
|
}
|
2039
|
-
void NotOneOf(ISchemaValidator** subvalidators, SizeType count) {
|
2040
|
-
AddErrorArray(
|
2162
|
+
void NotOneOf(ISchemaValidator** subvalidators, SizeType count, bool matched = false) {
|
2163
|
+
AddErrorArray(matched ? kValidateErrorOneOfMatch : kValidateErrorOneOf, subvalidators, count);
|
2041
2164
|
}
|
2042
2165
|
void Disallowed() {
|
2043
2166
|
currentError_.SetObject();
|
2044
|
-
AddCurrentError(
|
2167
|
+
AddCurrentError(kValidateErrorNot);
|
2045
2168
|
}
|
2046
2169
|
|
2047
2170
|
#define RAPIDJSON_STRING_(name, ...) \
|
@@ -2058,6 +2181,8 @@ public:
|
|
2058
2181
|
RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd')
|
2059
2182
|
RAPIDJSON_STRING_(Missing, 'm', 'i', 's', 's', 'i', 'n', 'g')
|
2060
2183
|
RAPIDJSON_STRING_(Errors, 'e', 'r', 'r', 'o', 'r', 's')
|
2184
|
+
RAPIDJSON_STRING_(ErrorCode, 'e', 'r', 'r', 'o', 'r', 'C', 'o', 'd', 'e')
|
2185
|
+
RAPIDJSON_STRING_(ErrorMessage, 'e', 'r', 'r', 'o', 'r', 'M', 'e', 's', 's', 'a', 'g', 'e')
|
2061
2186
|
RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's')
|
2062
2187
|
|
2063
2188
|
#undef RAPIDJSON_STRING_
|
@@ -2075,7 +2200,7 @@ RAPIDJSON_MULTILINEMACRO_END
|
|
2075
2200
|
|
2076
2201
|
#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
|
2077
2202
|
if (!valid_) return false; \
|
2078
|
-
if (!BeginValue() || !CurrentSchema().method arg1) {\
|
2203
|
+
if ((!BeginValue() && !GetContinueOnErrors()) || (!CurrentSchema().method arg1 && !GetContinueOnErrors())) {\
|
2079
2204
|
RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\
|
2080
2205
|
return valid_ = false;\
|
2081
2206
|
}
|
@@ -2093,7 +2218,8 @@ RAPIDJSON_MULTILINEMACRO_END
|
|
2093
2218
|
}
|
2094
2219
|
|
2095
2220
|
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
|
2096
|
-
|
2221
|
+
valid_ = (EndValue() || GetContinueOnErrors()) && (!outputHandler_ || outputHandler_->method arg2);\
|
2222
|
+
return valid_;
|
2097
2223
|
|
2098
2224
|
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
|
2099
2225
|
RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
|
@@ -2121,15 +2247,15 @@ RAPIDJSON_MULTILINEMACRO_END
|
|
2121
2247
|
bool Key(const Ch* str, SizeType len, bool copy) {
|
2122
2248
|
if (!valid_) return false;
|
2123
2249
|
AppendToken(str, len);
|
2124
|
-
if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
|
2250
|
+
if (!CurrentSchema().Key(CurrentContext(), str, len, copy) && !GetContinueOnErrors()) return valid_ = false;
|
2125
2251
|
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));
|
2126
2252
|
return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
|
2127
2253
|
}
|
2128
2254
|
|
2129
|
-
bool EndObject(SizeType memberCount) {
|
2255
|
+
bool EndObject(SizeType memberCount) {
|
2130
2256
|
if (!valid_) return false;
|
2131
2257
|
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));
|
2132
|
-
if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;
|
2258
|
+
if (!CurrentSchema().EndObject(CurrentContext(), memberCount) && !GetContinueOnErrors()) return valid_ = false;
|
2133
2259
|
RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));
|
2134
2260
|
}
|
2135
2261
|
|
@@ -2142,7 +2268,7 @@ RAPIDJSON_MULTILINEMACRO_END
|
|
2142
2268
|
bool EndArray(SizeType elementCount) {
|
2143
2269
|
if (!valid_) return false;
|
2144
2270
|
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));
|
2145
|
-
if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;
|
2271
|
+
if (!CurrentSchema().EndArray(CurrentContext(), elementCount) && !GetContinueOnErrors()) return valid_ = false;
|
2146
2272
|
RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));
|
2147
2273
|
}
|
2148
2274
|
|
@@ -2152,12 +2278,14 @@ RAPIDJSON_MULTILINEMACRO_END
|
|
2152
2278
|
#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
|
2153
2279
|
|
2154
2280
|
// Implementation of ISchemaStateFactory<SchemaType>
|
2155
|
-
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
|
2156
|
-
|
2281
|
+
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root, const bool inheritContinueOnErrors) {
|
2282
|
+
ISchemaValidator* sv = new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom<char>(), documentStack_.GetSize(),
|
2157
2283
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
2158
2284
|
depth_ + 1,
|
2159
2285
|
#endif
|
2160
2286
|
&GetStateAllocator());
|
2287
|
+
sv->SetValidateFlags(inheritContinueOnErrors ? GetValidateFlags() : GetValidateFlags() & ~(unsigned)kValidateContinueOnErrorFlag);
|
2288
|
+
return sv;
|
2161
2289
|
}
|
2162
2290
|
|
2163
2291
|
virtual void DestroySchemaValidator(ISchemaValidator* validator) {
|
@@ -2214,7 +2342,8 @@ private:
|
|
2214
2342
|
error_(kObjectType),
|
2215
2343
|
currentError_(),
|
2216
2344
|
missingDependents_(),
|
2217
|
-
valid_(true)
|
2345
|
+
valid_(true),
|
2346
|
+
flags_(kValidateDefaultFlags)
|
2218
2347
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
2219
2348
|
, depth_(depth)
|
2220
2349
|
#endif
|
@@ -2229,6 +2358,10 @@ private:
|
|
2229
2358
|
return *stateAllocator_;
|
2230
2359
|
}
|
2231
2360
|
|
2361
|
+
bool GetContinueOnErrors() const {
|
2362
|
+
return flags_ & kValidateContinueOnErrorFlag;
|
2363
|
+
}
|
2364
|
+
|
2232
2365
|
bool BeginValue() {
|
2233
2366
|
if (schemaStack_.Empty())
|
2234
2367
|
PushSchema(root_);
|
@@ -2236,7 +2369,7 @@ private:
|
|
2236
2369
|
if (CurrentContext().inArray)
|
2237
2370
|
internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);
|
2238
2371
|
|
2239
|
-
if (!CurrentSchema().BeginValue(CurrentContext()))
|
2372
|
+
if (!CurrentSchema().BeginValue(CurrentContext()) && !GetContinueOnErrors())
|
2240
2373
|
return false;
|
2241
2374
|
|
2242
2375
|
SizeType count = CurrentContext().patternPropertiesSchemaCount;
|
@@ -2252,7 +2385,7 @@ private:
|
|
2252
2385
|
SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
|
2253
2386
|
va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));
|
2254
2387
|
for (SizeType i = 0; i < count; i++)
|
2255
|
-
va[validatorCount++] = CreateSchemaValidator(*sa[i]);
|
2388
|
+
va[validatorCount++] = CreateSchemaValidator(*sa[i], true); // Inherit continueOnError
|
2256
2389
|
}
|
2257
2390
|
|
2258
2391
|
CurrentContext().arrayUniqueness = valueUniqueness;
|
@@ -2261,7 +2394,7 @@ private:
|
|
2261
2394
|
}
|
2262
2395
|
|
2263
2396
|
bool EndValue() {
|
2264
|
-
if (!CurrentSchema().EndValue(CurrentContext()))
|
2397
|
+
if (!CurrentSchema().EndValue(CurrentContext()) && !GetContinueOnErrors())
|
2265
2398
|
return false;
|
2266
2399
|
|
2267
2400
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
@@ -2272,21 +2405,27 @@ private:
|
|
2272
2405
|
documentStack_.template Pop<Ch>(1);
|
2273
2406
|
internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());
|
2274
2407
|
#endif
|
2275
|
-
|
2276
|
-
uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(
|
2408
|
+
void* hasher = CurrentContext().hasher;
|
2409
|
+
uint64_t h = hasher && CurrentContext().arrayUniqueness ? static_cast<HasherType*>(hasher)->GetHashCode() : 0;
|
2277
2410
|
|
2278
2411
|
PopSchema();
|
2279
2412
|
|
2280
2413
|
if (!schemaStack_.Empty()) {
|
2281
2414
|
Context& context = CurrentContext();
|
2282
|
-
if
|
2415
|
+
// Only check uniqueness if there is a hasher
|
2416
|
+
if (hasher && context.valueUniqueness) {
|
2283
2417
|
HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);
|
2284
2418
|
if (!a)
|
2285
2419
|
CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);
|
2286
2420
|
for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)
|
2287
2421
|
if (itr->GetUint64() == h) {
|
2288
2422
|
DuplicateItems(static_cast<SizeType>(itr - a->Begin()), a->Size());
|
2289
|
-
|
2423
|
+
// Cleanup before returning if continuing
|
2424
|
+
if (GetContinueOnErrors()) {
|
2425
|
+
a->PushBack(h, GetStateAllocator());
|
2426
|
+
while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/');
|
2427
|
+
}
|
2428
|
+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorUniqueItems);
|
2290
2429
|
}
|
2291
2430
|
a->PushBack(h, GetStateAllocator());
|
2292
2431
|
}
|
@@ -2327,25 +2466,32 @@ private:
|
|
2327
2466
|
c->~Context();
|
2328
2467
|
}
|
2329
2468
|
|
2330
|
-
void
|
2469
|
+
void AddErrorInstanceLocation(ValueType& result, bool parent) {
|
2331
2470
|
GenericStringBuffer<EncodingType> sb;
|
2332
2471
|
PointerType instancePointer = GetInvalidDocumentPointer();
|
2333
2472
|
((parent && instancePointer.GetTokenCount() > 0)
|
2334
|
-
|
2335
|
-
|
2473
|
+
? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1)
|
2474
|
+
: instancePointer).StringifyUriFragment(sb);
|
2336
2475
|
ValueType instanceRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
2337
|
-
|
2476
|
+
GetStateAllocator());
|
2338
2477
|
result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator());
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2478
|
+
}
|
2479
|
+
|
2480
|
+
void AddErrorSchemaLocation(ValueType& result, PointerType schema = PointerType()) {
|
2481
|
+
GenericStringBuffer<EncodingType> sb;
|
2482
|
+
SizeType len = CurrentSchema().GetURI().GetStringLength();
|
2483
|
+
if (len) memcpy(sb.Push(len), CurrentSchema().GetURI().GetString(), len * sizeof(Ch));
|
2484
|
+
if (schema.GetTokenCount()) schema.StringifyUriFragment(sb);
|
2485
|
+
else GetInvalidSchemaPointer().StringifyUriFragment(sb);
|
2344
2486
|
ValueType schemaRef(sb.GetString(), static_cast<SizeType>(sb.GetSize() / sizeof(Ch)),
|
2345
2487
|
GetStateAllocator());
|
2346
2488
|
result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator());
|
2347
2489
|
}
|
2348
2490
|
|
2491
|
+
void AddErrorCode(ValueType& result, const ValidateErrorCode code) {
|
2492
|
+
result.AddMember(GetErrorCodeString(), code, GetStateAllocator());
|
2493
|
+
}
|
2494
|
+
|
2349
2495
|
void AddError(ValueType& keyword, ValueType& error) {
|
2350
2496
|
typename ValueType::MemberIterator member = error_.FindMember(keyword);
|
2351
2497
|
if (member == error_.MemberEnd())
|
@@ -2360,9 +2506,11 @@ private:
|
|
2360
2506
|
}
|
2361
2507
|
}
|
2362
2508
|
|
2363
|
-
void AddCurrentError(const
|
2364
|
-
|
2365
|
-
|
2509
|
+
void AddCurrentError(const ValidateErrorCode code, bool parent = false) {
|
2510
|
+
AddErrorCode(currentError_, code);
|
2511
|
+
AddErrorInstanceLocation(currentError_, parent);
|
2512
|
+
AddErrorSchemaLocation(currentError_);
|
2513
|
+
AddError(ValueType(SchemaType::GetValidateErrorKeyword(code), GetStateAllocator(), false).Move(), currentError_);
|
2366
2514
|
}
|
2367
2515
|
|
2368
2516
|
void MergeError(ValueType& other) {
|
@@ -2371,24 +2519,24 @@ private:
|
|
2371
2519
|
}
|
2372
2520
|
}
|
2373
2521
|
|
2374
|
-
void AddNumberError(const
|
2522
|
+
void AddNumberError(const ValidateErrorCode code, ValueType& actual, const SValue& expected,
|
2375
2523
|
const typename SchemaType::ValueType& (*exclusive)() = 0) {
|
2376
2524
|
currentError_.SetObject();
|
2377
2525
|
currentError_.AddMember(GetActualString(), actual, GetStateAllocator());
|
2378
2526
|
currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator());
|
2379
2527
|
if (exclusive)
|
2380
2528
|
currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(), true, GetStateAllocator());
|
2381
|
-
AddCurrentError(
|
2529
|
+
AddCurrentError(code);
|
2382
2530
|
}
|
2383
2531
|
|
2384
|
-
void AddErrorArray(const
|
2532
|
+
void AddErrorArray(const ValidateErrorCode code,
|
2385
2533
|
ISchemaValidator** subvalidators, SizeType count) {
|
2386
2534
|
ValueType errors(kArrayType);
|
2387
2535
|
for (SizeType i = 0; i < count; ++i)
|
2388
2536
|
errors.PushBack(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError(), GetStateAllocator());
|
2389
2537
|
currentError_.SetObject();
|
2390
2538
|
currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator());
|
2391
|
-
AddCurrentError(
|
2539
|
+
AddCurrentError(code);
|
2392
2540
|
}
|
2393
2541
|
|
2394
2542
|
const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }
|
@@ -2408,6 +2556,7 @@ private:
|
|
2408
2556
|
ValueType currentError_;
|
2409
2557
|
ValueType missingDependents_;
|
2410
2558
|
bool valid_;
|
2559
|
+
unsigned flags_;
|
2411
2560
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
2412
2561
|
unsigned depth_;
|
2413
2562
|
#endif
|
@@ -2445,7 +2594,7 @@ public:
|
|
2445
2594
|
\param is Input stream.
|
2446
2595
|
\param sd Schema document.
|
2447
2596
|
*/
|
2448
|
-
SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), error_(kObjectType), isValid_(true) {}
|
2597
|
+
SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), invalidSchemaCode_(kValidateErrorNone), error_(kObjectType), isValid_(true) {}
|
2449
2598
|
|
2450
2599
|
template <typename Handler>
|
2451
2600
|
bool operator()(Handler& handler) {
|
@@ -2463,6 +2612,7 @@ public:
|
|
2463
2612
|
else {
|
2464
2613
|
invalidSchemaPointer_ = validator.GetInvalidSchemaPointer();
|
2465
2614
|
invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword();
|
2615
|
+
invalidSchemaCode_ = validator.GetInvalidSchemaCode();
|
2466
2616
|
invalidDocumentPointer_ = validator.GetInvalidDocumentPointer();
|
2467
2617
|
error_.CopyFrom(validator.GetError(), allocator_);
|
2468
2618
|
}
|
@@ -2476,6 +2626,7 @@ public:
|
|
2476
2626
|
const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }
|
2477
2627
|
const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; }
|
2478
2628
|
const ValueType& GetError() const { return error_; }
|
2629
|
+
ValidateErrorCode GetInvalidSchemaCode() const { return invalidSchemaCode_; }
|
2479
2630
|
|
2480
2631
|
private:
|
2481
2632
|
InputStream& is_;
|
@@ -2485,6 +2636,7 @@ private:
|
|
2485
2636
|
PointerType invalidSchemaPointer_;
|
2486
2637
|
const Ch* invalidSchemaKeyword_;
|
2487
2638
|
PointerType invalidDocumentPointer_;
|
2639
|
+
ValidateErrorCode invalidSchemaCode_;
|
2488
2640
|
StackAllocator allocator_;
|
2489
2641
|
ValueType error_;
|
2490
2642
|
bool isValid_;
|