BIND 10 master, updated. 0770d2df84e5608371db3a47e0456eb2a340b5f4 Merge branch 'trac2426'
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Feb 19 08:46:55 UTC 2014
The branch, master has been updated
via 0770d2df84e5608371db3a47e0456eb2a340b5f4 (commit)
via acb20abee749563f5de98d582825f29b39046f11 (commit)
via 5c94286b3fcf47697829b2edba32cd47ed090bd6 (commit)
via 1233aa6063c1790b69247fa96790651742d27c12 (commit)
via 8ec8a19d2342170d7deb9ee771c157eb439bc278 (commit)
via 659fb323f0b7fdd279cc1c36b0f5fe6526a0994e (commit)
via 4976235a26688d12d2c2a51f13ef66dc38ff9ee9 (commit)
from 91867e0886ec2511053bf0fd25f8cfb9fbfda1d4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 0770d2df84e5608371db3a47e0456eb2a340b5f4
Merge: 91867e0 acb20ab
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Feb 19 14:07:13 2014 +0530
Merge branch 'trac2426'
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/rdata.cc | 133 ++++++++++++++++++-----------------
src/lib/dns/rdata.h | 2 +-
src/lib/dns/tests/rdata_unittest.cc | 6 +-
3 files changed, 74 insertions(+), 67 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/rdata.cc b/src/lib/dns/rdata.cc
index ff95fee..a34f887 100644
--- a/src/lib/dns/rdata.cc
+++ b/src/lib/dns/rdata.cc
@@ -15,6 +15,7 @@
#include <exceptions/exceptions.h>
#include <util/buffer.h>
+#include <util/encode/hex.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
@@ -220,94 +221,100 @@ Generic::Generic(isc::util::InputBuffer& buffer, size_t rdata_len) {
impl_ = new GenericImpl(data);
}
-void
-Generic::constructHelper(const std::string& rdata_string) {
- istringstream iss(rdata_string);
- string unknown_mark;
- iss >> unknown_mark;
- if (unknown_mark != "\\#") {
+GenericImpl*
+Generic::constructFromLexer(MasterLexer& lexer) {
+ const MasterToken& token = lexer.getNextToken(MasterToken::STRING);
+ if (token.getString() != "\\#") {
isc_throw(InvalidRdataText,
- "Missing the special token (\\#) for generic RDATA encoding");
+ "Missing the special token (\\#) for "
+ "unknown RDATA encoding");
}
- // RDLENGTH: read into a string so that we can easily reject invalid tokens
- string rdlen_txt;
- iss >> rdlen_txt;
- istringstream iss_rdlen(rdlen_txt);
- int32_t rdlen;
- iss_rdlen >> rdlen;
- if (iss_rdlen.rdstate() != ios::eofbit) {
- isc_throw(InvalidRdataText,
- "Invalid representation for a generic RDLENGTH");
+ // Initialize with an absurd value.
+ uint32_t rdlen = 65536;
+
+ try {
+ rdlen = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataLength,
+ "Unknown RDATA length is invalid");
}
- if (rdlen < 0 || rdlen > 0xffff) {
- isc_throw(InvalidRdataLength, "RDATA length is out of range");
+
+ if (rdlen > 65535) {
+ isc_throw(InvalidRdataLength,
+ "Unknown RDATA length is out of range: " << rdlen);
}
- iss >> ws; // skip any white spaces
- // Hexadecimal encoding of RDATA: each segment must consist of an even
- // number of hex digits.
vector<uint8_t> data;
- while (!iss.eof() && data.size() < rdlen) {
- // extract two characters, which should compose a single byte of data.
- char buf[2];
- iss.read(buf, sizeof(buf));
- if ((iss.rdstate() & (ios::badbit | ios::failbit)) != 0) {
- isc_throw(InvalidRdataText,
- "Invalid hex encoding of generic RDATA");
+
+ if (rdlen > 0) {
+ string hex_txt;
+ string hex_part;
+ // Whitespace is allowed within hex data, so read to the end of input.
+ while (true) {
+ const MasterToken& token =
+ lexer.getNextToken(MasterToken::STRING, true);
+ if ((token.getType() == MasterToken::END_OF_FILE) ||
+ (token.getType() == MasterToken::END_OF_LINE)) {
+ // Unget the last read token as createRdata() expects us
+ // to leave it at the end-of-line or end-of-file when we
+ // return.
+ lexer.ungetToken();
+ break;
+ }
+ token.getString(hex_part);
+ hex_txt.append(hex_part);
}
- // convert it to a single byte integer as a hex digit.
- istringstream iss_byte(string(buf, sizeof(buf)));
- unsigned int ch;
- iss_byte >> hex >> ch;
- if (iss_byte.rdstate() != ios::eofbit) {
+ try {
+ isc::util::encode::decodeHex(hex_txt, data);
+ } catch (const isc::BadValue& ex) {
isc_throw(InvalidRdataText,
- "Invalid hex encoding of generic RDATA");
+ "Invalid hex encoding of generic RDATA: " << ex.what());
}
- data.push_back(ch);
- iss >> ws; // skip spaces
- }
-
- if (!iss.eof()) {
- isc_throw(InvalidRdataLength,
- "RDLENGTH is too small for generic RDATA");
}
if (data.size() != rdlen) {
isc_throw(InvalidRdataLength,
- "Generic RDATA code doesn't match RDLENGTH");
+ "Size of unknown RDATA hex data doesn't match RDLENGTH: "
+ << data.size() << " vs. " << rdlen);
}
- impl_ = new GenericImpl(data);
+ return (new GenericImpl(data));
}
-Generic::Generic(const std::string& rdata_string) {
- constructHelper(rdata_string);
-}
-
-Generic::Generic(MasterLexer& lexer, const Name*,
- MasterLoader::Options,
- MasterLoaderCallbacks&)
+Generic::Generic(const std::string& rdata_string) :
+ impl_(NULL)
{
- std::string s;
+ // We use auto_ptr here because if there is an exception in this
+ // constructor, the destructor is not called and there could be a
+ // leak of the GenericImpl that constructFromLexer() returns.
+ std::auto_ptr<GenericImpl> impl_ptr(NULL);
- while (true) {
- const MasterToken& token = lexer.getNextToken();
- if ((token.getType() == MasterToken::END_OF_FILE) ||
- (token.getType() == MasterToken::END_OF_LINE)) {
- lexer.ungetToken(); // let the upper layer handle the end-of token
- break;
- }
+ try {
+ std::istringstream ss(rdata_string);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
- if (!s.empty()) {
- s += " ";
- }
+ impl_ptr.reset(constructFromLexer(lexer));
- s += token.getString();
+ if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+ isc_throw(InvalidRdataText, "extra input text for unknown RDATA: "
+ << rdata_string);
+ }
+ } catch (const MasterLexer::LexerError& ex) {
+ isc_throw(InvalidRdataText, "Failed to construct unknown RDATA "
+ "from '" << rdata_string << "': " << ex.what());
}
- constructHelper(s);
+ impl_ = impl_ptr.release();
+}
+
+Generic::Generic(MasterLexer& lexer, const Name*,
+ MasterLoader::Options,
+ MasterLoaderCallbacks&) :
+ impl_(constructFromLexer(lexer))
+{
}
Generic::~Generic() {
diff --git a/src/lib/dns/rdata.h b/src/lib/dns/rdata.h
index 67ff079..eb07937 100644
--- a/src/lib/dns/rdata.h
+++ b/src/lib/dns/rdata.h
@@ -393,7 +393,7 @@ public:
//@}
private:
- void constructHelper(const std::string& rdata_string);
+ GenericImpl* constructFromLexer(MasterLexer& lexer);
GenericImpl* impl_;
};
diff --git a/src/lib/dns/tests/rdata_unittest.cc b/src/lib/dns/tests/rdata_unittest.cc
index f2810ac..f29b61c 100644
--- a/src/lib/dns/tests/rdata_unittest.cc
+++ b/src/lib/dns/tests/rdata_unittest.cc
@@ -301,14 +301,14 @@ TEST_F(Rdata_Unknown_Test, createFromText) {
// the length should be 16-bit unsigned integer
EXPECT_THROW(generic::Generic("\\# 65536 a1b2c30d"), InvalidRdataLength);
EXPECT_THROW(generic::Generic("\\# -1 a1b2c30d"), InvalidRdataLength);
- EXPECT_THROW(generic::Generic("\\# 1.1 a1"), InvalidRdataText);
+ EXPECT_THROW(generic::Generic("\\# 1.1 a1"), InvalidRdataLength);
EXPECT_THROW(generic::Generic("\\# 0a 00010203040506070809"),
- InvalidRdataText);
+ InvalidRdataLength);
// should reject if the special token is missing.
EXPECT_THROW(generic::Generic("4 a1b2c30d"), InvalidRdataText);
// the special token, the RDLENGTH and the data must be space separated.
EXPECT_THROW(generic::Generic("\\#0"), InvalidRdataText);
- EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataText);
+ EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataLength);
}
TEST_F(Rdata_Unknown_Test, createFromWire) {
More information about the bind10-changes
mailing list