DNSName::DNSName(const char* pos, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed)
{
+ d_recurse = 0;
packetParser(pos, len, offset, uncompress, qtype, qclass, consumed);
}
labellen &= (~0xc0);
int newpos = (labellen << 8) + *(const unsigned char*)pos;
- if(newpos < offset)
+ if(newpos < offset) {
+ if (++d_recurse > 100)
+ throw std::range_error("Abort label decompression after 100 redirects");
packetParser(opos, len, newpos, true);
- else
+ } else
throw std::range_error("Found a forward reference during label decompression");
pos++;
break;
// typedef __gnu_cxx::__sso_string string_t;
typedef std::string string_t;
string_t d_storage;
+ int d_recurse;
void packetParser(const char* p, int len, int offset, bool uncompress, uint16_t* qtype=0, uint16_t* qclass=0, unsigned int* consumed=0);
static std::string escapeLabel(const std::string& orig);
BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), 0, true), std::range_error);
}
+BOOST_AUTO_TEST_CASE(test_compression_loop2) { // Compression loop (deep recursion)
+
+ int i;
+ string name("\x00\xc0\x00", 3);
+ for (i=0; i<98; ++i) {
+ name.append( 1, ((i >> 7) & 0xff) | 0xc0);
+ name.append( 1, ((i << 1) & 0xff) | 0x01);
+ }
+ BOOST_CHECK_NO_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true));
+
+ ++i;
+ name.append( 1, ((i >> 7) & 0xff) | 0xc0);
+ name.append( 1, ((i << 1) & 0xff) | 0x01);
+
+ BOOST_CHECK_THROW(DNSName dn(name.c_str(), name.size(), name.size()-2, true), std::range_error);
+}
BOOST_AUTO_TEST_SUITE_END()