ares_expand_name() should escape more characters

RFC1035 5.1 specifies some reserved characters and escaping sequences
that are allowed to be specified.  Expand the list of reserved characters
and also escape non-printable characters using the \DDD format as
specified in the RFC.

Bug Reported By: philipp.jeitner@sit.fraunhofer.de
Fix By: Brad House (@bradh352)
pull/406/head
bradh352 4 years ago
parent 809d5e84f3
commit 362f91d807
  1. 41
      src/lib/ares_expand_name.c

@ -32,6 +32,26 @@
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen);
/* Reserved characters for names that need to be escaped */
static int is_reservedch(int ch)
{
switch (ch) {
case '"':
case '.':
case ';':
case '\\':
case '(':
case ')':
case '@':
case '$':
return 1;
default:
break;
}
return 0;
}
/* Expand an RFC1035-encoded domain name given by encoded. The
* containing message is given by abuf and alen. The result given by
* *s, which is set to a NUL-terminated allocated buffer. *enclen is
@ -111,9 +131,18 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
p++;
while (len--)
{
if (*p == '.' || *p == '\\')
if (!isprint(*p)) {
/* Output as \DDD for consistency with RFC1035 5.1 */
*q++ = '\\';
*q++ = '0' + *p / 100;
*q++ = '0' + (*p % 100) / 10;
*q++ = '0' + (*p % 10);
} else if (is_reservedch(*p)) {
*q++ = '\\';
*q++ = *p;
*q++ = *p;
} else {
*q++ = *p;
}
p++;
}
*q++ = '.';
@ -171,7 +200,13 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
encoded++;
while (offset--)
{
n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
if (!isprint(*encoded)) {
n += 4;
} else if (is_reservedch(*encoded)) {
n += 2;
} else {
n += 1;
}
encoded++;
}
n++;

Loading…
Cancel
Save