}
if(!c)
break;
- pvect.push_back(iter - d_content.cbegin());
+ auto offset = iter - d_content.cbegin();
+ if (offset >= 16384) break; // compression pointers cannot point here
+ pvect.push_back(offset);
iter+=*iter+1;
}
}
uint16_t li=0;
uint16_t matchlen=0;
- if(compress && (li=lookupName(name, &matchlen))) {
+ if(compress && (li=lookupName(name, &matchlen)) && li < 16384) {
const auto& dns=name.getStorage();
if(l_verbose)
cout<<"Found a substring of "<<matchlen<<" bytes from the back, offset: "<<li<<", dnslen: "<<dns.size()<<endl;
--- /dev/null
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_NO_MAIN
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/test/unit_test.hpp>
+#include <fstream>
+
+#include "dnswriter.hh"
+#include "dnsparser.hh"
+
+BOOST_AUTO_TEST_SUITE(test_dnswriter_cc)
+
+BOOST_AUTO_TEST_CASE(test_compressionBoundary) {
+ DNSName name("powerdns.com.");
+
+ vector<uint8_t> packet;
+ DNSPacketWriter pwR(packet, name, QType::A, QClass::IN, 0);
+ pwR.getHeader()->qr = 1;
+
+ /* record we want to see altered */
+ pwR.startRecord(name, QType::TXT, 3600, QClass::IN, DNSResourceRecord::ANSWER);
+ auto txt = string("\"")+string(16262, 'A')+string("\"");
+ pwR.xfrText(txt);
+ pwR.commit();
+ BOOST_CHECK_EQUAL(pwR.size(), 16368);
+
+ pwR.startRecord(DNSName("mediumsizedlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER);
+ pwR.xfrIP('P'<<24 |
+ 'Q'<<16 |
+ 'R'<<8 |
+ 'S');
+ pwR.commit();
+ BOOST_CHECK_EQUAL(pwR.size(), 16412); // 16412 (0x401c) puts '7example3net' at 0x4001
+
+ pwR.startRecord(DNSName("adifferentlabel.example.net"), QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER);
+ pwR.xfrIP('D'<<24 |
+ 'E'<<16 |
+ 'F'<<8 |
+ 'G');
+ pwR.commit();
+ BOOST_CHECK_EQUAL(pwR.size(), 16455);
+
+ string spacket(packet.begin(), packet.end());
+
+ BOOST_CHECK_NO_THROW(MOADNSParser mdp(false, spacket));
+}
+
+BOOST_AUTO_TEST_SUITE_END()