Commit fcd2e1f6 authored by Milo Yip's avatar Milo Yip

Fix #1017 allOf keyword fail with Writer handler

Gave up using static binding for null handler, because it cannot be
used with arbitrary handler type. Change `OutputHandler handler_` to
pointer type.
parent 2f45319b
...@@ -1594,7 +1594,7 @@ public: ...@@ -1594,7 +1594,7 @@ public:
ownStateAllocator_(0), ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity), schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity), documentStack_(allocator, documentStackCapacity),
outputHandler_(CreateNullHandler()), outputHandler_(0),
valid_(true) valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
, depth_(0) , depth_(0)
...@@ -1622,8 +1622,7 @@ public: ...@@ -1622,8 +1622,7 @@ public:
ownStateAllocator_(0), ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity), schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity), documentStack_(allocator, documentStackCapacity),
outputHandler_(outputHandler), outputHandler_(&outputHandler),
nullHandler_(0),
valid_(true) valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
, depth_(0) , depth_(0)
...@@ -1634,10 +1633,6 @@ public: ...@@ -1634,10 +1633,6 @@ public:
//! Destructor. //! Destructor.
~GenericSchemaValidator() { ~GenericSchemaValidator() {
Reset(); Reset();
if (nullHandler_) {
nullHandler_->~OutputHandler();
StateAllocator::Free(nullHandler_);
}
RAPIDJSON_DELETE(ownStateAllocator_); RAPIDJSON_DELETE(ownStateAllocator_);
} }
...@@ -1699,7 +1694,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1699,7 +1694,7 @@ RAPIDJSON_MULTILINEMACRO_END
} }
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ #define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
return valid_ = EndValue() && outputHandler_.method arg2 return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2)
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ #define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
...@@ -1721,7 +1716,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1721,7 +1716,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool StartObject() { bool StartObject() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());
return valid_ = outputHandler_.StartObject(); return valid_ = !outputHandler_ || outputHandler_->StartObject();
} }
bool Key(const Ch* str, SizeType len, bool copy) { bool Key(const Ch* str, SizeType len, bool copy) {
...@@ -1729,7 +1724,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1729,7 +1724,7 @@ RAPIDJSON_MULTILINEMACRO_END
AppendToken(str, len); AppendToken(str, len);
if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));
return valid_ = outputHandler_.Key(str, len, copy); return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
} }
bool EndObject(SizeType memberCount) { bool EndObject(SizeType memberCount) {
...@@ -1742,7 +1737,7 @@ RAPIDJSON_MULTILINEMACRO_END ...@@ -1742,7 +1737,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool StartArray() { bool StartArray() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());
return valid_ = outputHandler_.StartArray(); return valid_ = !outputHandler_ || outputHandler_->StartArray();
} }
bool EndArray(SizeType elementCount) { bool EndArray(SizeType elementCount) {
...@@ -1815,7 +1810,7 @@ private: ...@@ -1815,7 +1810,7 @@ private:
ownStateAllocator_(0), ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity), schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity), documentStack_(allocator, documentStackCapacity),
outputHandler_(CreateNullHandler()), outputHandler_(0),
valid_(true) valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
, depth_(depth) , depth_(depth)
...@@ -1929,10 +1924,6 @@ private: ...@@ -1929,10 +1924,6 @@ private:
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); } Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); } const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
OutputHandler& CreateNullHandler() {
return *(nullHandler_ = new (GetStateAllocator().Malloc(sizeof(OutputHandler))) OutputHandler);
}
static const size_t kDefaultSchemaStackCapacity = 1024; static const size_t kDefaultSchemaStackCapacity = 1024;
static const size_t kDefaultDocumentStackCapacity = 256; static const size_t kDefaultDocumentStackCapacity = 256;
const SchemaDocumentType* schemaDocument_; const SchemaDocumentType* schemaDocument_;
...@@ -1941,8 +1932,7 @@ private: ...@@ -1941,8 +1932,7 @@ private:
StateAllocator* ownStateAllocator_; StateAllocator* ownStateAllocator_;
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch) internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch)
OutputHandler& outputHandler_; OutputHandler* outputHandler_;
OutputHandler* nullHandler_;
bool valid_; bool valid_;
#if RAPIDJSON_SCHEMA_VERBOSE #if RAPIDJSON_SCHEMA_VERBOSE
unsigned depth_; unsigned depth_;
......
...@@ -1329,6 +1329,25 @@ TEST(SchemaValidator, Issue825) { ...@@ -1329,6 +1329,25 @@ TEST(SchemaValidator, Issue825) {
VALIDATE(s, "{ \"item\": \"hello\" }", true); VALIDATE(s, "{ \"item\": \"hello\" }", true);
} }
TEST(SchemaValidator, Issue1017_allOfHandler) {
Document sd;
sd.Parse("{\"allOf\": [{\"type\": \"object\",\"properties\": {\"cyanArray2\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}}},{\"type\": \"object\",\"properties\": {\"blackArray\": {\"type\": \"array\",\"items\": { \"type\": \"string\" }}},\"required\": [ \"blackArray\" ]}]}");
SchemaDocument s(sd);
StringBuffer sb;
Writer<StringBuffer> writer(sb);
GenericSchemaValidator<SchemaDocument, Writer<StringBuffer> > validator(s, writer);
EXPECT_TRUE(validator.StartObject());
EXPECT_TRUE(validator.Key("cyanArray2", 10, false));
EXPECT_TRUE(validator.StartArray());
EXPECT_TRUE(validator.EndArray(0));
EXPECT_TRUE(validator.Key("blackArray", 10, false));
EXPECT_TRUE(validator.StartArray());
EXPECT_TRUE(validator.EndArray(0));
EXPECT_TRUE(validator.EndObject(0));
EXPECT_TRUE(validator.IsValid());
EXPECT_STREQ("{\"cyanArray2\":[],\"blackArray\":[]}", sb.GetString());
}
#ifdef __clang__ #ifdef __clang__
RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_POP
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment