Mercurial > dovecot > core-2.2
changeset 837:ec6dd72cb8e3 HEAD
Use vsnprintf() always when possible, even if we went through the
upper_bound function. DEBUG message in data stack might have sometimes
caused an infinite loop. Made sure infinite loops don't happen anymore with
failure handlers. str_printfa() didn't handle %m. Made my_vsyslog() a lot
simpler, since t_strdup_printf() is now safe enough to call in failure
handler.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 22 Dec 2002 08:25:50 +0200 |
parents | eefa28ef9646 |
children | a6cd073c5283 |
files | src/lib/compat.c src/lib/data-stack.c src/lib/failures.c src/lib/str.c src/lib/strfuncs.c |
diffstat | 5 files changed, 123 insertions(+), 101 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/compat.c Sun Dec 22 00:39:15 2002 +0200 +++ b/src/lib/compat.c Sun Dec 22 08:25:50 2002 +0200 @@ -72,30 +72,7 @@ #ifndef HAVE_VSYSLOG void my_vsyslog(int priority, const char *format, va_list args) { - const char *str; - char buf[1024]; - -#ifdef HAVE_VSNPRINTF - int ret; - - ret = vsnprintf(buf, sizeof(buf), format, args); - if (ret < 0 || (size_t)ret >= sizeof(buf)) - buf[sizeof(buf)-1] = '\0'; - str = buf; -#else - va_list args2; - - VA_COPY(args2, args); - - if (printf_string_upper_bound(format, args) < sizeof(buf)) { - vsprintf(buf, format, args); - str = buf; - } else { - /* this may not be safe but not choice really.. */ - str = t_strdup_vprintf(format, args2); - } -#endif - syslog(priority, "%s", str); + syslog(priority, "%s", t_strdup_vprintf(format, args)); } #endif
--- a/src/lib/data-stack.c Sun Dec 22 00:39:15 2002 +0200 +++ b/src/lib/data-stack.c Sun Dec 22 08:25:50 2002 +0200 @@ -198,6 +198,9 @@ { StackBlock *block; void *ret; +#ifdef DEBUG + int warn = FALSE; +#endif if (size == 0) return NULL; @@ -233,7 +236,7 @@ } else { block = mem_block_alloc(size); #ifdef DEBUG - i_warning("Growing data stack with: %"PRIuSIZE_T, block->size); + warn = TRUE; #endif } @@ -245,7 +248,16 @@ current_block->next = block; current_block = block; - return STACK_BLOCK_DATA(current_block); + ret = STACK_BLOCK_DATA(current_block); +#ifdef DEBUG + if (warn) { + /* warn later, so that if i_warning() wants to allocate more + memory we don't go to infinite loop */ + i_warning("Growing data stack with: %"PRIuSIZE_T, block->size); + } +#endif + + return ret; } void *t_malloc(size_t size)
--- a/src/lib/failures.c Sun Dec 22 00:39:15 2002 +0200 +++ b/src/lib/failures.c Sun Dec 22 08:25:50 2002 +0200 @@ -78,26 +78,56 @@ } } +static void default_handler(const char *prefix, const char *format, + va_list args) +{ + static int recursed = 0; + int old_errno = errno; + + if (recursed == 2) { + /* we're being called from some signal handler, or + printf_string_upper_bound() killed us again */ + return; + } + + recursed++; + + if (log_fd == NULL) + log_fd = stderr; + + if (recursed == 2) { + /* write without fixing format, that probably killed us + last time. */ + + /* make sure there's no %n in there */ + (void)printf_string_upper_bound(format, args); + vfprintf(log_fd, format, args); + fputs(" - recursed!", log_fd); + } else { + write_prefix(log_fd); + + fputs(prefix, log_fd); + format = printf_string_fix_format(format); + /* make sure there's no %n in there */ + (void)printf_string_upper_bound(format, args); + vfprintf(log_fd, format, args); + } + + fputc('\n', log_fd); + + errno = old_errno; + recursed--; +} + static void default_panic_handler(const char *format, va_list args) { - if (log_fd == NULL) log_fd = stderr; - write_prefix(log_fd); - - fputs("Panic: ", log_fd); - vfprintf(log_fd, printf_string_fix_format(format), args); - fputc('\n', log_fd); - + default_handler("Panic: ", format, args); abort(); } static void default_fatal_handler(int status, const char *format, va_list args) { - if (log_fd == NULL) log_fd = stderr; - write_prefix(log_fd); - - fputs("Fatal: ", log_fd); - vfprintf(log_fd, printf_string_fix_format(format), args); - fputc('\n', log_fd); + default_handler("Fatal: ", format, args); if (fflush(log_fd) < 0 && status == FATAL_DEFAULT) status = FATAL_LOGWRITE; @@ -109,14 +139,7 @@ { int old_errno = errno; - if (log_fd == NULL) log_fd = stderr; - write_prefix(log_fd); - - t_push(); - fputs("Error: ", log_fd); - vfprintf(log_fd, printf_string_fix_format(format), args); - fputc('\n', log_fd); - t_pop(); + default_handler("Error: ", format, args); if (fflush(log_fd) < 0) exit(FATAL_LOGWRITE); @@ -128,14 +151,7 @@ { int old_errno = errno; - if (log_fd == NULL) log_fd = stderr; - write_prefix(log_fd); - - t_push(); - fputs("Warning: ", log_fd); - vfprintf(log_fd, printf_string_fix_format(format), args); - fputc('\n', log_fd); - t_pop(); + default_handler("Warning: ", format, args); if (fflush(log_fd) < 0) exit(FATAL_LOGWRITE); @@ -147,15 +163,9 @@ { int old_errno = errno; - if (log_info_fd == NULL) log_info_fd = stderr; - write_prefix(log_info_fd); + default_handler("Info: ", format, args); - t_push(); - vfprintf(log_info_fd, printf_string_fix_format(format), args); - fputc('\n', log_info_fd); - t_pop(); - - if (fflush(log_info_fd) < 0) + if (fflush(log_fd) < 0) exit(FATAL_LOGWRITE); errno = old_errno; @@ -250,31 +260,47 @@ info_handler = func; } +static void syslog_handler(int level, const char *format, va_list args) +{ + static int recursed = 0; + + if (recursed != 0) + return; + + recursed++; + + /* make sure there's no %n in there */ + (void)printf_string_upper_bound(format, args); + + vsyslog(level, format, args); + recursed--; +} + void i_syslog_panic_handler(const char *fmt, va_list args) { - vsyslog(LOG_CRIT, fmt, args); + syslog_handler(LOG_CRIT, fmt, args); abort(); } void i_syslog_fatal_handler(int status, const char *fmt, va_list args) { - vsyslog(LOG_CRIT, fmt, args); + syslog_handler(LOG_CRIT, fmt, args); exit(status); } void i_syslog_error_handler(const char *fmt, va_list args) { - vsyslog(LOG_ERR, fmt, args); + syslog_handler(LOG_ERR, fmt, args); } void i_syslog_warning_handler(const char *fmt, va_list args) { - vsyslog(LOG_WARNING, fmt, args); + syslog_handler(LOG_WARNING, fmt, args); } void i_syslog_info_handler(const char *fmt, va_list args) { - vsyslog(LOG_INFO, fmt, args); + syslog_handler(LOG_INFO, fmt, args); } void i_set_failure_syslog(const char *ident, int options, int facility)
--- a/src/lib/str.c Sun Dec 22 00:39:15 2002 +0200 +++ b/src/lib/str.c Sun Dec 22 08:25:50 2002 +0200 @@ -121,12 +121,25 @@ void str_vprintfa(String *str, const char *fmt, va_list args) { char *buf; - size_t len; + int ret; + size_t len, append_len; len = buffer_get_used_size(str); - buf = buffer_append_space(str, printf_string_upper_bound(fmt, args)); - len += vsprintf(buf, fmt, args); + fmt = printf_string_fix_format(fmt); + append_len = printf_string_upper_bound(fmt, args); + + buf = buffer_append_space(str, append_len); + +#ifdef HAVE_VSNPRINTF + ret = vsnprintf(buf, append_len, fmt, args); + i_assert(ret >= 0 && (size_t)ret <= append_len); +#else + ret = vsprintf(buf, fmt, args); + i_assert(ret >= 0); +#endif + + len += ret; buffer_set_used_size(str, len); }
--- a/src/lib/strfuncs.c Sun Dec 22 00:39:15 2002 +0200 +++ b/src/lib/strfuncs.c Sun Dec 22 08:25:50 2002 +0200 @@ -389,44 +389,30 @@ int i_snprintf(char *dest, size_t max_chars, const char *format, ...) { -#ifdef HAVE_VSNPRINTF +#ifndef HAVE_VSNPRINTF + char *buf; +#endif va_list args; + ssize_t len; int ret; - i_assert(dest != NULL); i_assert(max_chars < INT_MAX); - i_assert(format != NULL); - - t_push(); - va_start(args, format); - ret = vsnprintf(dest, max_chars, - printf_string_fix_format(format), args); - va_end(args); - t_pop(); - - if (ret < 0 || (size_t)ret >= max_chars) { - dest[max_chars-1] = '\0'; - return -1; - } - - return 0; -#else - char *buf; - va_list args; - int len, ret; - - i_assert(dest != NULL); - i_assert(max_chars < INT_MAX); - i_assert(format != NULL); t_push(); va_start(args, format); format = printf_string_fix_format(format); - buf = t_buffer_get(printf_string_upper_bound(format, args)); + len = printf_string_upper_bound(format, args); va_end(args); + i_assert(len >= 0); + +#ifdef HAVE_VSNPRINTF + len = vsnprintf(dest, max_chars, format, args); +#else + buf = t_buffer_get(len); len = vsprintf(buf, format, args); +#endif if (len < 0) { /* some error occured */ len = 0; @@ -439,12 +425,13 @@ ret = 0; } - memcpy(dest, buf, len); +#ifndef HAVE_VSNPRINTF + memcpy(dest, buf, len); +#endif dest[len] = '\0'; t_pop(); return ret; -#endif } #define STRDUP_CORE(alloc_func, str) STMT_START { \ @@ -608,7 +595,8 @@ ALLOC_FUNC alloc_func, Pool pool) { va_list temp_args; - char *ret; + char *ret; + size_t len; if (format == NULL) return NULL; @@ -617,8 +605,14 @@ VA_COPY(temp_args, args); - ret = alloc_func(pool, printf_string_upper_bound(format, args)); + len = printf_string_upper_bound(format, args); + ret = alloc_func(pool, len); + +#ifdef HAVE_VSNPRINTF + vsnprintf(ret, len, format, args); +#else vsprintf(ret, format, args); +#endif va_end(temp_args);