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:
@@ -32,6 +32,7 @@ routines := \
|
||||
inet_addr \
|
||||
inet_ntop \
|
||||
inet_pton \
|
||||
ns_name_ntop \
|
||||
nsap_addr \
|
||||
res-close \
|
||||
res-state \
|
||||
|
@@ -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;
|
||||
|
128
resolv/ns_name.c
128
resolv/ns_name.c
@@ -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
145
resolv/ns_name_ntop.c
Normal 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
|
Reference in New Issue
Block a user