Commit 8d2205ed authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[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.
parent 67500d3b
......@@ -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<class String, class Iterator, class Offsets, class Data>
template<class Iterator, class Offsets, class Data>
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() ? "<empty>" : namestring));
(empty ? "<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.
......
......@@ -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) {
//
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment