You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by al...@apache.org on 2018/09/18 19:41:51 UTC
[mesos] 02/02: Added new member function to stout PicoJSON context.
This is an automated email from the ASF dual-hosted git repository.
alexr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit bc90afc2a0bf9603a1fc9f1012f85a3f1cdcb518
Author: Benno Evers <be...@mesosphere.com>
AuthorDate: Tue Sep 18 21:34:33 2018 +0200
Added new member function to stout PicoJSON context.
This commit adds the new `parse_object_stop()` callback,
which was added in the previous patch, to stout's internal
PicoJSON context.
Review: https://reviews.apache.org/r/68720/
---
3rdparty/stout/include/stout/json.hpp | 35 ++++++++++++++++++++++++++++++-----
3rdparty/stout/tests/json_tests.cpp | 21 +++++++++++++++++++++
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/3rdparty/stout/include/stout/json.hpp b/3rdparty/stout/include/stout/json.hpp
index 62a8139..17bd02e 100644
--- a/3rdparty/stout/include/stout/json.hpp
+++ b/3rdparty/stout/include/stout/json.hpp
@@ -889,13 +889,18 @@ inline std::ostream& operator<<(std::ostream& stream, const Null& null)
namespace internal {
+// "Depth" is counted downwards to stay closer to the analogous
+// implementation in PicoJSON.
+constexpr size_t STOUT_JSON_MAX_DEPTH = 200;
+
// Our implementation of picojson's parsing context that allows
// us to parse directly into our JSON::Value.
//
// https://github.com/kazuho/picojson/blob/v1.3.0/picojson.h#L820-L870
class ParseContext {
public:
- ParseContext(Value* _value) : value(_value) {}
+ ParseContext(Value* _value, size_t _depth = STOUT_JSON_MAX_DEPTH)
+ : value(_value), depth(_depth) {}
ParseContext(const ParseContext&) = delete;
ParseContext &operator=(const ParseContext&) = delete;
@@ -920,19 +925,33 @@ public:
return picojson::_parse_string(value->as<String>().value, in);
}
- bool parse_array_start() { *value = Array(); return true; }
+ bool parse_array_start() {
+ if (depth <= 0) {
+ return false;
+ }
+ --depth;
+ *value = Array();
+ return true;
+ }
template <typename Iter>
bool parse_array_item(picojson::input<Iter>& in, size_t) {
Array& array = value->as<Array>();
array.values.push_back(Value());
- ParseContext context(&array.values.back());
+ ParseContext context(&array.values.back(), depth);
return picojson::_parse(context, in);
}
- bool parse_array_stop(size_t) { return true; }
+ bool parse_array_stop(size_t) {
+ ++depth;
+ return true;
+ }
bool parse_object_start() {
+ if (depth <= 0) {
+ return false;
+ }
+ --depth;
*value = Object();
return true;
}
@@ -940,11 +959,17 @@ public:
template <typename Iter>
bool parse_object_item(picojson::input<Iter>& in, const std::string& key) {
Object& object = value->as<Object>();
- ParseContext context(&object.values[key]);
+ ParseContext context(&object.values[key], depth);
return picojson::_parse(context, in);
}
+ bool parse_object_stop() {
+ ++depth;
+ return true;
+ }
+
Value* value;
+ size_t depth;
};
} // namespace internal {
diff --git a/3rdparty/stout/tests/json_tests.cpp b/3rdparty/stout/tests/json_tests.cpp
index ee44edf..7a33579 100644
--- a/3rdparty/stout/tests/json_tests.cpp
+++ b/3rdparty/stout/tests/json_tests.cpp
@@ -795,3 +795,24 @@ TEST(JsonTest, ContainsObject)
"}");
EXPECT_FALSE(nested.contains(nestedTest.get()));
}
+
+
+TEST(JsonTest, NestingDepth)
+{
+ const size_t depth = 500000;
+
+ string deeplyNested;
+
+ for (size_t i = 0; i < depth; ++i) {
+ deeplyNested += "[";
+ }
+
+ deeplyNested += "42";
+
+ for (size_t i = 0; i < depth; ++i) {
+ deeplyNested += "]";
+ }
+
+ Try<JSON::Value> parsed = JSON::parse(deeplyNested);
+ ASSERT_ERROR(parsed); // Maximum depth exceeded.
+}