diff --git a/bin/tests/system/digdelv/ns2/example.db.in b/bin/tests/system/digdelv/ns2/example.db.in index c711049e98..8a88e038cf 100644 --- a/bin/tests/system/digdelv/ns2/example.db.in +++ b/bin/tests/system/digdelv/ns2/example.db.in @@ -49,3 +49,42 @@ hours 10800 A 10.53.0.2 minutes 2700 A 10.53.0.2 ;TTL of 45 seconds seconds 45 A 10.53.0.2 +; domain names with yaml special values and data with ': ' +yaml TXT "a: b" +'.yaml TXT "a: b" +[.yaml TXT "a: b" +{.yaml TXT "a: b" +&.yaml TXT "a: b" +#.yaml TXT "a: b" +all.yaml TXT ( \000 \001 \002 \003 \004 \005 \006 \007 + \008 \009 \010 \011 \012 \013 \014 \015 + \016 \017 \018 \019 \020 \021 \022 \023 + \024 \025 \026 \027 \028 \029 \030 \031 + \032 \033 \034 \035 \036 \037 \038 \039 + \040 \041 \042 \043 \044 \045 \046 \047 + \048 \049 \050 \051 \052 \053 \054 \055 + \056 \057 \058 \059 \060 \061 \062 \063 + \064 \065 \066 \067 \068 \069 \070 \071 + \072 \073 \074 \075 \076 \077 \078 \079 + \080 \081 \082 \083 \084 \085 \086 \087 + \088 \089 \090 \091 \092 \093 \094 \095 + \096 \097 \098 \099 \100 \101 \102 \103 + \104 \105 \106 \107 \108 \109 \110 \111 + \112 \113 \114 \115 \116 \117 \118 \119 + \120 \121 \122 \123 \124 \125 \126 \127 + \128 \129 \130 \131 \132 \133 \134 \135 + \136 \137 \138 \139 \140 \141 \142 \143 + \144 \145 \146 \147 \148 \149 \150 \151 + \152 \153 \154 \155 \156 \157 \158 \159 + \160 \161 \162 \163 \164 \165 \166 \167 + \168 \169 \170 \171 \172 \173 \174 \175 + \176 \177 \178 \179 \180 \181 \182 \183 + \184 \185 \186 \187 \188 \189 \190 \191 + \192 \193 \194 \195 \196 \197 \198 \199 + \200 \201 \202 \203 \204 \205 \206 \207 + \208 \209 \210 \211 \212 \213 \214 \215 + \216 \217 \218 \219 \220 \221 \222 \223 + \224 \225 \226 \227 \228 \229 \230 \231 + \232 \233 \234 \235 \236 \237 \238 \239 + \240 \241 \242 \243 \244 \245 \246 \247 + \248 \249 \250 \251 \252 \253 \254 \255 ) diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index d7393057c4..5b8cfdb902 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -1407,5 +1407,60 @@ else echo_i "$DELV is needed, so skipping these delv tests" fi +if [ $HAS_PYYAML -ne 0 ]; then + for qname in "yaml" "'.yaml" "[.yaml" "{.yaml" "&.yaml" "#.yaml"; do + n=$((n + 1)) + echo_i "check yaml special '${yaml}.example' ($n)" + ret=0 + dig_with_opts @10.53.0.3 +yaml "${qname}.example" TXT +qr >dig.out.test$n 2>&1 || ret=1 + $PYTHON yamlget.py dig.out.test$n 0 message query_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1 + read -r value yamlget.out.test$n 2>&1 || ret=1 + read -r value dig.out.test$n 2>&1 || ret=1 + $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1 + read -r value " "?" "@" "A" "B" "C" "D" "E" "F" "G" "H"' + expected="$expected "'"I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V"' + expected="$expected "'"W" "X" "Y" "Z" "[" "\\" "]" "^" "_" "`" "a" "b" "c" "d"' + expected="$expected "'"e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r"' + expected="$expected "'"s" "t" "u" "v" "w" "x" "y" "z" "{" "|" "}" "~" "\127"' + expected="$expected "'"\128" "\129" "\130" "\131" "\132" "\133" "\134" "\135"' + expected="$expected "'"\136" "\137" "\138" "\139" "\140" "\141" "\142" "\143"' + expected="$expected "'"\144" "\145" "\146" "\147" "\148" "\149" "\150" "\151"' + expected="$expected "'"\152" "\153" "\154" "\155" "\156" "\157" "\158" "\159"' + expected="$expected "'"\160" "\161" "\162" "\163" "\164" "\165" "\166" "\167"' + expected="$expected "'"\168" "\169" "\170" "\171" "\172" "\173" "\174" "\175"' + expected="$expected "'"\176" "\177" "\178" "\179" "\180" "\181" "\182" "\183"' + expected="$expected "'"\184" "\185" "\186" "\187" "\188" "\189" "\190" "\191"' + expected="$expected "'"\192" "\193" "\194" "\195" "\196" "\197" "\198" "\199"' + expected="$expected "'"\200" "\201" "\202" "\203" "\204" "\205" "\206" "\207"' + expected="$expected "'"\208" "\209" "\210" "\211" "\212" "\213" "\214" "\215"' + expected="$expected "'"\216" "\217" "\218" "\219" "\220" "\221" "\222" "\223"' + expected="$expected "'"\224" "\225" "\226" "\227" "\228" "\229" "\230" "\231"' + expected="$expected "'"\232" "\233" "\234" "\235" "\236" "\237" "\238" "\239"' + expected="$expected "'"\240" "\241" "\242" "\243" "\244" "\245" "\246" "\247"' + expected="$expected "'"\248" "\249" "\250" "\251" "\252" "\253" "\254" "\255"' + [ "$value" = "$expected" ] || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) +fi + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 4946d0d237..69ab7851e5 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -475,12 +475,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); @@ -501,7 +533,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)); @@ -740,7 +779,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); @@ -750,13 +788,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; @@ -792,7 +829,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); @@ -800,6 +837,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; @@ -842,12 +884,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); } diff --git a/lib/dns/message.c b/lib/dns/message.c index 1d3b6fe2d3..213b6f529a 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -3396,9 +3396,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(