]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix yaml output
authorMark Andrews <marka@isc.org>
Mon, 8 Jul 2024 04:00:14 +0000 (14:00 +1000)
committerMark Andrews <marka@isc.org>
Thu, 1 Aug 2024 02:30:57 +0000 (12:30 +1000)
In yaml mode we emit a string for each question and record.  Certain
names and data could result in invalid yaml being produced.  Use single
quote string for all questions and records.  This requires that single
quotes get converted to two quotes within the string.

lib/dns/masterdump.c
lib/dns/message.c

index 6418420dc5e2a22a090ad8554b16bc73d5461a4a..849c00150c0bfeb99c7955082cc37b6736a20869 100644 (file)
@@ -472,12 +472,44 @@ str_totext(const char *source, isc_buffer_t *target) {
        return (ISC_R_SUCCESS);
 }
 
+static isc_result_t
+yaml_stringify(isc_buffer_t *target, char *start) {
+       isc_region_t r;
+       char *s = start;
+       char *tmp = NULL;
+
+       isc_buffer_availableregion(target, &r);
+       if (r.length < 1) {
+               return (ISC_R_NOSPACE);
+       }
+
+       /* NUL terminate buffer for string operations below */
+       r.base[0] = '\0';
+
+       /* Escape quotes in string using quote quote */
+       while ((tmp = strchr(s, '\'')) != NULL) {
+               isc_buffer_availableregion(target, &r);
+               /* Space to shift by 1 with trailing NUL? */
+               if (r.length < 2) {
+                       return (ISC_R_NOSPACE);
+               }
+               memmove(tmp + 1, tmp,
+                       (char *)isc_buffer_used(target) - tmp + 1);
+               isc_buffer_add(target, 1);
+               /* We now have "''..." - skip both quotes. */
+               s = tmp + 2;
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
 static isc_result_t
 ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot,
               dns_totext_ctx_t *ctx, isc_buffer_t *target) {
        isc_result_t result = ISC_R_SUCCESS;
        dns_rdataset_t rds;
        dns_name_t name;
+       char *start = NULL;
 
        dns_rdataset_init(&rds);
        dns_name_init(&name, NULL);
@@ -498,7 +530,8 @@ ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot,
                        }
 
                        if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) {
-                               CHECK(str_totext("- ", target));
+                               CHECK(str_totext("- '", target));
+                               start = isc_buffer_used(target);
                        } else {
                                CHECK(str_totext("; ", target));
                        }
@@ -512,7 +545,7 @@ ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot,
                        if (rds.type == dns_rdatatype_rrsig) {
                                CHECK(str_totext(" ", target));
                                CHECK(dns_rdatatype_totext(rds.covers, target));
-                               CHECK(str_totext(" ...\n", target));
+                               CHECK(str_totext(" ...", target));
                        } else {
                                dns_rdata_t rdata = DNS_RDATA_INIT;
                                dns_rdataset_current(&rds, &rdata);
@@ -520,8 +553,12 @@ ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot,
                                CHECK(dns_rdata_tofmttext(&rdata, dns_rootname,
                                                          0, 0, 0, " ",
                                                          target));
-                               CHECK(str_totext("\n", target));
                        }
+                       if (start != NULL) {
+                               RETERR(yaml_stringify(target, start));
+                               CHECK(str_totext("\'", target));
+                       }
+                       CHECK(str_totext("\n", target));
                }
                dns_rdataset_disassociate(&rds);
                result = dns_rdataset_next(rdataset);
@@ -559,6 +596,7 @@ rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
        dns_fixedname_t fixed;
        dns_name_t *name = NULL;
        unsigned int i;
+       char *start = NULL;
 
        REQUIRE(DNS_RDATASET_VALID(rdataset));
 
@@ -592,7 +630,8 @@ rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                 * YAML or comment prefix?
                 */
                if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) {
-                       RETERR(str_totext("- ", target));
+                       RETERR(str_totext("- '", target));
+                       start = isc_buffer_used(target);
                } else if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0)
                {
                        RETERR(str_totext(";", target));
@@ -743,7 +782,6 @@ rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                        break;
                } else {
                        dns_rdata_t rdata = DNS_RDATA_INIT;
-                       isc_region_t r;
 
                        dns_rdataset_current(rdataset, &rdata);
 
@@ -753,13 +791,12 @@ rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                                        ctx->style.rdata_column,
                                ctx->style.split_width, ctx->linebreak,
                                target));
-
-                       isc_buffer_availableregion(target, &r);
-                       if (r.length < 1) {
-                               return (ISC_R_NOSPACE);
+                       if (start != NULL) {
+                               RETERR(yaml_stringify(target, start));
+                               RETERR(str_totext("'\n", target));
+                       } else {
+                               RETERR(str_totext("\n", target));
                        }
-                       r.base[0] = '\n';
-                       isc_buffer_add(target, 1);
                }
 
                first = false;
@@ -795,7 +832,7 @@ question_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                isc_buffer_t *target) {
        unsigned int column;
        isc_result_t result;
-       isc_region_t r;
+       char *start = NULL;
 
        REQUIRE(DNS_RDATASET_VALID(rdataset));
        result = dns_rdataset_first(rdataset);
@@ -803,6 +840,11 @@ question_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
 
        column = 0;
 
+       if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) {
+               RETERR(str_totext("- '", target));
+               start = isc_buffer_used(target);
+       }
+
        /* Owner name */
        {
                unsigned int name_start = target->used;
@@ -846,12 +888,11 @@ question_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                column += (target->used - type_start);
        }
 
-       isc_buffer_availableregion(target, &r);
-       if (r.length < 1) {
-               return (ISC_R_NOSPACE);
+       if (start != NULL) {
+               RETERR(yaml_stringify(target, start));
+               RETERR(str_totext("\'", target));
        }
-       r.base[0] = '\n';
-       isc_buffer_add(target, 1);
+       RETERR(str_totext("\n", target));
 
        return (ISC_R_SUCCESS);
 }
index fe8e05c0a00e4fc46f429279fe561b5858e6cf96..d1917b30e2d83d280201ec17423d581068aa7812 100644 (file)
@@ -3458,9 +3458,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
                        }
                        if (section == DNS_SECTION_QUESTION) {
                                INDENT(style);
-                               if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
-                                       ADD_STRING(target, "- ");
-                               } else {
+                               if ((sflags & DNS_STYLEFLAG_YAML) == 0) {
                                        ADD_STRING(target, ";");
                                }
                                result = dns_master_questiontotext(