Commit d7a95471 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[trac117] handled empty type bitmap correctly. added tests for this case.

the original "from wire" code was actually buggy, too, and it's now fixed.
parent 17832da8
......@@ -64,10 +64,8 @@ NSEC3::NSEC3(const string& nsec3_str) :
istringstream iss(nsec3_str);
unsigned int hashalg, flags, iterations;
string iterations_str, salthex, nexthash;
stringbuf bitmaps;
iss >> hashalg >> flags >> iterations_str >> salthex >> nexthash
>> &bitmaps;
iss >> hashalg >> flags >> iterations_str >> salthex >> nexthash;
if (iss.bad() || iss.fail()) {
isc_throw(InvalidRdataText, "Invalid NSEC3 text: " << nsec3_str);
}
......@@ -107,15 +105,20 @@ NSEC3::NSEC3(const string& nsec3_str) :
<< next.size() << " bytes");
}
stringstream bitmap_stream(bitmaps.str());
uint8_t bitmap[8 * 1024]; // 64k bits
vector<uint8_t> typebits;
// For NSEC3 empty bitmap is possible and allowed.
if (iss.eof()) {
impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next,
vector<uint8_t>());
return;
}
vector<uint8_t> typebits;
uint8_t bitmap[8 * 1024]; // 64k bits
memset(bitmap, 0, sizeof(bitmap));
do {
string type;
int code;
bitmap_stream >> type;
iss >> type;
if (type.length() != 0) {
try {
code = RRType(type).getCode();
......@@ -124,7 +127,7 @@ NSEC3::NSEC3(const string& nsec3_str) :
isc_throw(InvalidRdataText, "Invalid RRtype in NSEC3");
}
}
} while (!bitmap_stream.eof());
} while (!iss.eof());
for (int window = 0; window < 256; window++) {
int octet;
......@@ -171,7 +174,7 @@ NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
const uint8_t nextlen = buffer.readUint8();
--rdata_len;
if (nextlen == 0 || rdata_len <= nextlen) {
if (nextlen == 0 || rdata_len < nextlen) {
isc_throw(DNSMessageFORMERR, "NSEC3 invalid hash length: " <<
static_cast<unsigned int>(nextlen));
}
......@@ -181,8 +184,12 @@ NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
rdata_len -= nextlen;
vector<uint8_t> typebits(rdata_len);
buffer.readData(&typebits[0], rdata_len);
checkRRTypeBitmaps("NSEC3", typebits);
if (rdata_len > 0) {
// Read and parse the bitmaps only when they exist; empty bitmap
// is possible for NSEC3.
buffer.readData(&typebits[0], rdata_len);
checkRRTypeBitmaps("NSEC3", typebits);
}
impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
}
......
......@@ -71,6 +71,9 @@ TEST_F(Rdata_NSEC3_Test, fromText) {
EXPECT_EQ(255, generic::NSEC3("1 1 1 D399EAAB " +
string((255 * 8) / 5, '0') +
" NS").getNext().size());
// type bitmap is empty. it's possible and allowed for NSEC3.
generic::NSEC3("1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6");
}
TEST_F(Rdata_NSEC3_Test, toText) {
......@@ -79,10 +82,6 @@ TEST_F(Rdata_NSEC3_Test, toText) {
}
TEST_F(Rdata_NSEC3_Test, badText) {
// Bitmap is missing
EXPECT_THROW(generic::NSEC3(
"1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6"),
InvalidRdataText);
EXPECT_THROW(generic::NSEC3("1 1 1 ADDAFEEE "
"0123456789ABCDEFGHIJKLMNOPQRSTUV "
"BIFF POW SPOON"),
......@@ -131,6 +130,10 @@ TEST_F(Rdata_NSEC3_Test, createFromWire) {
*rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
"rdata_nsec3_fromWire1")));
// A valid NSEC3 RR with empty type bitmap.
EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
"rdata_nsec3_fromWire15.wire"));
// Too short RDLENGTH: it doesn't even contain the first 5 octets.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
"rdata_nsec3_fromWire2.wire"),
......
......@@ -14,7 +14,7 @@ BUILT_SOURCES += rdata_nsec3_fromWire6.wire rdata_nsec3_fromWire7.wire
BUILT_SOURCES += rdata_nsec3_fromWire8.wire rdata_nsec3_fromWire9.wire
BUILT_SOURCES += rdata_nsec3_fromWire10.wire rdata_nsec3_fromWire11.wire
BUILT_SOURCES += rdata_nsec3_fromWire12.wire rdata_nsec3_fromWire13.wire
BUILT_SOURCES += rdata_nsec3_fromWire14.wire
BUILT_SOURCES += rdata_nsec3_fromWire14.wire rdata_nsec3_fromWire15.wire
BUILT_SOURCES += rdata_rrsig_fromWire2.wire
BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
......@@ -63,7 +63,7 @@ EXTRA_DIST += rdata_nsec3_fromWire6.spec rdata_nsec3_fromWire7.spec
EXTRA_DIST += rdata_nsec3_fromWire8.spec rdata_nsec3_fromWire9.spec
EXTRA_DIST += rdata_nsec3_fromWire10.spec rdata_nsec3_fromWire11.spec
EXTRA_DIST += rdata_nsec3_fromWire12.spec rdata_nsec3_fromWire13.spec
EXTRA_DIST += rdata_nsec3_fromWire14.spec
EXTRA_DIST += rdata_nsec3_fromWire14.spec rdata_nsec3_fromWire15.spec
EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
EXTRA_DIST += rdata_rrsig_fromWire2.spec
EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec
......
#
# NSEC3 RDATA with empty type bitmap. It's okay.
# The test data includes bytes for a bitmap field, but RDLEN indicates
# it's not part of the RDATA and so it will be ignored.
#
[custom]
sections: nsec3
[nsec3]
rdlen: 31
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