+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
ISC_PLATFORM_USEDECLSPEC
ISC_PLATFORM_RLIMITTYPE
ISC_PLATFORM_HAVESYSUNH
+ISC_PLATFORM_NEEDFPRINTF
+ISC_PLATFORM_NEEDPRINTF
LWRES_PLATFORM_QUADFORMAT
ISC_PLATFORM_QUADFORMAT
DST_EXTRA_SRCS
+{ $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
#
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
#
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,
* 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
*/
@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.
*/
* 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
#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
***/
#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 */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: print.c,v 1.37 2010/10/18 23:47:08 tbox Exp $ */
-
/*! \file */
#include <config.h>
#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;
* 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;
char buf[1024];
char c;
void *v;
- char *save = str;
const char *cp;
const char *head;
int count = 0;
#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++;
/*
* 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;
case '\0':
continue;
case '%':
- if (size > 1) {
- *str++ = *format;
- size--;
- }
+ emit(*format, arg);
count++;
break;
case 'q':
format++;
}
goto doint;
+ case 'z':
+ z = 1;
+ format++;
+ goto doint;
case 'n':
case 'i':
case 'd':
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':
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) {
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)
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)
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) {
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) {
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;
}
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;
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':
}
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;
}
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;
}
format++;
}
- if (size > 0)
- *str = '\0';
return (count);
}
${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}
* 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>
char buf[10000];
isc_uint64_t ll = 8589934592ULL;
int n;
+ size_t size;
UNUSED(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);
+ ATF_CHECK_STREQ(buf, "3e8");
+
+ size = 1000;
+ memset(buf, 0xff, sizeof(buf));
+ n = isc_print_snprintf(buf, sizeof(buf), "%zo", size);
+ ATF_CHECK_EQ(n, 4);
+ ATF_CHECK_STREQ(buf, "1750");
+}
+
+ATF_TC(fprintf);
+ATF_TC_HEAD(fprintf, tc) {
+ atf_tc_set_md_var(tc, "descr", "fprintf implementation");
+}
+ATF_TC_BODY(fprintf, tc) {
+ FILE *f;
+ int n;
+ size_t size;
+ char buf[10000];
+
+ UNUSED(tc);
+
+ f = fopen("fprintf.test", "w+");
+ ATF_REQUIRE(f != NULL);
+
+ size = 1000;
+ n = isc_print_fprintf(f, "%zu", size);
+ ATF_CHECK_EQ(n, 4);
+
+ rewind(f);
+
+ memset(buf, 0, sizeof(buf));
+ n = fread(buf, 1, sizeof(buf), f);
+ ATF_CHECK_EQ(n, 4);
+
+ fclose(f);
+
+ ATF_CHECK_STREQ(buf, "1000");
+
+ if ((n > 0) && (!strcmp(buf, "1000")))
+ unlink("fprintf.test");
}
/*
*/
ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, snprintf);
+ ATF_TP_ADD_TC(tp, fprintf);
return (atf_no_error());
}