Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Yip <miloyip@gmail.com>2017-07-13 11:07:36 +0300
committerMilo Yip <miloyip@gmail.com>2017-07-13 11:07:36 +0300
commitfcd2e1f60cecc00d414821987b2d3d02dbd593df (patch)
tree9efe62be3c291dacdf4c539b2ecbe952776ee7d5
parent2f45319b4e5862f9dc57bd1ffd11e55ab44efa61 (diff)
Fix #1017 allOf keyword fail with Writer handlerissue1017_allOfHandler
Gave up using static binding for null handler, because it cannot be used with arbitrary handler type. Change `OutputHandler handler_` to pointer type.
-rw-r--r--include/rapidjson/schema.h26
-rw-r--r--test/unittest/schematest.cpp19
2 files changed, 27 insertions, 18 deletions
diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h
index dd57edbc..abcf1a10 100644
--- a/include/rapidjson/schema.h
+++ b/include/rapidjson/schema.h
@@ -1594,7 +1594,7 @@ public:
ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity),
- outputHandler_(CreateNullHandler()),
+ outputHandler_(0),
valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE
, depth_(0)
@@ -1622,8 +1622,7 @@ public:
ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity),
- outputHandler_(outputHandler),
- nullHandler_(0),
+ outputHandler_(&outputHandler),
valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE
, depth_(0)
@@ -1634,10 +1633,6 @@ public:
//! Destructor.
~GenericSchemaValidator() {
Reset();
- if (nullHandler_) {
- nullHandler_->~OutputHandler();
- StateAllocator::Free(nullHandler_);
- }
RAPIDJSON_DELETE(ownStateAllocator_);
}
@@ -1699,7 +1694,7 @@ RAPIDJSON_MULTILINEMACRO_END
}
#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) \
RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
@@ -1721,7 +1716,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool StartObject() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());
- return valid_ = outputHandler_.StartObject();
+ return valid_ = !outputHandler_ || outputHandler_->StartObject();
}
bool Key(const Ch* str, SizeType len, bool copy) {
@@ -1729,7 +1724,7 @@ RAPIDJSON_MULTILINEMACRO_END
AppendToken(str, len);
if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
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) {
@@ -1742,7 +1737,7 @@ RAPIDJSON_MULTILINEMACRO_END
bool StartArray() {
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());
- return valid_ = outputHandler_.StartArray();
+ return valid_ = !outputHandler_ || outputHandler_->StartArray();
}
bool EndArray(SizeType elementCount) {
@@ -1815,7 +1810,7 @@ private:
ownStateAllocator_(0),
schemaStack_(allocator, schemaStackCapacity),
documentStack_(allocator, documentStackCapacity),
- outputHandler_(CreateNullHandler()),
+ outputHandler_(0),
valid_(true)
#if RAPIDJSON_SCHEMA_VERBOSE
, depth_(depth)
@@ -1929,10 +1924,6 @@ private:
Context& CurrentContext() { 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 kDefaultDocumentStackCapacity = 256;
const SchemaDocumentType* schemaDocument_;
@@ -1941,8 +1932,7 @@ private:
StateAllocator* ownStateAllocator_;
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)
- OutputHandler& outputHandler_;
- OutputHandler* nullHandler_;
+ OutputHandler* outputHandler_;
bool valid_;
#if RAPIDJSON_SCHEMA_VERBOSE
unsigned depth_;
diff --git a/test/unittest/schematest.cpp b/test/unittest/schematest.cpp
index e79fec28..9b99ba89 100644
--- a/test/unittest/schematest.cpp
+++ b/test/unittest/schematest.cpp
@@ -1329,6 +1329,25 @@ TEST(SchemaValidator, Issue825) {
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__
RAPIDJSON_DIAG_POP
#endif