diff options
| author | 2019-12-16 16:16:22 +0000 | |
|---|---|---|
| committer | 2019-12-16 16:16:22 +0000 | |
| commit | 2fc5abb04c862f358e234358caea4444e15db068 (patch) | |
| tree | 1c77d5b577fef0399be14245b2108ca9c1a8819d /usr.sbin/bind/lib/isc/print.c | |
| parent | Need to include message size in the maximum buffer calculation. (diff) | |
| download | wireguard-openbsd-2fc5abb04c862f358e234358caea4444e15db068.tar.xz wireguard-openbsd-2fc5abb04c862f358e234358caea4444e15db068.zip | |
Update to bind-9.10.5-P3, which appears to have been the last ISC version.
We only use this tree to build dig and nslookup. Our previous version
predated edns0 support in those tools, and we want that. This is the worst
code I've looked at in years, with layers and layers of spaghetti abstraction
clearly unfit for reuse, but then reused anyways, and the old ones remain
behind. So this is a 8MB diff.
florian, sthen, and otto tried this merge before but failed.
Diffstat (limited to 'usr.sbin/bind/lib/isc/print.c')
| -rw-r--r-- | usr.sbin/bind/lib/isc/print.c | 421 |
1 files changed, 286 insertions, 135 deletions
diff --git a/usr.sbin/bind/lib/isc/print.c b/usr.sbin/bind/lib/isc/print.c index d0436316d27..706acd4cf75 100644 --- a/usr.sbin/bind/lib/isc/print.c +++ b/usr.sbin/bind/lib/isc/print.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2010, 2014-2016 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or 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. * @@ -15,15 +15,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: print.c,v 1.27.18.3 2006/04/17 18:27:33 explorer Exp $ */ - /*! \file */ #include <config.h> #include <ctype.h> -#include <stdio.h> /* for snprintf */ +#include <stdio.h> /* for sprintf() */ #include <string.h> /* for strlen() */ +#include <assert.h> /* for assert() */ #define ISC__PRINT_SOURCE /* Used to get the isc_print_* prototypes. */ @@ -34,14 +33,79 @@ #include <isc/stdlib.h> #include <isc/util.h> +/* + * We use the system's sprintf so we undef it here. + */ +#undef sprintf + +static int +isc__print_printf(void (*emit)(char, void *), void *arg, + const char *format, va_list ap); + +static void +file_emit(char c, void *arg) { + FILE *fp = arg; + int i = c & 0xff; + + putc(i, fp); +} + +#if 0 +static int +isc_print_vfprintf(FILE *fp, const char *format, va_list ap) { + assert(fp != NULL); + assert(format != NULL); + + return (isc__print_printf(file_emit, fp, format, ap)); +} +#endif + +int +isc_print_printf(const char *format, ...) { + va_list ap; + int n; + + assert(format != NULL); + + va_start(ap, format); + n = isc__print_printf(file_emit, stdout, format, ap); + va_end(ap); + return (n); +} + +int +isc_print_fprintf(FILE *fp, const char *format, ...) { + va_list ap; + int n; + + assert(fp != NULL); + assert(format != NULL); + + va_start(ap, format); + n = isc__print_printf(file_emit, fp, format, ap); + va_end(ap); + return (n); +} + +static void +nocheck_emit(char c, void *arg) { + struct { char *str; } *a = arg; + + *(a->str)++ = c; +} + int isc_print_sprintf(char *str, const char *format, ...) { + struct { char *str; } arg; + int n; va_list ap; + arg.str = str; + va_start(ap, format); - vsprintf(str, format, ap); + n = isc__print_printf(nocheck_emit, &arg, format, ap); va_end(ap); - return (strlen(str)); + return (n); } /*! @@ -54,7 +118,7 @@ isc_print_snprintf(char *str, size_t size, const char *format, ...) { int ret; va_start(ap, format); - ret = vsnprintf(str, size, format, ap); + ret = isc_print_vsnprintf(str, size, format, ap); va_end(ap); return (ret); @@ -64,10 +128,40 @@ isc_print_snprintf(char *str, size_t size, const char *format, ...) { * Return length of string that would have been written if not truncated. */ +static void +string_emit(char c, void *arg) { + struct { char *str; size_t size; } *p = arg; + + if (p->size > 0) { + *(p->str)++ = c; + p->size--; + } +} + int isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { + struct { char *str; size_t size; } arg; + int n; + + assert(str != NULL); + assert(format != NULL); + + arg.str = str; + arg.size = size; + + n = isc__print_printf(string_emit, &arg, format, ap); + if (arg.size > 0) + *arg.str = '\0'; + return (n); +} + +static int +isc__print_printf(void (*emit)(char, void *), void *arg, + const char *format, va_list ap) +{ int h; int l; + int z; int q; int alt; int zero; @@ -83,7 +177,6 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { char buf[1024]; char c; void *v; - char *save = str; const char *cp; const char *head; int count = 0; @@ -91,22 +184,20 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { int zeropad; int dot; double dbl; + isc_boolean_t precision_set; #ifdef HAVE_LONG_DOUBLE long double ldbl; #endif char fmt[32]; - INSIST(str != NULL); - INSIST(format != NULL); + assert(emit != NULL); + assert(arg != NULL); + assert(format != NULL); while (*format != '\0') { if (*format != '%') { - if (size > 1) { - *str++ = *format; - size--; - } + emit(*format++, arg); count++; - format++; continue; } format++; @@ -114,10 +205,11 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { /* * Reset flags. */ - dot = neg = space = plus = left = zero = alt = h = l = q = 0; + dot = neg = space = plus = left = zero = alt = h = l = q = z = 0; width = precision = 0; head = ""; - length = pad = zeropad = 0; + pad = zeropad = 0; + precision_set = ISC_FALSE; do { if (*format == '#') { @@ -163,10 +255,12 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { dot = 1; if (*format == '*') { precision = va_arg(ap, int); + precision_set = ISC_TRUE; format++; } else if (isdigit((unsigned char)*format)) { char *e; precision = strtoul(format, &e, 10); + precision_set = ISC_TRUE; format = e; } } @@ -175,10 +269,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { case '\0': continue; case '%': - if (size > 1) { - *str++ = *format; - size--; - } + emit(*format, arg); count++; break; case 'q': @@ -197,6 +288,20 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { format++; } goto doint; + case 'z': + z = 1; + format++; + goto doint; +#ifdef WIN32 + case 'I': + /* Windows has I64 as a modifier for a quad. */ + if (format[1] == '6' && format[2] == '4') { + q = 1; + format += 3; + goto doint; + } + continue; +#endif case 'n': case 'i': case 'd': @@ -212,18 +317,23 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (h) { short int *p; p = va_arg(ap, short *); - REQUIRE(p != NULL); - *p = str - save; + assert(p != NULL); + *p = count; } else if (l) { long int *p; p = va_arg(ap, long *); - REQUIRE(p != NULL); - *p = str - save; + assert(p != NULL); + *p = count; + } else if (z) { + size_t *p; + p = va_arg(ap, size_t *); + assert(p != NULL); + *p = count; } else { int *p; p = va_arg(ap, int *); - REQUIRE(p != NULL); - *p = str - save; + assert(p != NULL); + *p = count; } break; case 'i': @@ -232,6 +342,8 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { tmpi = va_arg(ap, isc_int64_t); else if (l) tmpi = va_arg(ap, long int); + else if (z) + tmpi = va_arg(ap, ssize_t); else tmpi = va_arg(ap, int); if (tmpi < 0) { @@ -246,36 +358,97 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { head = ""; tmpui = tmpi; } - snprintf(buf, sizeof(buf), - "%" ISC_PRINT_QUADFORMAT "u", tmpui); + if (tmpui <= 0xffffffffU) + sprintf(buf, "%lu", + (unsigned long)tmpui); + else { + unsigned long mid; + unsigned long lo; + unsigned long hi; + lo = tmpui % 1000000000; + tmpui /= 1000000000; + mid = tmpui % 1000000000; + hi = tmpui / 1000000000; + if (hi != 0U) { + sprintf(buf, "%lu", hi); + sprintf(buf + strlen(buf), + "%09lu", mid); + } else + sprintf(buf, "%lu", mid); + sprintf(buf + strlen(buf), "%09lu", + lo); + } goto printint; case 'o': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, long int); + else if (z) + tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, int); - snprintf(buf, sizeof(buf), - alt ? "%#" ISC_PRINT_QUADFORMAT "o" - : "%" ISC_PRINT_QUADFORMAT "o", - tmpui); + if (tmpui <= 0xffffffffU) + sprintf(buf, alt ? "%#lo" : "%lo", + (unsigned long)tmpui); + else { + unsigned long mid; + unsigned long lo; + unsigned long hi; + lo = tmpui % 010000000000; + tmpui /= 010000000000; + mid = tmpui % 010000000000; + hi = tmpui / 010000000000; + if (hi != 0) { + sprintf(buf, + alt ? "%#lo" : "%lo", + hi); + sprintf(buf + strlen(buf), + "%09lo", mid); + } else + sprintf(buf, + alt ? "%#lo" : "%lo", + mid); + sprintf(buf + strlen(buf), "%09lo", lo); + } goto printint; case 'u': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); + else if (z) + tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); - snprintf(buf, sizeof(buf), - "%" ISC_PRINT_QUADFORMAT "u", tmpui); + if (tmpui <= 0xffffffffU) + sprintf(buf, "%lu", + (unsigned long)tmpui); + else { + unsigned long mid; + unsigned long lo; + unsigned long hi; + lo = tmpui % 1000000000; + tmpui /= 1000000000; + mid = tmpui % 1000000000; + hi = tmpui / 1000000000; + if (hi != 0U) { + sprintf(buf, "%lu", hi); + sprintf(buf + strlen(buf), + "%09lu", mid); + } else + sprintf(buf, "%lu", mid); + sprintf(buf + strlen(buf), "%09lu", + lo); + } goto printint; case 'x': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); + else if (z) + tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { @@ -283,14 +456,23 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (precision > 2) precision -= 2; } - snprintf(buf, sizeof(buf), - "%" ISC_PRINT_QUADFORMAT "x", tmpui); + if (tmpui <= 0xffffffffU) + sprintf(buf, "%lx", + (unsigned long)tmpui); + else { + unsigned long hi = tmpui>>32; + unsigned long lo = tmpui & 0xffffffff; + sprintf(buf, "%lx", hi); + sprintf(buf + strlen(buf), "%08lx", lo); + } goto printint; case 'X': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); + else if (z) + tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { @@ -298,11 +480,18 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (precision > 2) precision -= 2; } - snprintf(buf, sizeof(buf), - "%" ISC_PRINT_QUADFORMAT "X", tmpui); + if (tmpui <= 0xffffffffU) + sprintf(buf, "%lX", + (unsigned long)tmpui); + else { + unsigned long hi = tmpui>>32; + unsigned long lo = tmpui & 0xffffffff; + sprintf(buf, "%lX", hi); + sprintf(buf + strlen(buf), "%08lX", lo); + } goto printint; printint: - if (precision != 0 || width != 0) { + if (precision_set || width != 0U) { length = strlen(buf); if (length < precision) zeropad = precision - length; @@ -318,30 +507,23 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { count += strlen(head) + strlen(buf) + pad + zeropad; if (!left) { - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (pad > 0) { + emit(' ', arg); pad--; } } cp = head; - while (*cp != '\0' && size > 1) { - *str++ = *cp++; - size--; - } - while (zeropad > 0 && size > 1) { - *str++ = '0'; - size--; + while (*cp != '\0') + emit(*cp++, arg); + while (zeropad > 0) { + emit('0', arg); zeropad--; } cp = buf; - while (*cp != '\0' && size > 1) { - *str++ = *cp++; - size--; - } - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (*cp != '\0') + emit(*cp++, arg); + while (pad > 0) { + emit(' ', arg); pad--; } break; @@ -351,21 +533,23 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { break; case 's': cp = va_arg(ap, char *); - REQUIRE(cp != NULL); - if (precision != 0) { + if (precision_set) { /* * cp need not be NULL terminated. */ const char *tp; unsigned long n; + if (precision != 0U) + assert(cp != NULL); n = precision; tp = cp; while (n != 0 && *tp != '\0') n--, tp++; length = precision - n; } else { + assert(cp != NULL); length = strlen(cp); } if (width != 0) { @@ -375,26 +559,20 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { } count += pad + length; if (!left) - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (pad > 0) { + emit(' ', arg); pad--; } - if (precision != 0) - while (precision > 0 && *cp != '\0' && - size > 1) { - *str++ = *cp++; - size--; + if (precision_set) + while (precision > 0U && *cp != '\0') { + emit(*cp++, arg); precision--; } else - while (*cp != '\0' && size > 1) { - *str++ = *cp++; - size--; - } - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (*cp != '\0') + emit(*cp++, arg); + while (pad > 0) { + emit(' ', arg); pad--; } break; @@ -403,29 +581,20 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { if (width > 0) { count += width; width--; - if (left) { - *str++ = c; - size--; - } - while (width-- > 0 && size > 1) { - *str++ = ' '; - size--; - } - if (!left && size > 1) { - *str++ = c; - size--; - } + if (left) + emit(c, arg); + while (width-- > 0) + emit(' ', arg); + if (!left) + emit(c, arg); } else { count++; - if (size > 1) { - *str++ = c; - size--; - } + emit(c, arg); } break; case 'p': v = va_arg(ap, void *); - snprintf(buf, sizeof(buf), "%p", v); + sprintf(buf, "%p", v); length = strlen(buf); if (precision > length) zeropad = precision - length; @@ -436,50 +605,39 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { } count += length + pad + zeropad; if (!left) - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (pad > 0) { + emit(' ', arg); pad--; } cp = buf; if (zeropad > 0 && buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { - if (size > 1) { - *str++ = *cp++; - size--; - } - if (size > 1) { - *str++ = *cp++; - size--; - } - while (zeropad > 0 && size > 1) { - *str++ = '0'; - size--; + emit(*cp++, arg); + emit(*cp++, arg); + while (zeropad > 0) { + emit('0', arg); zeropad--; } } - while (*cp != '\0' && size > 1) { - *str++ = *cp++; - size--; - } - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (*cp != '\0') + emit(*cp++, arg); + while (pad > 0) { + emit(' ', arg); pad--; } break; case 'D': /*deprecated*/ - INSIST("use %ld instead of %D" == NULL); + assert("use %ld instead of %D" == NULL); case 'O': /*deprecated*/ - INSIST("use %lo instead of %O" == NULL); + assert("use %lo instead of %O" == NULL); case 'U': /*deprecated*/ - INSIST("use %lu instead of %U" == NULL); + assert("use %lu instead of %U" == NULL); case 'L': #ifdef HAVE_LONG_DOUBLE l = 1; #else - INSIST("long doubles are not supported" == NULL); + assert("long doubles are not supported" == NULL); #endif /*FALLTHROUGH*/ case 'e': @@ -501,10 +659,9 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { */ if (precision > 512) precision = 512; - snprintf(fmt, sizeof(fmt), - "%%%s%s.%lu%s%c", alt ? "#" : "", - plus ? "+" : space ? " " : "", - precision, l ? "L" : "", *format); + sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "", + plus ? "+" : space ? " " : "", + precision, l ? "L" : "", *format); switch (*format) { case 'e': case 'E': @@ -514,12 +671,12 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { #ifdef HAVE_LONG_DOUBLE if (l) { ldbl = va_arg(ap, long double); - snprintf(buf, sizeof(buf), fmt, ldbl); + sprintf(buf, fmt, ldbl); } else #endif { dbl = va_arg(ap, double); - snprintf(buf, sizeof(buf), fmt, dbl); + sprintf(buf, fmt, dbl); } length = strlen(buf); if (width > 0) { @@ -529,19 +686,15 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { } count += length + pad; if (!left) - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (pad > 0) { + emit(' ', arg); pad--; } cp = buf; - while (*cp != ' ' && size > 1) { - *str++ = *cp++; - size--; - } - while (pad > 0 && size > 1) { - *str++ = ' '; - size--; + while (*cp != ' ') + emit(*cp++, arg); + while (pad > 0) { + emit(' ', arg); pad--; } break; @@ -554,7 +707,5 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { } format++; } - if (size > 0) - *str = '\0'; return (count); } |
