[dovecot-cvs] dovecot: Require C99 compatible vsnprintf(). Removed printf_stri...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jun 11 02:21:34 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/09415e6a0892
changeset: 5681:09415e6a0892
user: Timo Sirainen <tss at iki.fi>
date: Mon Jun 11 02:21:30 2007 +0300
description:
Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
replaced the code with printf_format_fix*() and vsnprintf().
diffstat:
11 files changed, 155 insertions(+), 484 deletions(-)
AUTHORS | 14 -
configure.in | 31 +++
src/lib/Makefile.am | 2
src/lib/failures.c | 13 -
src/lib/printf-format-fix.c | 89 ++++++-----
src/lib/printf-format-fix.h | 11 +
src/lib/printf-upper-bound.c | 326 ------------------------------------------
src/lib/printf-upper-bound.h | 10 -
src/lib/str.c | 32 +---
src/lib/strfuncs.c | 109 ++++++--------
src/lib/strfuncs.h | 2
diffs (truncated from 830 to 300 lines):
diff -r 7577fb89916a -r 09415e6a0892 AUTHORS
--- a/AUTHORS Mon Jun 11 02:16:59 2007 +0300
+++ b/AUTHORS Mon Jun 11 02:21:30 2007 +0300
@@ -14,20 +14,6 @@ at Carnegie Mellon University (http://ww
at Carnegie Mellon University (http://www.cmu.edu/computing/).
(src/lib/base64.c, src/lib/utc-mktime.c)
-GLib Team (src/lib/printf-upper-bound.c)
----------
-Shawn T. Amundson <amundson at gimp.org>
-Jeff Garzik <jgarzik at pobox.com>
-Raja R Harinath <harinath at cs.umn.edu>
-Tim Janik <timj at gtk.org>
-Elliot Lee <sopwith at redhat.com>
-Tor Lillqvist <tml at iki.fi>
-Paolo Molaro <lupus at debian.org>
-Havoc Pennington <hp at pobox.com>
-Manish Singh <yosh at gimp.org>
-Owen Taylor <otaylor at gtk.org>
-Sebastian Wilhelmi <wilhelmi at ira.uka.de>
-
Simon Tatham (src/imap/imap-thread.c merge sorting)
Vaclav Haisman <v.haisman at sh.cvut.cz> (src/lib/ioloop-kqueue.c)
diff -r 7577fb89916a -r 09415e6a0892 configure.in
--- a/configure.in Mon Jun 11 02:16:59 2007 +0300
+++ b/configure.in Mon Jun 11 02:21:30 2007 +0300
@@ -433,7 +433,7 @@ fi
dnl * after -lsocket and -lnsl tests, inet_aton() may be in them
AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \
- strcasecmp stricmp vsnprintf vsyslog writev pread \
+ strcasecmp stricmp vsyslog writev pread \
setrlimit setproctitle seteuid setreuid setegid setresgid \
strtoull strtouq setpriority quotactl getmntent kqueue kevent \
getrusage backtrace_symbols walkcontext dirfd \
@@ -1311,6 +1311,35 @@ AC_TRY_COMPILE([
])
dnl ***
+dnl *** C99 vsnprintf()?
+dnl ***
+
+AC_CACHE_CHECK([for C99 vsnprintf()],c99_vsnprintf,[
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ #include <stdio.h>
+ #include <stdarg.h>
+ static int f(const char *fmt, ...) {
+ va_list args;
+ char buf[13];
+ int ret;
+
+ va_start(args, fmt);
+ ret = vsnprintf(buf, 11, fmt, args) != 12 || buf[11-1] != '\0';
+ va_end(args);
+ return ret;
+ }
+ int main() {
+ return f("hello %s%d", "world", 1);
+ }]])],
+ [c99_vsnprintf=yes],
+ [c99_vsnprintf=no],
+ [])
+])
+if test $c99_vsnprintf = no; then
+ AC_ERROR([You don't appear to have C99 compatible vsnprintf() call])
+fi
+
+dnl ***
dnl *** va_copy checks (from GLIB)
dnl ***
diff -r 7577fb89916a -r 09415e6a0892 src/lib/Makefile.am
--- a/src/lib/Makefile.am Mon Jun 11 02:16:59 2007 +0300
+++ b/src/lib/Makefile.am Mon Jun 11 02:21:30 2007 +0300
@@ -67,7 +67,6 @@ liblib_a_SOURCES = \
ostream-crlf.c \
primes.c \
printf-format-fix.c \
- printf-upper-bound.c \
process-title.c \
randgen.c \
read-full.c \
@@ -148,7 +147,6 @@ headers = \
ostream-internal.h \
primes.h \
printf-format-fix.h \
- printf-upper-bound.h \
process-title.h \
randgen.h \
read-full.h \
diff -r 7577fb89916a -r 09415e6a0892 src/lib/failures.c
--- a/src/lib/failures.c Mon Jun 11 02:16:59 2007 +0300
+++ b/src/lib/failures.c Mon Jun 11 02:21:30 2007 +0300
@@ -83,7 +83,7 @@ default_handler(const char *prefix, FILE
if (recursed == 2) {
/* we're being called from some signal handler, or
- printf_format_fix() killed us again */
+ printf_format_fix_unsafe() killed us again */
return -1;
}
@@ -98,9 +98,8 @@ default_handler(const char *prefix, FILE
VA_COPY(args2, args);
- t_push();
if (recursed == 2) {
- /* printf_format_fix() probably killed us last time,
+ /* printf_format_fix_unsafe() probably killed us last time,
just write the format now. */
fputs("recursed: ", f);
@@ -114,13 +113,10 @@ default_handler(const char *prefix, FILE
errno = old_errno;
/* make sure there's no %n in there and fix %m */
- (void)printf_format_fix(&format);
- vfprintf(f, format, args2);
+ vfprintf(f, printf_format_fix_unsafe(format), args2);
}
fputc('\n', f);
-
- t_pop();
errno = old_errno;
recursed--;
@@ -290,8 +286,7 @@ syslog_handler(int level, const char *fo
/* make sure there's no %n in there. vsyslog() supports %m, but since
we'll convert it ourself anyway, we might as well it */
- (void)printf_format_fix(&format);
- vsyslog(level, format, args);
+ vsyslog(level, printf_format_fix_unsafe(format), args);
recursed--;
return 0;
diff -r 7577fb89916a -r 09415e6a0892 src/lib/printf-format-fix.c
--- a/src/lib/printf-format-fix.c Mon Jun 11 02:16:59 2007 +0300
+++ b/src/lib/printf-format-fix.c Mon Jun 11 02:21:30 2007 +0300
@@ -3,68 +3,81 @@
#include "lib.h"
#include "printf-format-fix.h"
-static const char *fix_format_real(const char *fmt, const char *p)
+static const char *
+fix_format_real(const char *fmt, const char *p, unsigned int *len_r)
{
const char *errstr;
char *buf;
- size_t pos, alloc, errlen;
+ unsigned int len1, len2, len3;
+
+ i_assert((size_t)(p - fmt) < INT_MAX);
errstr = strerror(errno);
- errlen = strlen(errstr);
- pos = (size_t) (p-fmt);
- i_assert(pos < SSIZE_T_MAX);
+ /* we'll assume that there's only one %m in the format string.
+ this simplifies the code and there's really no good reason to have
+ it multiple times. */
+ len1 = p - fmt;
+ len2 = strlen(errstr);
+ len3 = strlen(fmt + 1);
- alloc = pos + errlen + 128;
- buf = t_buffer_get(alloc);
+ /* @UNSAFE */
+ buf = t_buffer_get(len1 + len2 + len3 + 1);
+ memcpy(buf, fmt, len1);
+ memcpy(buf + len1, errstr, len2);
+ memcpy(buf + len1 + len2, p + 1, len3);
+ buf[len1 + len2 + len3] = '\0';
- memcpy(buf, fmt, pos);
-
- while (*p != '\0') {
- if (*p == '%' && p[1] == 'm') {
- if (pos+errlen+1 > alloc) {
- alloc += errlen+1 + 128;
- buf = t_buffer_get(alloc);
- }
-
- memcpy(buf+pos, errstr, errlen);
- pos += errlen;
- p += 2;
- } else {
- /* p + \0 */
- if (pos+2 > alloc) {
- alloc += 128;
- buf = t_buffer_get(alloc);
- }
-
- buf[pos++] = *p;
- p++;
- }
- }
-
- buf[pos++] = '\0';
- t_buffer_alloc(pos);
+ *len_r = len1 + len2 + len3;
return buf;
}
-bool printf_format_fix(const char **format)
+static const char *
+printf_format_fix_noalloc(const char *format, unsigned int *len_r)
{
const char *p;
- for (p = *format; *p != '\0'; p++) {
+ for (p = format; *p != '\0'; p++) {
if (*p++ == '%') {
switch (*p) {
case 'n':
i_panic("%%n modifier used");
case 'm':
- *format = fix_format_real(*format, p-1);
- return TRUE;
+ return fix_format_real(format, p-1, len_r);
case '\0':
i_panic("%% modifier missing");
}
}
}
- return FALSE;
+ *len_r = p - format;
+ return format;
}
+const char *printf_format_fix_get_len(const char *format, unsigned int *len_r)
+{
+ const char *ret;
+
+ ret = printf_format_fix_noalloc(format, len_r);
+ if (ret != format)
+ t_buffer_alloc(*len_r + 1);
+ return ret;
+}
+
+const char *printf_format_fix(const char *format)
+{
+ const char *ret;
+ unsigned int len;
+
+ ret = printf_format_fix_noalloc(format, &len);
+ if (ret != format)
+ t_buffer_alloc(len + 1);
+ return ret;
+}
+
+const char *printf_format_fix_unsafe(const char *format)
+{
+ unsigned int len;
+
+ return printf_format_fix_noalloc(format, &len);
+}
diff -r 7577fb89916a -r 09415e6a0892 src/lib/printf-format-fix.h
--- a/src/lib/printf-format-fix.h Mon Jun 11 02:16:59 2007 +0300
+++ b/src/lib/printf-format-fix.h Mon Jun 11 02:21:30 2007 +0300
@@ -2,7 +2,14 @@
#define __PRINTF_FORMAT_FIX_H
/* Replaces %m in format with strerror(errno) and panics if %n modifier is
- used. Returns TRUE if format was modified. */
-bool printf_format_fix(const char **format);
+ used. If the format string was modified, it's returned from data stack. */
+const char *printf_format_fix(const char *format) __attr_format_arg__(1);
+/* Like printf_format_fix(), except return also the format string's length. */
+const char *printf_format_fix_get_len(const char *format, unsigned int *len_r)
+ __attr_format_arg__(1);
+/* Like printf_format_fix(), except the format string is written to data
+ stack without actually allocating it. Data stack must not be used until
+ format string is no longer needed. */
+const char *printf_format_fix_unsafe(const char *format) __attr_format_arg__(1);
#endif
diff -r 7577fb89916a -r 09415e6a0892 src/lib/printf-upper-bound.c
--- a/src/lib/printf-upper-bound.c Mon Jun 11 02:16:59 2007 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,326 +0,0 @@
-/*
- Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- Modified by the GLib Team and others 1997-1999.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
More information about the dovecot-cvs
mailing list