]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5513] Added PR#61 fix
authorFrancis Dupont <fdupont@isc.org>
Sat, 20 Jan 2018 20:56:09 +0000 (21:56 +0100)
committerFrancis Dupont <fdupont@isc.org>
Sat, 20 Jan 2018 20:56:09 +0000 (21:56 +0100)
src/bin/admin/kea-admin.in
src/lib/cc/json_feed.cc
src/lib/cc/json_feed.h
src/lib/cc/tests/json_feed_unittests.cc

index 7613dfafa686b46255ae349303f6ec9afec76947..648f49fede64e0ffdb5554e836d50a0a21a3d585 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -448,7 +448,7 @@ mysql_dump() {
 ### Functions used for dump
 pgsql_dump() {
     # Check the lease type was given
-    if [ $dump_type -eq o ]; then
+    if [ $dump_type -eq 0 ]; then
         log_error "lease-dump: lease type ( -4 or -6 ) needs to be specified"
         usage
         exit 1
index 2bb2b6e5fdf9597e0cae25babef497f50ed04e9e..269d896c3a1db773d4fcce8063b1f50c0c65e51e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,6 +18,8 @@ const int JSONFeed::RECEIVE_START_ST;
 const int JSONFeed::WHITESPACE_BEFORE_JSON_ST;
 const int JSONFeed::JSON_START_ST;
 const int JSONFeed::INNER_JSON_ST;
+const int JSONFeed::STRING_JSON_ST;
+const int JSONFeed::ESCAPE_JSON_ST;
 const int JSONFeed::JSON_END_ST;
 const int JSONFeed::FEED_OK_ST;
 const int JSONFeed::FEED_FAILED_ST;
@@ -135,6 +137,10 @@ JSONFeed::defineStates() {
                 boost::bind(&JSONFeed::whiteSpaceBeforeJSONHandler, this));
     defineState(INNER_JSON_ST, "INNER_JSON_ST",
                 boost::bind(&JSONFeed::innerJSONHandler, this));
+    defineState(STRING_JSON_ST, "STRING_JSON_ST",
+                boost::bind(&JSONFeed::stringJSONHandler, this));
+    defineState(ESCAPE_JSON_ST, "ESCAPE_JSON_ST",
+                boost::bind(&JSONFeed::escapeJSONHandler, this));
     defineState(JSON_END_ST, "JSON_END_ST",
                 boost::bind(&JSONFeed::endJSONHandler, this));
 }
@@ -227,6 +233,8 @@ JSONFeed::receiveStartHandler() {
                 transition(INNER_JSON_ST, DATA_READ_OK_EVT);
                 return;
 
+            // Cannot start by a string
+            case '"':
             default:
                 feedFailure("invalid first character " + std::string(1, c));
                 break;
@@ -257,6 +265,8 @@ JSONFeed::whiteSpaceBeforeJSONHandler() {
             transition(INNER_JSON_ST, DATA_READ_OK_EVT);
             break;
 
+        // Cannot start by a string
+        case '"':
         default:
             feedFailure("invalid character " + std::string(1, c));
         }
@@ -286,12 +296,47 @@ JSONFeed::innerJSONHandler() {
             }
             break;
 
+        case '"':
+            transition(STRING_JSON_ST, DATA_READ_OK_EVT);
+            break;
+
         default:
             transition(getCurrState(), DATA_READ_OK_EVT);
         }
     }
 }
 
+void
+JSONFeed::stringJSONHandler() {
+    char c = getNextFromBuffer();
+    if (getNextEvent() != NEED_MORE_DATA_EVT) {
+        output_.push_back(c);
+
+        switch(c) {
+        case '"':
+            transition(INNER_JSON_ST, DATA_READ_OK_EVT);
+            break;
+
+        case '\\':
+            transition(ESCAPE_JSON_ST, DATA_READ_OK_EVT);
+            break;
+
+        default:
+            transition(getCurrState(), DATA_READ_OK_EVT);
+        }
+    }
+}
+
+void
+JSONFeed::escapeJSONHandler() {
+    char c = getNextFromBuffer();
+    if (getNextEvent() != NEED_MORE_DATA_EVT) {
+        output_.push_back(c);
+
+        transition(STRING_JSON_ST, DATA_READ_OK_EVT);
+    }
+}
+
 void
 JSONFeed::endJSONHandler() {
     switch (getNextEvent()) {
index 11c4dfac12d607f2c39da80ffc3ff0fccfc0674d..5ebef68f14d24d63516caa1d79dc4b6ba75515cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -56,6 +56,10 @@ public:
 /// is decreased. When the counter is decreased to 0 it indicates that the
 /// entire JSON structure has been received and processed.
 ///
+/// As '{', '}', '[' and ']' can be embedded in JSON strings two states
+/// for strings and escape in strings are required. Note the processing
+/// of escapes is greatly simplified compared to ECMA 404 figure 5.
+
 /// Note that this mechanism doesn't check if the JSON structure is well
 /// formed. It merely detects the end of the JSON structure if this structure
 /// is well formed. The structure is validated when @ref JSONFeed::toElement
@@ -80,8 +84,14 @@ public:
     /// @brief Parsing JSON.
     static const int INNER_JSON_ST = SM_DERIVED_STATE_MIN + 4;
 
+    /// @brief Parsing JSON string.
+    static const int STRING_JSON_ST = SM_DERIVED_STATE_MIN + 5;
+
+    /// @brief JSON escape next character.
+    static const int ESCAPE_JSON_ST = SM_DERIVED_STATE_MIN + 6;
+
     /// @brief Found last closing brace or square bracket.
-    static const int JSON_END_ST = SM_DERIVED_STATE_MIN + 5;
+    static const int JSON_END_ST = SM_DERIVED_STATE_MIN + 7;
 
     /// @brief Found opening and closing brace or square bracket.
     ///
@@ -248,9 +258,15 @@ private:
     /// @brief Handler for WHITESPACE_BEFORE_JSON_ST.
     void whiteSpaceBeforeJSONHandler();
 
-    /// @brief Handle for the FIRST_BRACE_ST.
+    /// @brief Handler for the FIRST_BRACE_ST.
     void innerJSONHandler();
 
+    /// @brief Handler for the STRING_JSON_ST.
+    void stringJSONHandler();
+
+    /// @brief Handler for the ESCAPE_JSON_ST;
+    void escapeJSONHandler();
+
     /// @brief Handler for the JSON_END_ST.
     void endJSONHandler();
 
index e289757d00e93d14ba25e12a5253a6fd5f52f95d..5f8b64ea68a460bc591812fa0da521f1d5421260 100644 (file)
@@ -171,4 +171,20 @@ TEST_F(JSONFeedTest, noOpeningSquareBracket) {
     testInvalidRead(json);
 }
 
+// This test verifies that a string is correctly handled
+TEST_F(JSONFeedTest, string) {
+    std::string json = "{ \"braces\": \"}}}}\" }";
+    ElementPtr expected = Element::createMap();
+    expected->set("braces", Element::create("}}}}"));
+    testRead(json, expected);
+}
+
+// This test verifies that a string with escapes is correctly handled
+TEST_F(JSONFeedTest, escape) {
+    std::string json = "{ \"escapes\": \"\\n\\t\\\"\\\" }";
+    ElementPtr expected = Element::createMap();
+    expected->set("escapes", Element::create("\\n\\t\\\"\\"));
+    testRead(json, expected);
+}
+
 } // end of anonymous namespace.