]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add YAML escaping where needed
authorMark Andrews <marka@isc.org>
Tue, 29 Oct 2024 05:45:41 +0000 (16:45 +1100)
committerEvan Hunt <each@isc.org>
Wed, 7 May 2025 07:00:10 +0000 (00:00 -0700)
When rendering text, such as domain names or the EXTRA-TEXT
field of the EDE option, backslashes and quotation marks must
be escaped to ensure that the emitted message is valid YAML.

(cherry picked from commit 280e9b7cf4b28bffa6a281bb64b43e35829645ec)

bin/tests/system/digdelv/tests.sh
lib/dns/message.c

index 2a1500e5b34d2d8e84b000ec058505d0b5005464..ca84b32ef8a600e4bdd60d0111ebf90160892ae9 100644 (file)
@@ -679,6 +679,26 @@ if [ -x "$DIG" ]; then
   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   status=$((status + ret))
 
+  n=$((n + 1))
+  echo_i "check that dig processes +ednsopt=chain:02002200 ($n)"
+  ret=0
+  dig_with_opts @10.53.0.3 +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
+  grep '; CHAIN: "\\000\\""' dig.out.test$n >/dev/null || ret=1
+  if [ $ret -ne 0 ]; then echo_i "failed"; fi
+  status=$((status + ret))
+
+  if [ $HAS_PYYAML -ne 0 ]; then
+    n=$((n + 1))
+    echo_i "check that dig processes +ednsopt=chain:02002200 +yaml ($n)"
+    ret=0
+    dig_with_opts @10.53.0.3 +yaml +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
+    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CHAIN >yamlget.out.test$n 2>&1 || ret=1
+    read -r value <yamlget.out.test$n
+    [ "$value" = '\000\"' ] || ret=1
+    if [ $ret -ne 0 ]; then echo_i "failed"; fi
+    status=$((status + ret))
+  fi
+
   n=$((n + 1))
   echo_i "check that Extended DNS Error 0 is printed correctly ($n)"
   ret=0
@@ -689,6 +709,19 @@ if [ -x "$DIG" ]; then
   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   status=$((status + ret))
 
+  if [ $HAS_PYYAML -ne 0 ]; then
+    n=$((n + 1))
+    echo_i "check that Extended DNS Error 0 is printed correctly +yaml ($n)"
+    ret=0
+    # add specials '"' and '\'
+    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f225c a.example +qr >dig.out.test$n 2>&1 || ret=1
+    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 || ret=1
+    read -r value <yamlget.out.test$n
+    [ "$value" = 'foo"\' ] || ret=1
+    if [ $ret -ne 0 ]; then echo_i "failed"; fi
+    status=$((status + ret))
+  fi
+
   n=$((n + 1))
   echo_i "check that Extended DNS Error 24 is printed correctly ($n)"
   ret=0
index 86d4342af975e8f7bb4c7a57a618aa81205960f6..cf8fef754c0402894a2178ef97cb8d35cafe0236 100644 (file)
@@ -3565,7 +3565,29 @@ cleanup:
 }
 
 static isc_result_t
-render_nameopt(isc_buffer_t *optbuf, isc_buffer_t *target) {
+put_yamlstr(isc_buffer_t *target, unsigned char *namebuf, size_t len,
+           bool utfok) {
+       isc_result_t result = ISC_R_SUCCESS;
+
+       for (size_t i = 0; i < len; i++) {
+               if (isprint(namebuf[i]) || (utfok && namebuf[i] > 127)) {
+                       if (namebuf[i] == '\\' || namebuf[i] == '"') {
+                               ADD_STRING(target, "\\");
+                       }
+                       if (isc_buffer_availablelength(target) < 1) {
+                               return ISC_R_NOSPACE;
+                       }
+                       isc_buffer_putmem(target, &namebuf[i], 1);
+               } else {
+                       ADD_STRING(target, ".");
+               }
+       }
+cleanup:
+       return result;
+}
+
+static isc_result_t
+render_nameopt(isc_buffer_t *optbuf, bool yaml, isc_buffer_t *target) {
        dns_decompress_t dctx = DNS_DECOMPRESS_NEVER;
        dns_fixedname_t fixed;
        dns_name_t *name = dns_fixedname_initname(&fixed);
@@ -3576,7 +3598,15 @@ render_nameopt(isc_buffer_t *optbuf, isc_buffer_t *target) {
        if (result == ISC_R_SUCCESS && isc_buffer_activelength(optbuf) == 0) {
                dns_name_format(name, namebuf, sizeof(namebuf));
                ADD_STRING(target, " \"");
-               ADD_STRING(target, namebuf);
+               if (yaml) {
+                       result = put_yamlstr(target, (unsigned char *)namebuf,
+                                            strlen(namebuf), false);
+                       if (result != ISC_R_SUCCESS) {
+                               goto cleanup;
+                       }
+               } else {
+                       ADD_STRING(target, namebuf);
+               }
                ADD_STRING(target, "\"");
                return result;
        }
@@ -3801,7 +3831,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
                                if (optlen > 0U) {
                                        isc_buffer_t sb = optbuf;
                                        isc_buffer_setactive(&optbuf, optlen);
-                                       result = render_nameopt(&optbuf,
+                                       result = render_nameopt(&optbuf, true,
                                                                target);
                                        if (result == ISC_R_SUCCESS) {
                                                ADD_STRING(target, "\n");
@@ -3937,21 +3967,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
                                } else {
                                        ADD_STRING(target, "\"");
                                }
-                               if (isc_buffer_availablelength(target) < optlen)
-                               {
-                                       result = ISC_R_NOSPACE;
-                                       goto cleanup;
-                               }
-                               for (i = 0; i < optlen; i++) {
-                                       if (isprint(optdata[i]) ||
-                                           (utf8ok && optdata[i] > 127))
-                                       {
-                                               isc_buffer_putmem(
-                                                       target, &optdata[i], 1);
-                                       } else {
-                                               isc_buffer_putstr(target, ".");
-                                       }
-                               }
+                               put_yamlstr(target, optdata, optlen, utf8ok);
                                if (!extra_text) {
                                        ADD_STRING(target, "\")");
                                } else {
@@ -4196,7 +4212,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section,
                                if (optlen > 0U) {
                                        isc_buffer_t sb = optbuf;
                                        isc_buffer_setactive(&optbuf, optlen);
-                                       result = render_nameopt(&optbuf,
+                                       result = render_nameopt(&optbuf, false,
                                                                target);
                                        if (result == ISC_R_SUCCESS) {
                                                ADD_STRING(target, "\n");