--- /dev/null
+[bug] fdupont
+ Fixed the length of FQDN data fields when parsing
+ custom options. Thank you to Qifan Zhang from
+ Palo Alto Networks for reporting the issue.
+ (Gitlab #4567)
// utility function will return the size of the buffer on success.
if (data_type == OPT_FQDN_TYPE) {
try {
+ // Set the raw optional falg as we do not want escapes.
std::string fqdn =
- OptionDataTypeUtil::readFqdn(OptionBuffer(begin, end));
+ OptionDataTypeUtil::readFqdn(
+ OptionBuffer(begin, end), true);
// The size of the buffer holding an FQDN is always
// 1 byte larger than the size of the string
// representation of this FQDN.
}
std::string
-OptionDataTypeUtil::readFqdn(const std::vector<uint8_t>& buf) {
+OptionDataTypeUtil::readFqdn(const std::vector<uint8_t>& buf,
+ bool raw /* = false */) {
// If buffer is empty emit an error.
if (buf.empty()) {
isc_throw(BadDataTypeCast, "unable to read FQDN from a buffer."
// it means that the buffer doesn't hold a valid domain name (invalid
// syntax).
isc::dns::Name name(in_buf);
- return (name.toText());
+ if (!raw) {
+ return (name.toText());
+ } else {
+ return (name.toRawText());
+ }
} catch (const isc::Exception& ex) {
// Unable to convert the data in the buffer into FQDN.
isc_throw(BadDataTypeCast, ex.what());
/// section 3.1.
///
/// @param buf input buffer holding a FQDN.
+ /// @param raw raw (i.e. not escape) output.
///
/// @throw BadDataTypeCast if a FQDN stored within a buffer is
/// invalid (e.g. empty, contains invalid characters, truncated).
/// @return fully qualified domain name in a text form.
- static std::string readFqdn(const std::vector<uint8_t>& buf);
+ static std::string readFqdn(const std::vector<uint8_t>& buf,
+ bool raw = false);
/// @brief Append FQDN into a buffer.
///
Option::lenient_parsing_ = false;
}
+// Same as the previous test but with characters which could be escaped.
+TEST_F(OptionCustomTest, fqdnRawData) {
+ OptionDefinition opt_def("option-foo", 1000, "my-space", "fqdn",
+ "option-foo-space");
+
+ const char data[] = { 1, 9, 0 }; // "<tab>."
+
+ std::vector<uint8_t> buf(data, data + sizeof(data));
+
+ boost::scoped_ptr<OptionCustom> option;
+ ASSERT_NO_THROW(option.reset(new OptionCustom(opt_def, Option::V6,
+ buf.begin(), buf.end())));
+ ASSERT_TRUE(option);
+ ASSERT_EQ(1U, option->getDataFieldsNum());
+
+ std::string domain0 = option->readFqdn(0);
+ EXPECT_EQ("\\009.", domain0);
+}
+
// The purpose of this test is to verify that the option definition comprising
// 16-bit signed integer value can be used to create an instance of custom option.
TEST_F(OptionCustomTest, int16Data) {
);
}
+// Same as the previous test but with characters which could be escaped.
+TEST_F(OptionDataTypesTest, readFqdnRaw) {
+ // The binary representation of the "<tab>.".
+ const char data[] = { 1, 9, 0 };
+
+ // Make a vector out of the data.
+ std::vector<uint8_t> buf(data, data + sizeof(data));
+
+ // Read the buffer as FQDN and verify its correctness.
+ std::string fqdn;
+ EXPECT_NO_THROW(fqdn = OptionDataTypeUtil::readFqdn(buf));
+ EXPECT_EQ("\\009.", fqdn);
+ std::string raw;
+ EXPECT_NO_THROW(raw = OptionDataTypeUtil::readFqdn(buf, true));
+ EXPECT_EQ(2U, raw.size());
+ EXPECT_EQ(9, raw[0]);
+ EXPECT_EQ('.', raw[1]);
+}
+
// The purpose of this test is to verify that FQDN's syntax is validated
// and that FQDN is correctly written to a buffer in a format described
// in RFC1035 section 3.1.