]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Allow quoted words to immediately follow non-quoted in text record contents. 16087/head
authorMiod Vallat <miod.vallat@powerdns.com>
Mon, 8 Sep 2025 13:36:20 +0000 (15:36 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 8 Sep 2025 13:36:20 +0000 (15:36 +0200)
Also reject \DDD escapes with a value larger than 8 bits.

Signed-off-by: Miod Vallat <miod.vallat@powerdns.com>
pdns/rcpgenerator.cc
pdns/test-dnsrecords_cc.cc

index fee6cc0637acea9d417d2e1aec6b2d1436f6aa73..3be09a915f6f612e7130bfa2c1cfd371049668c2 100644 (file)
@@ -642,7 +642,7 @@ void RecordTextReader::xfrText(string& val, bool multi, bool /* lenField */)
             char chr2 = d_string[d_pos + 1];
             char chr3 = d_string[d_pos + 2];
             if (chr2 >= '0' && chr2 <= '9' && chr3 >= '0' && chr3 <= '9') {
-              valid = true;
+              valid = 100 * (chr - '0') + 10 * (chr2 - '0') + chr3 - '0' < 256;
             }
           }
           if (!valid) {
@@ -652,6 +652,12 @@ void RecordTextReader::xfrText(string& val, bool multi, bool /* lenField */)
         // Not advancing d_pos, we'll append the next 1 or 3 characters as
         // part of the regular case.
       }
+      if (!quoted && d_string[d_pos] == '"') {
+        // Bind allows a non-quoted text to be immediately followed by a
+        // quoted text, without any whitespace in between, so handle this
+        // as a delimiter.
+        break;
+      }
       val.append(1, d_string[d_pos]);
       ++d_pos;
     }
index cdb0e6245b1d79d075628f455fd03d33c06e1cab..321d9a6e8520a50462efd271e68fbefbb50313a1 100644 (file)
@@ -100,7 +100,6 @@ BOOST_AUTO_TEST_CASE(test_record_types) {
      (CASE_S(QType::TXT,  "\"\\195\\133LAND ISLANDS\"", "\x0e\xc3\x85LAND ISLANDS"))
      (CASE_S(QType::TXT,  "\"text with DEL in there: \\127\"", "\x19text with DEL in there: \x7f"))
      (CASE_L(QType::TXT, "\"\xc3\x85LAND ISLANDS\"", "\"\\195\\133LAND ISLANDS\"", "\x0e\xc3\x85LAND ISLANDS"))
-     (CASE_S(QType::TXT, "\"nonbreakingtxt\"", "\x0enonbreakingtxt"))
 // local name
      (CASE_S(QType::RP, "admin.rec.test. admin-info.rec.test.", "\x05""admin\x03rec\x04test\x00\x0a""admin-info\x03rec\x04test\x00"))
 // non-local name
@@ -384,6 +383,8 @@ BOOST_AUTO_TEST_CASE(test_record_types_bad_values) {
 // non-local overly large name (256), must be broken
      (ZONE_CASE(QType::CNAME, "123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012."))
      (ZONE_CASE(QType::SOA, "ns.rec.test hostmaster.test.rec 20130512010 3600 3600 604800 120")) // too long serial
+     (ZONE_CASE(QType::TXT, "\\02unlimited")) // incorrect escape
+     (ZONE_CASE(QType::TXT, "\\384excessive")) // incorrect escape
 ;
 
   int n=0;