1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

resolv: Move ns_name_ntop to its own file and into libc

Reformat to GNU style.  Avoid out-of-bounds pointer arithmetic
(e.g., use eom - dn < 2 instead of dn + 1 >= eom).  Inline the
labellen function and fold the compression pointer check into
the length check (l >= 64).  Assume ASCII encoding.

The symbol was moved using scripts/move-symbol-to-libc.py.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Florian Weimer
2021-07-15 08:28:50 +02:00
parent 2ff32dd492
commit adcc572a29
69 changed files with 221 additions and 161 deletions

View File

@@ -32,6 +32,7 @@ routines := \
inet_addr \
inet_ntop \
inet_pton \
ns_name_ntop \
nsap_addr \
res-close \
res-state \

View File

@@ -24,6 +24,9 @@ libc {
getaddrinfo_a;
%endif
}
GLIBC_2.9 {
ns_name_ntop;
}
GLIBC_2.34 {
%if PTHREAD_IN_LIBC
gai_cancel;
@@ -31,6 +34,7 @@ libc {
gai_suspend;
getaddrinfo_a;
%endif
ns_name_ntop;
}
GLIBC_PRIVATE {
%if !PTHREAD_IN_LIBC
@@ -40,6 +44,7 @@ libc {
__inet_aton_exact;
__inet_pton_length;
__res_iclose;
__ns_name_ntop;
__resolv_context_get;
__resolv_context_get_override;
__resolv_context_get_preinit;
@@ -137,7 +142,6 @@ libresolv {
ns_msg_getflag;
ns_name_compress;
ns_name_ntol;
ns_name_ntop;
ns_name_pack;
ns_name_pton;
ns_name_rollback;
@@ -158,7 +162,6 @@ libresolv {
GLIBC_PRIVATE {
__ns_get16;
__ns_get32;
__ns_name_ntop;
__ns_name_unpack;
__res_context_hostalias;
__res_context_query;

View File

@@ -35,8 +35,6 @@ static const char digits[] = "0123456789";
/* Forward. */
static int special(int);
static int printable(int);
static int dn_find(const u_char *, const u_char *,
const u_char * const *,
const u_char * const *);
@@ -44,93 +42,6 @@ static int labellen(const u_char *);
/* Public. */
/*%
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
*\li Number of bytes written to buffer, or -1 (with errno set)
*
* notes:
*\li The root is returned as "."
*\li All other domains are returned in non absolute form
*/
int
ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
{
const u_char *cp;
char *dn, *eom;
u_char c;
u_int n;
int l;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* Some kind of compression pointer. */
__set_errno (EMSGSIZE);
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = '.';
}
if ((l = labellen(cp - 1)) < 0) {
__set_errno (EMSGSIZE);
return(-1);
}
if (dn + l >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
for ((void)NULL; l > 0; l--) {
c = *cp++;
if (special(c)) {
if (dn + 1 >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable(c)) {
if (dn + 3 >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
__set_errno (EMSGSIZE);
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
libresolv_hidden_def (ns_name_ntop)
strong_alias (ns_name_ntop, __ns_name_ntop)
/*%
* Convert an ascii string into an encoded domain name as per RFC1035.
@@ -517,7 +428,7 @@ ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
if (__ns_name_ntop (tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
@@ -606,43 +517,6 @@ libresolv_hidden_def (ns_name_skip)
/* Private. */
/*%
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character special ("in need of quoting") ?
*
* return:
*\li boolean.
*/
static int
special(int ch) {
switch (ch) {
case 0x22: /*%< '"' */
case 0x2E: /*%< '.' */
case 0x3B: /*%< ';' */
case 0x5C: /*%< '\\' */
case 0x28: /*%< '(' */
case 0x29: /*%< ')' */
/* Special modifiers in zone files. */
case 0x40: /*%< '@' */
case 0x24: /*%< '$' */
return (1);
default:
return (0);
}
}
/*%
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
*
* return:
*\li boolean.
*/
static int
printable(int ch) {
return (ch > 0x20 && ch < 0x7f);
}
/*%
* Thinking in noninternationalized USASCII (per the DNS spec),
* convert this character to lower case if it's upper case.

145
resolv/ns_name_ntop.c Normal file
View File

@@ -0,0 +1,145 @@
/* Convert DNS domain names from network format to textual presentation format.
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <arpa/nameser.h>
#include <errno.h>
#include <shlib-compat.h>
#include <stdbool.h>
/* Thinking in noninternationalized US-ASCII (per the DNS spec), is
this character special ("in need of quoting")? */
static inline bool
special (int ch)
{
switch (ch)
{
case '"':
case '.':
case ';':
case '\\':
case '(':
case ')':
/* Special modifiers in zone files. */
case '@':
case '$':
return true;
default:
return false;
}
}
/* Thinking in noninternationalized US-ASCII (per the DNS spec), is
this character visible and not a space when printed? */
static inline bool
printable (int ch)
{
return ch > 0x20 && ch < 0x7f;
}
/* Converts an uncompressed, encoded domain name to printable ASCII as
per RFC1035. Returns the number of bytes written to buffer, or -1
(with errno set). The root is returned as "." All other domains
are returned in non absolute form. */
int
___ns_name_ntop (const unsigned char *src, char *dst, size_t dstsiz)
{
const unsigned char *cp;
char *dn, *eom;
unsigned char c;
int l;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((l = *cp++) != 0)
{
if (l >= 64)
{
/* Some kind of compression pointer. */
__set_errno (EMSGSIZE);
return -1;
}
if (dn != dst)
{
if (dn >= eom)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = '.';
}
for (; l > 0; l--)
{
c = *cp++;
if (special (c))
{
if (eom - dn < 2)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = '\\';
*dn++ = c;
}
else if (!printable (c))
{
if (eom - dn < 4)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = '\\';
*dn++ = '0' + (c / 100);
*dn++ = '0' + ((c % 100) / 10);
*dn++ = '0' + (c % 10);
}
else
{
if (eom - dn < 2)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = c;
}
}
}
if (dn == dst)
{
if (dn >= eom)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = '.';
}
if (dn >= eom)
{
__set_errno (EMSGSIZE);
return -1;
}
*dn++ = '\0';
return dn - dst;
}
versioned_symbol (libc, ___ns_name_ntop, ns_name_ntop, GLIBC_2_34);
versioned_symbol (libc, ___ns_name_ntop, __ns_name_ntop, GLIBC_PRIVATE);
libc_hidden_ver (___ns_name_ntop, __ns_name_ntop)
#if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_9, GLIBC_2_34)
compat_symbol (libresolv, ___ns_name_ntop, ns_name_ntop, GLIBC_2_9);
#endif