diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-07-15 08:28:50 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-07-15 08:39:31 +0200 |
commit | adcc572a29169e5b571ab06b1a5bf941985d8fe6 (patch) | |
tree | 77aebfcb3ff5acaddaaed71e70abde4d39399942 /resolv | |
parent | 2ff32dd4926c7ec3bb6c09b58a12a8e828a4cc58 (diff) | |
download | glibc-adcc572a29169e5b571ab06b1a5bf941985d8fe6.tar.gz glibc-adcc572a29169e5b571ab06b1a5bf941985d8fe6.tar.xz glibc-adcc572a29169e5b571ab06b1a5bf941985d8fe6.zip |
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>
Diffstat (limited to 'resolv')
-rw-r--r-- | resolv/Makefile | 1 | ||||
-rw-r--r-- | resolv/Versions | 7 | ||||
-rw-r--r-- | resolv/ns_name.c | 128 | ||||
-rw-r--r-- | resolv/ns_name_ntop.c | 145 |
4 files changed, 152 insertions, 129 deletions
diff --git a/resolv/Makefile b/resolv/Makefile index f14b149b31..bb16175654 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -32,6 +32,7 @@ routines := \ inet_addr \ inet_ntop \ inet_pton \ + ns_name_ntop \ nsap_addr \ res-close \ res-state \ diff --git a/resolv/Versions b/resolv/Versions index 3b5328301a..4bf1a13d48 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -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; diff --git a/resolv/ns_name.c b/resolv/ns_name.c index 73213fee2d..4990003746 100644 --- a/resolv/ns_name.c +++ b/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); } @@ -608,43 +519,6 @@ libresolv_hidden_def (ns_name_skip) /*% * 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. */ static int diff --git a/resolv/ns_name_ntop.c b/resolv/ns_name_ntop.c new file mode 100644 index 0000000000..4dab3a3ce0 --- /dev/null +++ b/resolv/ns_name_ntop.c @@ -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 |