diff options
author | Thomas Markwalder <tmark@isc.org> | 2019-08-01 20:40:49 +0200 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2019-08-15 17:41:18 +0200 |
commit | 65d268ce8a2b2974a12a965294870b1f38bbea0f (patch) | |
tree | 951b1bd3555dbe8a55e9ce0f97896d541e12c261 /src/lib | |
parent | [#721,!466] ChangeLog updated. (diff) | |
download | kea-65d268ce8a2b2974a12a965294870b1f38bbea0f.tar.xz kea-65d268ce8a2b2974a12a965294870b1f38bbea0f.zip |
[#761,!447] Binary option data parser now accepts strings
src/lib/dhcpsrv/parsers/option_data_parser.cc
OptionDataParser::createOption() - added logic to support
parsing "'text'" into binary option data
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc
TEST_F(ParseConfigTest, stringOrHexBinaryData) - new unit test
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/dhcpsrv/parsers/option_data_parser.cc | 11 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc | 106 |
2 files changed, 113 insertions, 4 deletions
diff --git a/src/lib/dhcpsrv/parsers/option_data_parser.cc b/src/lib/dhcpsrv/parsers/option_data_parser.cc index 99177fae05..ae79505517 100644 --- a/src/lib/dhcpsrv/parsers/option_data_parser.cc +++ b/src/lib/dhcpsrv/parsers/option_data_parser.cc @@ -299,10 +299,15 @@ OptionDataParser::createOption(ConstElementPtr option_data) { data_tokens = isc::util::str::tokens(data_param, ",", true); } else { - // Otherwise, the option data is specified as a string of - // hexadecimal digits that we have to turn into binary format. + // Try to convert the values in quotes into a vector of ASCII codes. + // If the identifier lacks opening and closing quote, this will return + // an empty value, in which case we'll try to decode it as a string of + // hexadecimal digits. try { - util::str::decodeFormattedHexString(data_param, binary); + binary = util::str::quotedStringToBinary(data_param); + if (binary.empty()) { + util::str::decodeFormattedHexString(data_param, binary); + } } catch (...) { isc_throw(DhcpConfigError, "option data is not a valid" << " string of hexadecimal digits: " << data_param diff --git a/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc b/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc index 85f3d7436b..4dc4da40cf 100644 --- a/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc +++ b/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc @@ -421,7 +421,6 @@ public: // If error was reported, the error string should contain // position of the data element which caused failure. if (rcode_ != 0) { - std::cout << "Error text:" << error_text_ << std::endl; EXPECT_TRUE(errorContainsPosition(status, "<string>")); } } @@ -1722,6 +1721,111 @@ TEST_F(ParseConfigTest, hexOptionData) { } } +// Verifies that binary option data can be configured with either +// "'strings'" or hex literals. +TEST_F(ParseConfigTest, stringOrHexBinaryData) { + // Structure the defines a given test scenario + struct Scenario { + std::string description_; // describes the scenario for logging + std::string str_data_; // configured data value of the option + std::vector<uint8_t> exp_binary_; // expected parsed binary data + std::string exp_error_; // expected error test for invalid input + }; + + // Convenience value to use for initting valid scenarios + std::string no_error(""); + + // Valid and invalid scenarios we will test. + // Note we are not concerned with the varitions of valid or invalid + // hex literals those are tested elsewhere. + std::vector<Scenario> scenarios = { + { + "valid hex digits", + "0C:00:03:01:C0:00:03:02", + {0x0C,0x00,0x03,0x01,0xC0,0x00,0x03,0x02}, + no_error + }, + { + "valid string", + "'abcdefghijk'", + {0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B}, + no_error + }, + { + "valid empty", + "", + {}, + no_error + }, + { + "invalid empty", + "''", + {}, + "Configuration parsing failed: option data is not a valid string" + " of hexadecimal digits: '' (<string>:7:13)" + }, + { + "missing end quote", + "'abcdefghijk", + {}, + "Configuration parsing failed: option data is not a valid string" + " of hexadecimal digits: 'abcdefghijk (<string>:7:13)" + }, + { + "missing open quote", + "abcdefghijk'", + {}, + "Configuration parsing failed: option data is not a valid string" + " of hexadecimal digits: abcdefghijk' (<string>:7:13)" + }, + { + "no quotes", + "abcdefghijk", + {}, + "Configuration parsing failed: option data is not a valid string" + " of hexadecimal digits: abcdefghijk (<string>:7:13)" + } + }; + + // Iterate over our test scenarios + for (auto scenario : scenarios) { + SCOPED_TRACE(scenario.description_); + { + // Build the configuration text. + ostringstream os; + os << + "{ \n" + " \"option-data\": [ { \n" + " \"name\": \"user-class\", \n" + " \"code\": 77, \n" + " \"space\": \"dhcp4\", \n" + " \"csv-format\": false, \n" + " \"data\": \"" << scenario.str_data_ << "\" \n" + " } ] \n" + "} \n"; + + // Attempt to parse it. + reset_context(AF_INET); + int rcode = 0; + ASSERT_NO_THROW(rcode = parseConfiguration(os.str(), true)); + + if (!scenario.exp_error_.empty()) { + // We expected to fail, did we? + ASSERT_NE(0, rcode); + // Did we fail for the reason we think we should? + EXPECT_EQ(error_text_, scenario.exp_error_); + } else { + // We expected to succeed, did we? + ASSERT_EQ(0, rcode); + OptionPtr opt = getOptionPtr(DHCP4_OPTION_SPACE, 77); + ASSERT_TRUE(opt); + // Verify the parsed data is correct. + EXPECT_EQ(opt->getData(), scenario.exp_binary_); + } + } + } +} + /// The next set of tests check basic operation of the HooksLibrariesParser. // |