#!/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
### 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
-// 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
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;
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));
}
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;
transition(INNER_JSON_ST, DATA_READ_OK_EVT);
break;
+ // Cannot start by a string
+ case '"':
default:
feedFailure("invalid character " + std::string(1, c));
}
}
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()) {
-// 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
/// 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
/// @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.
///
/// @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();
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.