Commit cadf8d68 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] add %z format options to printf

4123.	[port]		Added %z (size_t) format options to the portable
			internal printf/sprintf implementation. [RT #39586]
parent f5c20627
4123. [port] Added %z (size_t) format options to the portable
internal printf/sprintf implementation. [RT #39586]
4122. [bug] The server could match a shorter prefix than what was
available in CLIENT-IP policy triggers, and so, an
unexpected action could be taken. This has been
......
......@@ -719,6 +719,8 @@ LWRES_PLATFORM_USEDECLSPEC
ISC_PLATFORM_USEDECLSPEC
ISC_PLATFORM_RLIMITTYPE
ISC_PLATFORM_HAVESYSUNH
ISC_PLATFORM_NEEDFPRINTF
ISC_PLATFORM_NEEDPRINTF
LWRES_PLATFORM_QUADFORMAT
ISC_PLATFORM_QUADFORMAT
DST_EXTRA_SRCS
......@@ -18764,6 +18766,46 @@ fi
 
 
 
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking printf for %z support" >&5
$as_echo_n "checking printf for %z support... " >&6; }
if test "$cross_compiling" = yes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming target platform supports %z" >&5
$as_echo "assuming target platform supports %z" >&6; }
ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF'
ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF'
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
main() {
/* Assume sprintf matches printf/fprintf. */
size_t j = 0;
char buf[100];
buf[0] = 0;
sprintf(buf, "%zu", j);
exit(strcmp(buf, "0") != 0);
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF'
ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF'
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
ISC_PLATFORM_NEEDPRINTF='#define ISC_PLATFORM_NEEDPRINTF 1'
ISC_PLATFORM_NEEDFPRINTF='#define ISC_PLATFORM_NEEDFPRINTF 1'
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
#
# Security Stuff
#
......
......@@ -3345,6 +3345,30 @@ main() {
AC_SUBST(ISC_PLATFORM_QUADFORMAT)
AC_SUBST(LWRES_PLATFORM_QUADFORMAT)
AC_MSG_CHECKING([printf for %z support])
AC_TRY_RUN([
#include <stdio.h>
main() {
/* Assume sprintf matches printf/fprintf. */
size_t j = 0;
char buf[100];
buf[0] = 0;
sprintf(buf, "%zu", j);
exit(strcmp(buf, "0") != 0);
}
],
[AC_MSG_RESULT(yes)
ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF'
ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF'],
[AC_MSG_RESULT(no)
ISC_PLATFORM_NEEDPRINTF='#define ISC_PLATFORM_NEEDPRINTF 1'
ISC_PLATFORM_NEEDFPRINTF='#define ISC_PLATFORM_NEEDFPRINTF 1'],
[AC_MSG_RESULT([assuming target platform supports %z])
ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF'
ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF'])
AC_SUBST(ISC_PLATFORM_NEEDPRINTF)
AC_SUBST(ISC_PLATFORM_NEEDFPRINTF)
#
# Security Stuff
#
......
......@@ -1656,8 +1656,8 @@ fix_triggers(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_INFO_LEVEL,
"(re)loading policy zone '%s' changed from"
" %ld to %ld qname, %ld to %ld nsdname,"
" %ld to %ld IP, %ld to %ld NSIP entries",
" %zd to %zd qname, %zd to %zd nsdname,"
" %zd to %zd IP, %zd to %zd NSIP entries",
namebuf,
old_totals.qname, rpzs->total_triggers.qname,
old_totals.nsdname, rpzs->total_triggers.nsdname,
......
......@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: platform.h.in,v 1.56 2010/12/18 01:56:23 each Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
......@@ -171,6 +169,16 @@
*/
@ISC_PLATFORM_NEEDSPRINTF@
/*! \brief
* If this system need a modern printf() that format size %z (size_t).
*/
@ISC_PLATFORM_NEEDPRINTF@
/*! \brief
* If this system need a modern fprintf() that format size %z (size_t).
*/
@ISC_PLATFORM_NEEDFPRINTF@
/*! \brief
* The printf format string modifier to use with isc_uint64_t values.
*/
......
......@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: print.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */
#ifndef ISC_PRINT_H
#define ISC_PRINT_H 1
......@@ -47,6 +45,16 @@
#undef sprintf
#endif
#if !defined(ISC_PLATFORM_NEEDFPRINTF) && defined(ISC__PRINT_SOURCE)
#define ISC_PLATFORM_NEEDFPRINTF
#undef fprintf
#endif
#if !defined(ISC_PLATFORM_NEEDPRINTF) && defined(ISC__PRINT_SOURCE)
#define ISC_PLATFORM_NEEDPRINTF
#undef printf
#endif
/***
*** Macros
***/
......@@ -85,6 +93,18 @@ isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
#define sprintf isc_print_sprintf
#endif
#ifdef ISC_PLATFORM_NEEDPRINTF
int
isc_print_printf(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
#define printf isc_print_printf
#endif
#ifdef ISC_PLATFORM_NEEDFPRINTF
int
isc_print_fprintf(FILE * fp, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
#define fprintf isc_print_fprintf
#endif
ISC_LANG_ENDDECLS
#endif /* ISC_PRINT_H */
......@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: print.c,v 1.37 2010/10/18 23:47:08 tbox Exp $ */
/*! \file */
#include <config.h>
......@@ -34,6 +32,44 @@
#include <isc/stdlib.h>
#include <isc/util.h>
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) {
fputc(c, arg);
}
static int
isc_print_vfprintf(FILE *fp, const char *format, va_list ap) {
INSIST(fp != NULL);
INSIST(format != NULL);
return (isc__print_printf(file_emit, fp, format, ap));
}
int
isc_print_printf(const char *format, ...) {
va_list ap;
int n;
va_start(ap, format);
n = isc_print_vfprintf(stdout, format, ap);
va_end(ap);
return (n);
}
int
isc_print_fprintf(FILE *fp, const char *format, ...) {
va_list ap;
int n;
va_start(ap, format);
n = isc_print_vfprintf(fp, format, ap);
va_end(ap);
return (n);
}
int
isc_print_sprintf(char *str, const char *format, ...) {
va_list ap;
......@@ -64,10 +100,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;
INSIST(str != NULL);
INSIST(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 +149,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;
......@@ -96,17 +161,14 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
#endif
char fmt[32];
INSIST(str != NULL);
INSIST(emit != NULL);
INSIST(arg != NULL);
INSIST(format != NULL);
while (*format != '\0') {
if (*format != '%') {
if (size > 1) {
*str++ = *format;
size--;
}
emit(*format++, arg);
count++;
format++;
continue;
}
format++;
......@@ -114,7 +176,7 @@ 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 = "";
pad = zeropad = 0;
......@@ -175,10 +237,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 +256,10 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
format++;
}
goto doint;
case 'z':
z = 1;
format++;
goto doint;
case 'n':
case 'i':
case 'd':
......@@ -213,17 +276,22 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
short int *p;
p = va_arg(ap, short *);
REQUIRE(p != NULL);
*p = str - save;
*p = count;
} else if (l) {
long int *p;
p = va_arg(ap, long *);
REQUIRE(p != NULL);
*p = str - save;
*p = count;
} else if (z) {
size_t *p;
p = va_arg(ap, size_t *);
REQUIRE(p != NULL);
*p = count;
} else {
int *p;
p = va_arg(ap, int *);
REQUIRE(p != NULL);
*p = str - save;
*p = count;
}
break;
case 'i':
......@@ -232,6 +300,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) {
......@@ -270,6 +340,8 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
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);
if (tmpui <= 0xffffffffU)
......@@ -301,6 +373,8 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
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 (tmpui <= 0xffffffffU)
......@@ -327,6 +401,8 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
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) {
......@@ -349,6 +425,8 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
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) {
......@@ -383,30 +461,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;
......@@ -440,26 +511,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--;
while (precision > 0 && *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;
......@@ -468,24 +533,15 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
if (width > 0) {
count += width;
width--;
if (left && size > 1) {
*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':
......@@ -501,35 +557,24 @@ 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;
......@@ -593,19 +638,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;
......@@ -618,7 +659,5 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
}
format++;
}
if (size > 0)
*str = '\0';
return (count);
}
......@@ -99,7 +99,8 @@ sockaddr_test@EXEEXT@: sockaddr_test.@O@ isctest.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
sockaddr_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
print_test@EXEEXT@: print_test.@O@ ${ISCDEPLIBS} ${top_srcdir}/lib/isc/print.c
print_test.@O@: ${top_srcdir}/lib/isc/print.c
print_test@EXEEXT@: print_test.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
print_test.@O@ ${ISCLIBS} ${LIBS}
......
......@@ -28,11 +28,17 @@
* it on all platforms even if we don't include it in libisc.
*/
#include <isc/platform.h>
#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && !defined(ISC_PLATFORM_NEEDSPRINTF)
#if !defined(ISC_PLATFORM_NEEDPRINTF) && \
!defined(ISC_PLATFORM_NEEDFPRINTF) && \
!defined(ISC_PLATFORM_NEEDSPRINTF) && \
!defined(ISC_PLATFORM_NEEDVSNPRINTF)
#define ISC__PRINT_SOURCE
#include "../print.c"
#else
#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) || !defined(ISC_PLATFORM_NEEDSPRINTF)
#if !defined(ISC_PLATFORM_NEEDPRINTF) || \
!defined(ISC_PLATFORM_NEEDFPRINTF) || \
!defined(ISC_PLATFORM_NEEDSPRINTF) || \
!defined(ISC_PLATFORM_NEEDVSNPRINTF)
#define ISC__PRINT_SOURCE
#endif
#include <isc/print.h>
......@@ -48,6 +54,7 @@ ATF_TC_BODY(snprintf, tc) {
char buf[10000];
isc_uint64_t ll = 8589934592ULL;
int n;
size_t size;
UNUSED(tc);
......@@ -65,6 +72,57 @@ ATF_TC_BODY(snprintf, tc) {
n = isc_print_snprintf(buf, sizeof(buf), "%llu", ll);
ATF_CHECK_EQ(n, 10);
ATF_CHECK_STREQ(buf, "8589934592");
size = 1000;
memset(buf, 0xff, sizeof(buf));
n = isc_print_snprintf(buf, sizeof(buf), "%zu", size);
ATF_CHECK_EQ(n, 4);
ATF_CHECK_STREQ(buf, "1000");
size = 1000;
memset(buf, 0xff, sizeof(buf));
n = isc_print_snprintf(buf, sizeof(buf), "%zx", size);
ATF_CHECK_EQ(n, 3);