mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
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
This commit is contained in:
parent
6e7ab511db
commit
11e98042f4
|
@ -1,4 +1,4 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
|
||||
if(POLICY CMP0025)
|
||||
# detect Apple's Clang
|
||||
cmake_policy(SET CMP0025 NEW)
|
||||
|
@ -68,7 +68,7 @@ endif(CCACHE_FOUND)
|
|||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(RAPIDJSON_ENABLE_INSTRUMENTATION_OPT AND NOT CMAKE_CROSSCOMPILING)
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
||||
else()
|
||||
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
||||
|
@ -102,7 +102,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
||||
else()
|
||||
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
||||
|
@ -128,6 +128,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
add_definitions(-DNOMINMAX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||
# CMake >= 3.10 should handle the above CMAKE_CXX_STANDARD fine, otherwise use /std:c++XX with MSVC >= 19.10
|
||||
if (RAPIDJSON_BUILD_CXX11 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
|
||||
|
@ -241,8 +242,10 @@ INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAM
|
|||
DESTINATION ${CMAKECONFIG_INSTALL_DIR} )
|
||||
|
||||
# Install files
|
||||
INSTALL(FILES
|
||||
IF(CMAKE_INSTALL_DIR)
|
||||
INSTALL(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||
DESTINATION "${CMAKE_INSTALL_DIR}"
|
||||
COMPONENT dev)
|
||||
ENDIF()
|
||||
|
|
|
@ -97,11 +97,11 @@
|
|||
},
|
||||
"county_type": {
|
||||
"type": "string",
|
||||
"enum": ["Sussex", "Surrey", "Kent"]
|
||||
"enum": ["Sussex", "Surrey", "Kent", "Narnia"]
|
||||
},
|
||||
"province_type": {
|
||||
"type": "string",
|
||||
"enum": ["Quebec", "BC", "Alberta"]
|
||||
"enum": ["Quebec", "Narnia", "BC", "Alberta"]
|
||||
},
|
||||
"date_type": {
|
||||
"pattern": "^([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?$",
|
||||
|
@ -132,7 +132,6 @@
|
|||
"type": "string"
|
||||
},
|
||||
"url_type": {
|
||||
"pattern": "^\\S*$",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,30 +2,30 @@
|
|||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<!-- rapidjson::GenericValue - basic support -->
|
||||
<Type Name="rapidjson::GenericValue<*,*>">
|
||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kNullType">null</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == rapidjson::kNullType">null</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == kTrueFlag">true</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == kFalseFlag">false</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == kShortStringFlag">{(const Ch*)data_.ss.str,na}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kStringType">{(const Ch*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF),na}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == rapidjson::kStringType">{(const Ch*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF),[data_.s.length]na}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kNumberIntFlag) == kNumberIntFlag">{data_.n.i.i}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kNumberUintFlag) == kNumberUintFlag">{data_.n.u.u}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kNumberInt64Flag) == kNumberInt64Flag">{data_.n.i64}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kNumberUint64Flag) == kNumberUint64Flag">{data_.n.u64}</DisplayString>
|
||||
<DisplayString Condition="(data_.f.flags & kNumberDoubleFlag) == kNumberDoubleFlag">{data_.n.d}</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == kObjectType">Object members={data_.o.size}</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == kArrayType">Array members={data_.a.size}</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == rapidjson::kObjectType">Object members={data_.o.size}</DisplayString>
|
||||
<DisplayString Condition="data_.f.flags == rapidjson::kArrayType">Array members={data_.a.size}</DisplayString>
|
||||
<Expand>
|
||||
<Item Condition="data_.f.flags == kObjectType" Name="[size]">data_.o.size</Item>
|
||||
<Item Condition="data_.f.flags == kObjectType" Name="[capacity]">data_.o.capacity</Item>
|
||||
<ArrayItems Condition="data_.f.flags == kObjectType">
|
||||
<Item Condition="data_.f.flags == rapidjson::kObjectType" Name="[size]">data_.o.size</Item>
|
||||
<Item Condition="data_.f.flags == rapidjson::kObjectType" Name="[capacity]">data_.o.capacity</Item>
|
||||
<ArrayItems Condition="data_.f.flags == rapidjson::kObjectType">
|
||||
<Size>data_.o.size</Size>
|
||||
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
||||
<ValuePointer>(rapidjson::GenericMember<$T1,$T2>*)(((size_t)data_.o.members) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
||||
</ArrayItems>
|
||||
|
||||
<Item Condition="data_.f.flags == kArrayType" Name="[size]">data_.a.size</Item>
|
||||
<Item Condition="data_.f.flags == kArrayType" Name="[capacity]">data_.a.capacity</Item>
|
||||
<ArrayItems Condition="data_.f.flags == kArrayType">
|
||||
<Item Condition="data_.f.flags == rapidjson::kArrayType" Name="[size]">data_.a.size</Item>
|
||||
<Item Condition="data_.f.flags == rapidjson::kArrayType" Name="[capacity]">data_.a.capacity</Item>
|
||||
<ArrayItems Condition="data_.f.flags == rapidjson::kArrayType">
|
||||
<Size>data_.a.size</Size>
|
||||
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
||||
<ValuePointer>(rapidjson::GenericValue<$T1,$T2>*)(((size_t)data_.a.elements) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
* RapidJSON should be fully RFC4627/ECMA-404 compliance.
|
||||
* Support JSON Pointer (RFC6901).
|
||||
* Support JSON Schema Draft v4.
|
||||
* Support Swagger v2 schema.
|
||||
* Support OpenAPI v3.0.x schema.
|
||||
* Support Unicode surrogate.
|
||||
* Support null character (`"\u0000"`)
|
||||
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
||||
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
||||
* Support optional relaxed syntax.
|
||||
* Single line (`// ...`) and multiple line (`/* ... */`) comments (`kParseCommentsFlag`).
|
||||
* Trailing commas at the end of objects and arrays (`kParseTrailingCommasFlag`).
|
||||
* `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (`kParseNanAndInfFlag`)
|
||||
* Single line (`// ...`) and multiple line (`/* ... */`) comments (`kParseCommentsFlag`).
|
||||
* Trailing commas at the end of objects and arrays (`kParseTrailingCommasFlag`).
|
||||
* `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (`kParseNanAndInfFlag`)
|
||||
* [NPM compliant](http://github.com/Tencent/rapidjson/blob/master/doc/npm.md).
|
||||
|
||||
## Unicode
|
||||
|
|
|
@ -24,7 +24,15 @@ if (sd.Parse(schemaJson).HasParseError()) {
|
|||
// the schema is not a valid JSON.
|
||||
// ...
|
||||
}
|
||||
|
||||
SchemaDocument schema(sd); // Compile a Document to SchemaDocument
|
||||
if (!schema.GetError().ObjectEmpty()) {
|
||||
// there was a problem compiling the schema
|
||||
StringBuffer sb;
|
||||
Writer<StringBuffer> w(sb);
|
||||
schema.GetError().Accept(w);
|
||||
printf("Invalid schema: %s\n", sb.GetString());
|
||||
}
|
||||
// sd is no longer needed here.
|
||||
|
||||
Document d;
|
||||
|
|
|
@ -41,7 +41,8 @@ static std::string GetString(const ValueType& val) {
|
|||
s << "false";
|
||||
else if (val.IsFloat())
|
||||
s << val.GetFloat();
|
||||
return s.str();}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
// Create the error message for a named error
|
||||
// The error object can either be empty or contain at least member properties:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "internal/meta.h"
|
||||
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
#include <type_traits>
|
||||
|
@ -433,7 +434,7 @@ namespace internal {
|
|||
template<typename T, typename A>
|
||||
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
|
||||
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class GenericDocument;
|
|||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||
*/
|
||||
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
||||
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
|
||||
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
|
||||
#endif
|
||||
|
||||
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||
|
@ -85,7 +85,7 @@ class GenericDocument;
|
|||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||
*/
|
||||
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
|
||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
|
||||
#endif
|
||||
|
||||
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||
|
@ -1078,6 +1078,7 @@ public:
|
|||
*/
|
||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
||||
|
||||
#ifndef __cpp_impl_three_way_comparison
|
||||
//! Not-equal-to operator
|
||||
/*! \return !(*this == rhs)
|
||||
*/
|
||||
|
@ -1092,7 +1093,6 @@ public:
|
|||
*/
|
||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
||||
|
||||
#ifndef __cpp_lib_three_way_comparison
|
||||
//! Equal-to operator with arbitrary types (symmetric version)
|
||||
/*! \return (rhs == lhs)
|
||||
*/
|
||||
|
@ -1230,13 +1230,28 @@ public:
|
|||
else {
|
||||
RAPIDJSON_ASSERT(false); // see above note
|
||||
|
||||
// This will generate -Wexit-time-destructors in clang
|
||||
// static GenericValue NullValue;
|
||||
// return NullValue;
|
||||
|
||||
// Use static buffer and placement-new to prevent destruction
|
||||
static char buffer[sizeof(GenericValue)];
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
// Use thread-local storage to prevent races between threads.
|
||||
// Use static buffer and placement-new to prevent destruction, with
|
||||
// alignas() to ensure proper alignment.
|
||||
alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
|
||||
return *new (buffer) GenericValue();
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// There's no way to solve both thread locality and proper alignment
|
||||
// simultaneously.
|
||||
__declspec(thread) static char buffer[sizeof(GenericValue)];
|
||||
return *new (buffer) GenericValue();
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// This will generate -Wexit-time-destructors in clang, but that's
|
||||
// better than having under-alignment.
|
||||
__thread static GenericValue buffer;
|
||||
return buffer;
|
||||
#else
|
||||
// Don't know what compiler this is, so don't know how to ensure
|
||||
// thread-locality.
|
||||
static GenericValue buffer;
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
template <typename SourceAllocator>
|
||||
|
@ -2486,6 +2501,7 @@ public:
|
|||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
|
||||
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
||||
typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter.
|
||||
|
||||
//! Constructor
|
||||
/*! Creates an empty document of specified type.
|
||||
|
|
|
@ -104,11 +104,65 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode val
|
|||
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
||||
|
||||
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
||||
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
|
||||
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'.");
|
||||
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
||||
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
||||
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
||||
|
||||
case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing.");
|
||||
case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
//! Maps error code of schema document compilation into error message.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\param schemaErrorCode Error code obtained from compiling the schema document.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) {
|
||||
switch (schemaErrorCode) {
|
||||
case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document.");
|
||||
case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer.");
|
||||
case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string.");
|
||||
case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'.");
|
||||
case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document.");
|
||||
case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical.");
|
||||
case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider.");
|
||||
case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema.");
|
||||
case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'.");
|
||||
case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized.");
|
||||
case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported.");
|
||||
case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document.");
|
||||
case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
//! Maps error code of pointer parse into error message.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\param pointerParseErrorCode Error code obtained from pointer parse.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) {
|
||||
switch (pointerParseErrorCode) {
|
||||
case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'.");
|
||||
case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape.");
|
||||
case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment.");
|
||||
case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ RAPIDJSON_DIAG_OFF(padded)
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_STRING
|
||||
|
||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
By default this conversion macro does nothing.
|
||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
||||
|
@ -185,14 +185,17 @@ enum ValidateErrorCode {
|
|||
kValidateErrorPatternProperties, //!< See other errors.
|
||||
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
|
||||
|
||||
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values
|
||||
kValidateErrorType, //!< Property has a type that is not allowed by the schema..
|
||||
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values.
|
||||
kValidateErrorType, //!< Property has a type that is not allowed by the schema.
|
||||
|
||||
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
|
||||
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
|
||||
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
|
||||
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
|
||||
kValidateErrorNot //!< Property matched the sub-schema specified by 'not'.
|
||||
kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'.
|
||||
|
||||
kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing
|
||||
kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading
|
||||
};
|
||||
|
||||
//! Function pointer type of GetValidateError().
|
||||
|
@ -207,6 +210,72 @@ enum ValidateErrorCode {
|
|||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SchemaErrorCode
|
||||
|
||||
//! Error codes when validating.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericSchemaValidator
|
||||
*/
|
||||
enum SchemaErrorCode {
|
||||
kSchemaErrorNone = 0, //!< No error.
|
||||
|
||||
kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document
|
||||
kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer
|
||||
kSchemaErrorRefInvalid, //!< $ref must not be an empty string
|
||||
kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset
|
||||
kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document
|
||||
kSchemaErrorRefCyclical, //!< $ref is cyclical
|
||||
kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider
|
||||
kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema
|
||||
kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties'
|
||||
kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized
|
||||
kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported
|
||||
kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document
|
||||
kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly'
|
||||
};
|
||||
|
||||
//! Function pointer type of GetSchemaError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetSchemaError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PointerParseErrorCode
|
||||
|
||||
//! Error code of JSON pointer parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
||||
*/
|
||||
enum PointerParseErrorCode {
|
||||
kPointerParseErrorNone = 0, //!< The parse is successful
|
||||
|
||||
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
||||
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
||||
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
||||
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
||||
};
|
||||
|
||||
//! Function pointer type of GetPointerParseError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetPointerParseError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode);
|
||||
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
||||
#include <intrin.h> // for _umul128
|
||||
#if !defined(_ARM64EC_)
|
||||
#pragma intrinsic(_umul128)
|
||||
#else
|
||||
#pragma comment(lib,"softintrin")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -255,7 +259,7 @@ private:
|
|||
if (low < k)
|
||||
(*outHigh)++;
|
||||
return low;
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
__extension__ typedef unsigned __int128 uint128;
|
||||
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
|
||||
p += k;
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||
#include <intrin.h>
|
||||
#if !defined(_ARM64EC_)
|
||||
#pragma intrinsic(_umul128)
|
||||
#else
|
||||
#pragma comment(lib,"softintrin")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -75,7 +79,7 @@ struct DiyFp {
|
|||
if (l & (uint64_t(1) << 63)) // rounding
|
||||
h++;
|
||||
return DiyFp(h, e + rhs.e + 64);
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
__extension__ typedef unsigned __int128 uint128;
|
||||
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
|
||||
uint64_t h = static_cast<uint64_t>(p >> 64);
|
||||
|
|
|
@ -58,11 +58,11 @@ inline int CountDecimalDigit32(uint32_t n) {
|
|||
}
|
||||
|
||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||
static const uint64_t kPow10[] = { 1U, 10U, 100U, 1000U, 10000U, 100000U, 1000000U, 10000000U, 100000000U,
|
||||
1000000000U, 10000000000U, 100000000000U, 1000000000000U,
|
||||
10000000000000U, 100000000000000U, 1000000000000000U,
|
||||
10000000000000000U, 100000000000000000U, 1000000000000000000U,
|
||||
10000000000000000000U };
|
||||
static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL,
|
||||
1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL,
|
||||
10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
|
||||
10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
|
||||
10000000000000000000ULL };
|
||||
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
||||
const DiyFp wp_w = Mp - W;
|
||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "document.h"
|
||||
#include "uri.h"
|
||||
#include "internal/itoa.h"
|
||||
#include "error/error.h" // PointerParseErrorCode
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
|
@ -31,19 +32,6 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||
|
||||
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
||||
|
||||
//! Error code of parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
||||
*/
|
||||
enum PointerParseErrorCode {
|
||||
kPointerParseErrorNone = 0, //!< The parse is successful
|
||||
|
||||
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
||||
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
||||
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
||||
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GenericPointer
|
||||
|
||||
|
@ -902,10 +890,16 @@ private:
|
|||
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
||||
}
|
||||
|
||||
// Adjust pointers to name buffer
|
||||
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
||||
for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
|
||||
t->name += diff;
|
||||
// The names of each token point to a string in the nameBuffer_. The
|
||||
// previous memcpy copied over string pointers into the rhs.nameBuffer_,
|
||||
// but they should point to the strings in the new nameBuffer_.
|
||||
for (size_t i = 0; i < rhs.tokenCount_; ++i) {
|
||||
// The offset between the string address and the name buffer should
|
||||
// still be constant, so we can just get this offset and set each new
|
||||
// token name according the new buffer start + the known offset.
|
||||
std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
|
||||
tokens_[i].name = nameBuffer_ + name_offset;
|
||||
}
|
||||
|
||||
return nameBuffer_ + nameBufferSize;
|
||||
}
|
||||
|
|
|
@ -1433,7 +1433,7 @@ private:
|
|||
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
||||
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
||||
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
|
||||
|
@ -1459,7 +1459,7 @@ private:
|
|||
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
||||
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
|
||||
};
|
||||
|
@ -1694,7 +1694,7 @@ private:
|
|||
}
|
||||
else {
|
||||
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
|
||||
GenericStringStream<UTF8<NumberCharacter>> srcStream(s.Pop());
|
||||
GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
|
||||
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
|
||||
while (numCharsToCopy--) {
|
||||
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,6 +67,7 @@ enum WriteFlag {
|
|||
kWriteNoFlags = 0, //!< No flags are set.
|
||||
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
||||
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
|
||||
kWriteNanAndInfNullFlag = 4, //!< Allow writing of Infinity, -Infinity and NaN as null.
|
||||
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||
};
|
||||
|
||||
|
@ -350,6 +351,11 @@ protected:
|
|||
if (internal::Double(d).IsNanOrInf()) {
|
||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
||||
return false;
|
||||
if (writeFlags & kWriteNanAndInfNullFlag) {
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
|
@ -548,6 +554,11 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
|||
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
|
||||
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
|
||||
return false;
|
||||
if (kWriteDefaultFlags & kWriteNanAndInfNullFlag) {
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
|
|
|
@ -20,7 +20,7 @@ using namespace rapidjson;
|
|||
|
||||
// static const char json[] = "{\"string\"\n\n:\"my string\",\"array\"\n:[\"1\", \"2\", \"3\"]}";
|
||||
|
||||
bool testJson(const char *json, size_t &line, size_t &col) {
|
||||
static bool testJson(const char *json, size_t &line, size_t &col) {
|
||||
StringStream ss(json);
|
||||
CursorStreamWrapper<StringStream> csw(ss);
|
||||
Document document;
|
||||
|
|
|
@ -113,8 +113,8 @@ protected:
|
|||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
EXPECT_EQ('\0', s.Peek());
|
||||
free(data);
|
||||
EXPECT_EQ(size, eis.Tell());
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ TEST(Pointer, Parse_URIFragment) {
|
|||
}
|
||||
|
||||
{
|
||||
// Decode UTF-8 perecent encoding to UTF-8
|
||||
// Decode UTF-8 percent encoding to UTF-8
|
||||
Pointer p("#/%C2%A2");
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(1u, p.GetTokenCount());
|
||||
|
@ -311,7 +311,7 @@ TEST(Pointer, Parse_URIFragment) {
|
|||
}
|
||||
|
||||
{
|
||||
// Decode UTF-8 perecent encoding to UTF-16
|
||||
// Decode UTF-8 percent encoding to UTF-16
|
||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(1u, p.GetTokenCount());
|
||||
|
@ -320,7 +320,7 @@ TEST(Pointer, Parse_URIFragment) {
|
|||
}
|
||||
|
||||
{
|
||||
// Decode UTF-8 perecent encoding to UTF-16
|
||||
// Decode UTF-8 percent encoding to UTF-16
|
||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(1u, p.GetTokenCount());
|
||||
|
|
|
@ -2054,61 +2054,61 @@ struct NumbersAsStringsHandlerWChar_t {
|
|||
TEST(Reader, NumbersAsStringsWChar_t) {
|
||||
{
|
||||
const wchar_t* json = L"{ \"pi\": 3.1416 } ";
|
||||
GenericStringStream<UTF16<>> s(json);
|
||||
GenericStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
{
|
||||
wchar_t* json = StrDup(L"{ \"pi\": 3.1416 } ");
|
||||
GenericInsituStringStream<UTF16<>> s(json);
|
||||
GenericInsituStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||
free(json);
|
||||
}
|
||||
{
|
||||
const wchar_t* json = L"{ \"gigabyte\": 1.0e9 } ";
|
||||
GenericStringStream<UTF16<>> s(json);
|
||||
GenericStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
{
|
||||
wchar_t* json = StrDup(L"{ \"gigabyte\": 1.0e9 } ");
|
||||
GenericInsituStringStream<UTF16<>> s(json);
|
||||
GenericInsituStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||
free(json);
|
||||
}
|
||||
{
|
||||
const wchar_t* json = L"{ \"pi\": 314.159e-2 } ";
|
||||
GenericStringStream<UTF16<>> s(json);
|
||||
GenericStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
{
|
||||
wchar_t* json = StrDup(L"{ \"gigabyte\": 314.159e-2 } ");
|
||||
GenericInsituStringStream<UTF16<>> s(json);
|
||||
GenericInsituStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||
free(json);
|
||||
}
|
||||
{
|
||||
const wchar_t* json = L"{ \"negative\": -1.54321 } ";
|
||||
GenericStringStream<UTF16<>> s(json);
|
||||
GenericStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
{
|
||||
wchar_t* json = StrDup(L"{ \"negative\": -1.54321 } ");
|
||||
GenericInsituStringStream<UTF16<>> s(json);
|
||||
GenericInsituStringStream<UTF16<> > s(json);
|
||||
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||
free(json);
|
||||
}
|
||||
|
@ -2117,7 +2117,7 @@ TEST(Reader, NumbersAsStringsWChar_t) {
|
|||
std::wstringstream ss(json);
|
||||
WIStreamWrapper s(ss);
|
||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
{
|
||||
|
@ -2126,9 +2126,9 @@ TEST(Reader, NumbersAsStringsWChar_t) {
|
|||
for(int i = 1; i < 320; i++)
|
||||
n1e319[i] = L'0';
|
||||
n1e319[320] = L'\0';
|
||||
GenericStringStream<UTF16<>> s(n1e319);
|
||||
GenericStringStream<UTF16<> > s(n1e319);
|
||||
NumbersAsStringsHandlerWChar_t h(n1e319);
|
||||
GenericReader<UTF16<>, UTF16<>> reader;
|
||||
GenericReader<UTF16<>, UTF16<> > reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,13 @@ TEST(SchemaValidator, Hasher) {
|
|||
|
||||
#define VALIDATE(schema, json, expected) \
|
||||
{\
|
||||
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);*/\
|
||||
|
@ -149,6 +156,8 @@ TEST(SchemaValidator, Hasher) {
|
|||
#define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
|
||||
flags, SchemaValidatorType, PointerType) \
|
||||
{\
|
||||
EXPECT_TRUE(schema.GetError().ObjectEmpty());\
|
||||
EXPECT_TRUE(schema.IsSupportedSpecification());\
|
||||
SchemaValidatorType validator(schema);\
|
||||
validator.SetValidateFlags(flags);\
|
||||
Document d;\
|
||||
|
@ -188,6 +197,20 @@ TEST(SchemaValidator, Hasher) {
|
|||
}\
|
||||
}
|
||||
|
||||
// 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("{}");
|
||||
|
@ -223,7 +246,7 @@ TEST(SchemaValidator, Enum_Typed) {
|
|||
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
|
||||
}
|
||||
|
||||
TEST(SchemaValidator, Enum_Typless) {
|
||||
TEST(SchemaValidator, Enum_Typeless) {
|
||||
Document sd;
|
||||
sd.Parse("{ \"enum\": [\"red\", \"amber\", \"green\", null, 42] }");
|
||||
SchemaDocument s(sd);
|
||||
|
@ -333,7 +356,7 @@ TEST(SchemaValidator, OneOf) {
|
|||
" ]"
|
||||
"}}");
|
||||
INVALIDATE(s, "15", "", "oneOf", "",
|
||||
"{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"errors\": [{}, {}]}}");
|
||||
"{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"matches\": [0,1]}}");
|
||||
}
|
||||
|
||||
TEST(SchemaValidator, Not) {
|
||||
|
@ -502,12 +525,13 @@ TEST(SchemaValidator, String_Pattern) {
|
|||
|
||||
TEST(SchemaValidator, String_Pattern_Invalid) {
|
||||
Document sd;
|
||||
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); // TODO: report regex is invalid somehow
|
||||
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}");
|
||||
SchemaDocument s(sd);
|
||||
SCHEMAERROR(s, "{\"RegexInvalid\":{\"errorCode\":9,\"instanceRef\":\"#/pattern\",\"value\":\"a{0}\"}}");
|
||||
|
||||
VALIDATE(s, "\"\"", true);
|
||||
VALIDATE(s, "\"a\"", true);
|
||||
VALIDATE(s, "\"aa\"", true);
|
||||
VALIDATE_(s, "\"\"", true, false);
|
||||
VALIDATE_(s, "\"a\"", true, false);
|
||||
VALIDATE_(s, "\"aa\"", true, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1886,12 +1910,6 @@ TEST(SchemaValidator, SchemaPointer) {
|
|||
" },"
|
||||
" \"f\": {"
|
||||
" \"type\": \"boolean\""
|
||||
" },"
|
||||
" \"cyclic_source\": {"
|
||||
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_target\""
|
||||
" },"
|
||||
" \"cyclic_target\": {"
|
||||
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_source\""
|
||||
" }"
|
||||
" },"
|
||||
" \"type\": \"object\""
|
||||
|
@ -2135,9 +2153,13 @@ public:
|
|||
}
|
||||
|
||||
virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) {
|
||||
//printf("GetRemoteDocument : %s\n", uri);
|
||||
for (size_t i = 0; i < kCount; i++)
|
||||
if (typename SchemaDocumentType::SValue(uri, length) == sd_[i]->GetURI())
|
||||
if (typename SchemaDocumentType::GValue(uri, length) == sd_[i]->GetURI()) {
|
||||
//printf("Matched document");
|
||||
return sd_[i];
|
||||
}
|
||||
//printf("No matched document");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2390,7 +2412,9 @@ TEST(SchemaValidator, Issue728_AllOfRef) {
|
|||
Document sd;
|
||||
sd.Parse("{\"allOf\": [{\"$ref\": \"#/abc\"}]}");
|
||||
SchemaDocument s(sd);
|
||||
VALIDATE(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true);
|
||||
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/allOf/0\",\"value\":\"#/abc\"}}");
|
||||
|
||||
VALIDATE_(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true, false);
|
||||
}
|
||||
|
||||
TEST(SchemaValidator, Issue1017_allOfHandler) {
|
||||
|
@ -2625,7 +2649,7 @@ TEST(SchemaValidator, Ref_remote_issue1210) {
|
|||
SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
|
||||
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
||||
int i = 0;
|
||||
while (collection[i] && SchemaDocument::SValue(uri, length) != collection[i]->GetURI()) ++i;
|
||||
while (collection[i] && SchemaDocument::GValue(uri, length) != collection[i]->GetURI()) ++i;
|
||||
return collection[i];
|
||||
}
|
||||
};
|
||||
|
@ -2656,7 +2680,7 @@ TEST(SchemaValidator, ContinueOnErrors) {
|
|||
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);
|
||||
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", "#",
|
||||
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"
|
||||
" },"
|
||||
|
@ -2691,6 +2715,9 @@ TEST(SchemaValidator, ContinueOnErrors) {
|
|||
" },"
|
||||
" \"required\": {"
|
||||
" \"missing\": [\"street1\"], \"errorCode\": 15, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\""
|
||||
" },"
|
||||
" \"oneOf\": {"
|
||||
" \"matches\": [0, 1], \"errorCode\": 22, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\""
|
||||
" }"
|
||||
"}",
|
||||
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
||||
|
@ -2917,7 +2944,7 @@ TEST(SchemaValidator, ContinueOnErrors_RogueString) {
|
|||
|
||||
// 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
|
||||
TEST(SchemaValidator, ContinueOnErrors_Issue2) {
|
||||
TEST(SchemaValidator, ContinueOnErrors_BadSimpleType) {
|
||||
Document sd;
|
||||
sd.Parse("{\"type\":\"string\", \"anyOf\":[{\"maxLength\":2}]}");
|
||||
ASSERT_FALSE(sd.HasParseError());
|
||||
|
@ -2943,10 +2970,606 @@ TEST(SchemaValidator, ContinueOnErrors_Issue2) {
|
|||
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
||||
}
|
||||
|
||||
TEST(SchemaValidator, Schema_UnknownError) {
|
||||
|
||||
TEST(SchemaValidator, UnknownValidationError) {
|
||||
ASSERT_TRUE(SchemaValidator::SchemaType::GetValidateErrorKeyword(kValidateErrors).GetString() == std::string("null"));
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -49,10 +49,12 @@ using namespace rapidjson_simd;
|
|||
#define SIMD_SUFFIX(name) name
|
||||
#endif
|
||||
|
||||
#define SIMD_SIZE_ALIGN(n) ((size_t(n) + 15) & ~size_t(15))
|
||||
|
||||
template <typename StreamType>
|
||||
void TestSkipWhitespace() {
|
||||
for (size_t step = 1; step < 32; step++) {
|
||||
char buffer[1025];
|
||||
char buffer[SIMD_SIZE_ALIGN(1025)];
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
buffer[i] = " \t\r\n"[i % 4];
|
||||
for (size_t i = 0; i < 1024; i += step)
|
||||
|
@ -79,7 +81,7 @@ TEST(SIMD, SIMD_SUFFIX(SkipWhitespace)) {
|
|||
|
||||
TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
|
||||
for (size_t step = 1; step < 32; step++) {
|
||||
char buffer[1024];
|
||||
char buffer[SIMD_SIZE_ALIGN(1024)];
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
buffer[i] = " \t\r\n"[i % 4];
|
||||
for (size_t i = 0; i < 1024; i += step)
|
||||
|
@ -87,14 +89,12 @@ TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
|
|||
|
||||
MemoryStream ms(buffer, 1024);
|
||||
EncodedInputStream<UTF8<>, MemoryStream> s(ms);
|
||||
size_t i = 0;
|
||||
for (;;) {
|
||||
SkipWhitespace(s);
|
||||
if (s.Peek() == '\0')
|
||||
break;
|
||||
//EXPECT_EQ(i, s.Tell());
|
||||
EXPECT_EQ('X', s.Take());
|
||||
i += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ struct ScanCopyUnescapedStringHandler : BaseReaderHandler<UTF8<>, ScanCopyUnesca
|
|||
|
||||
template <unsigned parseFlags, typename StreamType>
|
||||
void TestScanCopyUnescapedString() {
|
||||
char buffer[1024u + 5 + 32];
|
||||
char backup[1024u + 5 + 32];
|
||||
char buffer[SIMD_SIZE_ALIGN(1024u + 5 + 32)];
|
||||
char backup[SIMD_SIZE_ALIGN(1024u + 5 + 32)];
|
||||
|
||||
// Test "ABCDABCD...\\"
|
||||
for (size_t offset = 0; offset < 32; offset++) {
|
||||
|
@ -167,7 +167,7 @@ TEST(SIMD, SIMD_SUFFIX(ScanCopyUnescapedString)) {
|
|||
}
|
||||
|
||||
TEST(SIMD, SIMD_SUFFIX(ScanWriteUnescapedString)) {
|
||||
char buffer[2048 + 1 + 32];
|
||||
char buffer[SIMD_SIZE_ALIGN(2048 + 1 + 32)];
|
||||
for (size_t offset = 0; offset < 32; offset++) {
|
||||
for (size_t step = 0; step < 1024; step++) {
|
||||
char* s = buffer + offset;
|
||||
|
|
|
@ -48,7 +48,6 @@ TEST(Uri, DefaultConstructor) {
|
|||
EXPECT_TRUE(u.GetStringLength() == 0);
|
||||
}
|
||||
|
||||
|
||||
TEST(Uri, Parse) {
|
||||
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
||||
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||
|
@ -66,21 +65,8 @@ TEST(Uri, Parse) {
|
|||
u.Get(w, allocator);
|
||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
typedef std::basic_string<Value::Ch> String;
|
||||
String str = "http://auth/path/xxx?query#frag";
|
||||
const UriType uri = UriType(str);
|
||||
EXPECT_TRUE(UriType::GetScheme(uri) == "http:");
|
||||
EXPECT_TRUE(UriType::GetAuth(uri) == "//auth");
|
||||
EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx");
|
||||
EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query");
|
||||
EXPECT_TRUE(UriType::GetQuery(uri) == "?query");
|
||||
EXPECT_TRUE(UriType::GetFrag(uri) == "#frag");
|
||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||
#endif
|
||||
|
||||
v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0);
|
||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
||||
|
@ -91,7 +77,7 @@ TEST(Uri, Parse) {
|
|||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||
|
||||
v.SetString("", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
||||
|
@ -100,7 +86,7 @@ TEST(Uri, Parse) {
|
|||
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
||||
|
||||
v.SetString("http://auth/", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
||||
|
@ -162,12 +148,11 @@ TEST(Uri, Parse) {
|
|||
EXPECT_TRUE(u.GetFragStringLength() == len);
|
||||
|
||||
// Incomplete auth treated as path
|
||||
str = "http:/";
|
||||
const UriType u2 = UriType(str);
|
||||
EXPECT_TRUE(StrCmp(u2.GetSchemeString(), "http:") == 0);
|
||||
EXPECT_TRUE(u2.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(StrCmp(u2.GetPathString(), "/") == 0);
|
||||
EXPECT_TRUE(StrCmp(u2.GetBaseString(), "http:/") == 0);
|
||||
u = UriType("http:/");
|
||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetBaseString(), "http:/") == 0);
|
||||
}
|
||||
|
||||
TEST(Uri, Parse_UTF16) {
|
||||
|
@ -188,21 +173,8 @@ TEST(Uri, Parse_UTF16) {
|
|||
u.Get(w, allocator);
|
||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
typedef std::basic_string<Value16::Ch> String;
|
||||
String str = L"http://auth/path/xxx?query#frag";
|
||||
const UriType uri = UriType(str);
|
||||
EXPECT_TRUE(UriType::GetScheme(uri) == L"http:");
|
||||
EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth");
|
||||
EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx");
|
||||
EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query");
|
||||
EXPECT_TRUE(UriType::GetQuery(uri) == L"?query");
|
||||
EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag");
|
||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||
#endif
|
||||
|
||||
v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0);
|
||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
||||
|
@ -213,7 +185,7 @@ TEST(Uri, Parse_UTF16) {
|
|||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||
|
||||
v.SetString(L"", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
||||
|
@ -222,7 +194,7 @@ TEST(Uri, Parse_UTF16) {
|
|||
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
||||
|
||||
v.SetString(L"http://auth/", allocator);
|
||||
u = UriType(v);
|
||||
u = UriType(v, &allocator);
|
||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
||||
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0);
|
||||
|
@ -291,6 +263,41 @@ TEST(Uri, Parse_UTF16) {
|
|||
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http:/") == 0);
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
TEST(Uri, Parse_Std) {
|
||||
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
||||
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||
typedef std::basic_string<Value::Ch> String;
|
||||
|
||||
String str = "http://auth/path/xxx?query#frag";
|
||||
const UriType uri = UriType(str, &allocator);
|
||||
EXPECT_TRUE(UriType::GetScheme(uri) == "http:");
|
||||
EXPECT_TRUE(UriType::GetAuth(uri) == "//auth");
|
||||
EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx");
|
||||
EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query");
|
||||
EXPECT_TRUE(UriType::GetQuery(uri) == "?query");
|
||||
EXPECT_TRUE(UriType::GetFrag(uri) == "#frag");
|
||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||
}
|
||||
|
||||
TEST(Uri, Parse_UTF16_Std) {
|
||||
typedef GenericValue<UTF16<> > Value16;
|
||||
typedef GenericUri<Value16, MemoryPoolAllocator<> > UriType;
|
||||
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||
typedef std::basic_string<Value16::Ch> String;
|
||||
|
||||
String str = L"http://auth/path/xxx?query#frag";
|
||||
const UriType uri = UriType(str, &allocator);
|
||||
EXPECT_TRUE(UriType::GetScheme(uri) == L"http:");
|
||||
EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth");
|
||||
EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx");
|
||||
EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query");
|
||||
EXPECT_TRUE(UriType::GetQuery(uri) == L"?query");
|
||||
EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag");
|
||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Uri, CopyConstructor) {
|
||||
typedef GenericUri<Value> UriType;
|
||||
CrtAllocator allocator;
|
||||
|
|
|
@ -1581,7 +1581,7 @@ TEST(Value, ObjectHelperRangeFor) {
|
|||
{
|
||||
int i = 0;
|
||||
for (auto& m : x.GetObject()) {
|
||||
char name[10];
|
||||
char name[11];
|
||||
sprintf(name, "%d", i);
|
||||
EXPECT_STREQ(name, m.name.GetString());
|
||||
EXPECT_EQ(i, m.value.GetInt());
|
||||
|
@ -1592,7 +1592,7 @@ TEST(Value, ObjectHelperRangeFor) {
|
|||
{
|
||||
int i = 0;
|
||||
for (const auto& m : const_cast<const Value&>(x).GetObject()) {
|
||||
char name[10];
|
||||
char name[11];
|
||||
sprintf(name, "%d", i);
|
||||
EXPECT_STREQ(name, m.name.GetString());
|
||||
EXPECT_EQ(i, m.value.GetInt());
|
||||
|
|
|
@ -15,3 +15,12 @@
|
|||
Memcheck:Value8
|
||||
fun:__wcslen_sse2
|
||||
}
|
||||
|
||||
{
|
||||
Suppress wmemcmp valgrind report 4
|
||||
Memcheck:Addr32
|
||||
fun:__wmemcmp_avx2_movbe
|
||||
...
|
||||
fun:*Uri*Parse_UTF16_Std*
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue