diff options
author | Erwin Lansing <erwin@FreeBSD.org> | 2014-12-15 12:14:41 +0000 |
---|---|---|
committer | Erwin Lansing <erwin@FreeBSD.org> | 2014-12-15 12:14:41 +0000 |
commit | 4c9547cd12b5bb569f10b368eb6bb04d897d596f (patch) | |
tree | 025b1191fa4f9c03bf5345071dd2658f5d240b69 /lib/dns/rdata.c | |
parent | 989b3b2d6068ce5b525479b7754977baf6364a7d (diff) |
Notes
Diffstat (limited to 'lib/dns/rdata.c')
-rw-r--r-- | lib/dns/rdata.c | 95 |
1 files changed, 36 insertions, 59 deletions
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 5bdd1255b5f75..08bfa34aa678d 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -116,7 +116,7 @@ typedef struct dns_rdata_textctx { } dns_rdata_textctx_t; static isc_result_t -txt_totext(isc_region_t *source, isc_buffer_t *target); +txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target); static isc_result_t txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); @@ -130,9 +130,6 @@ multitxt_totext(isc_region_t *source, isc_buffer_t *target); static isc_result_t multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target); -static isc_result_t -multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target); - static isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); @@ -1131,7 +1128,7 @@ name_length(dns_name_t *name) { } static isc_result_t -txt_totext(isc_region_t *source, isc_buffer_t *target) { +txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target) { unsigned int tl; unsigned int n; unsigned char *sp; @@ -1146,13 +1143,20 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { n = *sp++; REQUIRE(n + 1 <= source->length); + if (n == 0U) + REQUIRE(quote == ISC_TRUE); - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; + if (quote) { + if (tl < 1) + return (ISC_R_NOSPACE); + *tp++ = '"'; + tl--; + } while (n--) { - if (*sp < 0x20 || *sp >= 0x7f) { + /* + * \DDD space (0x20) if not quoting. + */ + if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { if (tl < 4) return (ISC_R_NOSPACE); *tp++ = 0x5c; @@ -1163,8 +1167,13 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { tl -= 4; continue; } - /* double quote, semi-colon, backslash */ - if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { + /* + * Escape double quote, semi-colon, backslash. + * If we are not enclosing the string in double + * quotes also escape at sign. + */ + if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c || + (!quote && *sp == 0x40)) { if (tl < 2) return (ISC_R_NOSPACE); *tp++ = '\\'; @@ -1175,10 +1184,12 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { *tp++ = *sp++; tl--; } - if (tl < 1) - return (ISC_R_NOSPACE); - *tp++ = '"'; - tl--; + if (quote) { + if (tl < 1) + return (ISC_R_NOSPACE); + *tp++ = '"'; + tl--; + } isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); isc_region_consume(source, *source->base + 1); return (ISC_R_SUCCESS); @@ -1274,6 +1285,9 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { return (ISC_R_SUCCESS); } +/* + * Conversion of TXT-like rdata fields without length limits. + */ static isc_result_t multitxt_totext(isc_region_t *source, isc_buffer_t *target) { unsigned int tl; @@ -1292,9 +1306,8 @@ multitxt_totext(isc_region_t *source, isc_buffer_t *target) { *tp++ = '"'; tl--; do { - n0 = n = *sp++; - - REQUIRE(n0 + 1 <= source->length); + n = source->length; + n0 = source->length - 1; while (n--) { if (*sp < 0x20 || *sp >= 0x7f) { @@ -1346,17 +1359,11 @@ multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { do { isc_buffer_availableregion(target, &tregion); - t0 = tregion.base; + t0 = t = tregion.base; nrem = tregion.length; if (nrem < 1) return (ISC_R_NOSPACE); - /* length byte */ - t = t0; - nrem--; - t++; - /* 255 byte character-string slice */ - if (nrem > 255) - nrem = 255; + while (n != 0) { --n; c = (*s++) & 0xff; @@ -1390,39 +1397,9 @@ multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { } if (escape) return (DNS_R_SYNTAX); - *t0 = (unsigned char)(t - t0 - 1); - isc_buffer_add(target, *t0 + 1); - } while (n != 0); - return (ISC_R_SUCCESS); -} - -static isc_result_t -multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { - unsigned int n; - isc_region_t sregion; - isc_region_t tregion; - - isc_buffer_activeregion(source, &sregion); - if (sregion.length == 0) - return(ISC_R_UNEXPECTEDEND); - n = 256U; - do { - if (n != 256U) - return (DNS_R_SYNTAX); - n = *sregion.base + 1; - if (n > sregion.length) - return (ISC_R_UNEXPECTEDEND); - isc_buffer_availableregion(target, &tregion); - if (n > tregion.length) - return (ISC_R_NOSPACE); - - if (tregion.base != sregion.base) - memmove(tregion.base, sregion.base, n); - isc_buffer_forward(source, n); - isc_buffer_add(target, n); - isc_buffer_activeregion(source, &sregion); - } while (sregion.length != 0); + isc_buffer_add(target, t - t0); + } while (n != 0); return (ISC_R_SUCCESS); } |