From: Michal 'vorner' Vaner Date: Tue, 30 Oct 2012 10:39:22 +0000 (+0100) Subject: [2383] Basic parsing in the new Name constructor X-Git-Tag: trac2487_base~21^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d2205ed3fc327862a0e3a7169e0432f221d514b;p=thirdparty%2Fkea.git [2383] Basic parsing in the new Name constructor We only call the same parsing as from within the old constructor. No appending of origin is done. Also, no checking some data came, so the tests not only fail, but also segfault. --- diff --git a/src/lib/dns/name.cc b/src/lib/dns/name.cc index 36d9d6dc8c..fdb4ea4e13 100644 --- a/src/lib/dns/name.cc +++ b/src/lib/dns/name.cc @@ -133,11 +133,12 @@ typedef enum { // The parser of name from a string. It is a template, because // some parameters are used with two different types, while others // are private type aliases. -template +template void -stringParse(const String& namestring, Iterator s, Iterator send, - bool downcase, Offsets& offsets, Data& ndata) +stringParse(Iterator s, Iterator send, bool downcase, Offsets& offsets, + Data& ndata) { + const Iterator orig_s(s); // // Initialize things to make the compiler happy; they're not required. // @@ -150,6 +151,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, // bool done = false; bool is_root = false; + const bool empty = s == send; ft_state state = ft_init; // Prepare the output buffers. @@ -173,7 +175,8 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (c == '.') { if (s != send) { isc_throw(EmptyLabel, - "non terminating empty label in " << namestring); + "non terminating empty label in " << + string(orig_s, send)); } is_root = true; } else if (c == '@' && s == send) { @@ -202,7 +205,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (c == '.') { if (count == 0) { isc_throw(EmptyLabel, - "duplicate period in " << namestring); + "duplicate period in " << string(orig_s, send)); } ndata.at(offsets.back()) = count; offsets.push_back(ndata.size()); @@ -216,7 +219,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, } else { if (++count > Name::MAX_LABELLEN) { isc_throw(TooLongLabel, - "label is too long in " << namestring); + "label is too long in " << string(orig_s, send)); } ndata.push_back(downcase ? maptolower[c] : c); } @@ -226,7 +229,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, // This looks like a bitstring label, which was deprecated. // Intentionally drop it. isc_throw(BadLabelType, - "invalid label type in " << namestring); + "invalid label type in " << string(orig_s, send)); } state = ft_escape; // FALLTHROUGH @@ -234,7 +237,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (!isdigit(c & 0xff)) { if (++count > Name::MAX_LABELLEN) { isc_throw(TooLongLabel, - "label is too long in " << namestring); + "label is too long in " << string(orig_s, send)); } ndata.push_back(downcase ? maptolower[c] : c); state = ft_ordinary; @@ -248,7 +251,7 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (!isdigit(c & 0xff)) { isc_throw(BadEscape, "mixture of escaped digit and non-digit in " - << namestring); + << string(orig_s, send)); } value *= 10; value += digitvalue[c]; @@ -257,11 +260,11 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (value > 255) { isc_throw(BadEscape, "escaped decimal is too large in " - << namestring); + << string(orig_s, send)); } if (++count > Name::MAX_LABELLEN) { isc_throw(TooLongLabel, - "label is too long in " << namestring); + "label is too long in " << string(orig_s, send)); } ndata.push_back(downcase ? maptolower[value] : value); state = ft_ordinary; @@ -276,13 +279,14 @@ stringParse(const String& namestring, Iterator s, Iterator send, if (!done) { // no trailing '.' was found. if (ndata.size() == Name::MAX_WIRE) { isc_throw(TooLongName, - "name is too long for termination in " << namestring); + "name is too long for termination in " << + string(orig_s, send)); } assert(s == send); if (state != ft_ordinary && state != ft_at) { isc_throw(IncompleteName, "incomplete textual name in " << - (namestring.empty() ? "" : namestring)); + (empty ? "" : string(orig_s, send))); } if (state == ft_ordinary) { assert(count != 0); @@ -299,15 +303,15 @@ stringParse(const String& namestring, Iterator s, Iterator send, Name::Name(const std::string &namestring, bool downcase) { // Prepare inputs for the parser - std::string::const_iterator s = namestring.begin(); - std::string::const_iterator send = namestring.end(); + const std::string::const_iterator s = namestring.begin(); + const std::string::const_iterator send = namestring.end(); // Prepare outputs NameOffsets offsets; NameString ndata; // To the parsing - stringParse(namestring, s, send, downcase, offsets, ndata); + stringParse(s, send, downcase, offsets, ndata); // And get the output labelcount_ = offsets.size(); @@ -317,6 +321,25 @@ Name::Name(const std::string &namestring, bool downcase) { offsets_.assign(offsets.begin(), offsets.end()); } +Name::Name(const char* namedata, size_t data_len, const Name*, bool downcase) { + // Prepare inputs for the parser + const char* end = namedata + data_len; + + // Prepare outputs + NameOffsets offsets; + NameString ndata; + + // Do the actual parsing + stringParse(namedata, end, downcase, offsets, ndata); + + // Get the output + labelcount_ = offsets.size(); + assert(labelcount_ > 0 && labelcount_ <= Name::MAX_LABELS); + ndata_.assign(ndata.data(), ndata.size()); + length_ = ndata_.size(); + offsets_.assign(offsets.begin(), offsets.end()); +} + namespace { /// /// Wire-format name parser states. diff --git a/src/lib/dns/tests/name_unittest.cc b/src/lib/dns/tests/name_unittest.cc index 51e0e997fd..d2a16847fa 100644 --- a/src/lib/dns/tests/name_unittest.cc +++ b/src/lib/dns/tests/name_unittest.cc @@ -157,14 +157,11 @@ checkBadTextName(const string& txt) { // NameParserException. EXPECT_THROW(Name(txt, false), ExceptionType); EXPECT_THROW(Name(txt, false), NameParserException); -#if 0 - // TODO: Enable once the new constructor exists. // The same is thrown when constructing by the master-file constructor EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()), ExceptionType); EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()), NameParserException); -#endif } TEST_F(NameTest, fromText) { @@ -239,8 +236,6 @@ TEST_F(NameTest, fromText) { EXPECT_EQ(Name::MAX_LABELS, maxlabels.getLabelCount()); } -#if 0 -// TODO: Enable once the constructor exists, there's a need to test the changes // on the rest while we prepare it. // Check the @ syntax is accepted and it just copies the origin. TEST_F(NameTest, copyOrigin) { @@ -255,12 +250,12 @@ TEST_F(NameTest, copyOrigin) { // Test the master-file constructor does not append the origin when the // provided name is absolute TEST_F(NameTest, dontAppendOrigin) { - EXPECT_EQ(example_name, Name("www.example.org.", 16, &origin_name)); + EXPECT_EQ(example_name, Name("www.example.com.", 16, &origin_name)); // The downcase works (only if provided, though) - EXPECT_EQ(example_name, Name("WWW.EXAMPLE.ORG.", 16, &origin_name, true)); - EXPECT_EQ(example_name_upper, Name("WWW.EXAMPLE.ORG.", 16, &origin_name)); + EXPECT_EQ(example_name, Name("WWW.EXAMPLE.COM.", 16, &origin_name, true)); + EXPECT_EQ(example_name_upper, Name("WWW.EXAMPLE.COM.", 16, &origin_name)); // And it does not require the origin to be provided - EXPECT_NO_THROW(Name("www.example.org.", 16, NULL)); + EXPECT_NO_THROW(Name("www.example.com.", 16, NULL)); } // Test the master-file constructor properly appends the origin when @@ -272,7 +267,7 @@ TEST_F(NameTest, appendOrigin) { EXPECT_EQ(example_name, Name("WWW", 3, &origin_name_upper, true)); EXPECT_EQ(example_name_upper, Name("WWW", 3, &origin_name_upper)); // Check we can prepend more than one label - EXPECT_EQ(Name("a.b.c.d.example.org."), Name("a.b.c.d", 7, &origin_name)); + EXPECT_EQ(Name("a.b.c.d.example.com."), Name("a.b.c.d", 7, &origin_name)); // When the name is relative, we throw. EXPECT_THROW(Name("www", 3, NULL), MissingNameOrigin); } @@ -299,7 +294,6 @@ TEST_F(NameTest, combinedTooLong) { EXPECT_NO_THROW(Name(max_labels_str, strlen(max_labels_str), &Name::ROOT_NAME())); } -#endif TEST_F(NameTest, fromWire) { //