summaryrefslogtreecommitdiff
path: root/lib/dns/rdata.c
diff options
context:
space:
mode:
authorErwin Lansing <erwin@FreeBSD.org>2014-12-15 12:14:41 +0000
committerErwin Lansing <erwin@FreeBSD.org>2014-12-15 12:14:41 +0000
commit4c9547cd12b5bb569f10b368eb6bb04d897d596f (patch)
tree025b1191fa4f9c03bf5345071dd2658f5d240b69 /lib/dns/rdata.c
parent989b3b2d6068ce5b525479b7754977baf6364a7d (diff)
Notes
Diffstat (limited to 'lib/dns/rdata.c')
-rw-r--r--lib/dns/rdata.c95
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);
}