@@ -109,7 +109,7 @@ class StreamingJsonParser {
109109 };
110110
111111 StreamingJsonParser (bool strict_mode = false )
112- : state(START), strict_mode(strict_mode), result(new JsonObject()) {
112+ : state(START), strict_mode(strict_mode), result(std::make_unique< JsonObject> ()) {
113113 // Initialize the expected characters for each state
114114 expected_chars[START] = " {" ;
115115 expected_chars[EXPECT_KEY_OR_END] = " \" }" ;
@@ -151,6 +151,8 @@ class StreamingJsonParser {
151151
152152private:
153153 std::unique_ptr<JsonValue> result;
154+ // Holds a stack of pointers to JsonObjects, make sure that pointers pushed
155+ // here have lifetimes that exceed the time on stack.
154156 std::vector<JsonObject*> stack;
155157 State state;
156158 std::string current_key;
@@ -212,12 +214,20 @@ class StreamingJsonParser {
212214
213215 case EXPECT_VALUE:
214216 if (c == ' "' ) {
217+ // we know it's a string value so set cur_obj[cur_key] = ""
215218 state = IN_VALUE;
216219 current_obj->set (current_key, std::make_unique<JsonString>());
217220 } else if (c == ' {' ) {
218221 auto newObj = std::make_unique<JsonObject>();
219- JsonObject* objPtr = dynamic_cast <JsonObject*>(newObj.get ());
222+ JsonObject* objPtr = newObj.get ();
223+ // Transfer ownership of pointer to current_obj
220224 current_obj->set (current_key, std::move (newObj));
225+ // Store raw pointer (w/o ownership) on stack. current_obj has ownership
226+ // so we have to make sure that current_obj lives longer than the element
227+ // does on the stack:
228+ // This is satisifed because 1) current_obj points to result which is alive
229+ // the longest, or 2), points to the previous stack entry which by definition
230+ // of a stack will outlive it.
221231 stack.push_back (objPtr);
222232 state = EXPECT_KEY_OR_END;
223233 }
0 commit comments