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.
+}