diff --git a/changes/bug5969_022 b/changes/bug5969_022 new file mode 100644 index 0000000000..57c8744267 --- /dev/null +++ b/changes/bug5969_022 @@ -0,0 +1,7 @@ + o Minor bugfixes + - Fix a build warning with Clang 3.1 related to our use of vasprint. + Fix for bug 5969. Bugfix on 0.2.2.11-alpha. + + o Compilation improvements: + - Tell GCC and Clang to check for any errors in format strings passed + to the tor_v*(print|scan)f functions. diff --git a/src/common/compat.h b/src/common/compat.h index b0ef63badf..7edd889ee3 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -259,11 +259,12 @@ void tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1)); int tor_snprintf(char *str, size_t size, const char *format, ...) CHECK_PRINTF(3,4) ATTR_NONNULL((1,3)); int tor_vsnprintf(char *str, size_t size, const char *format, va_list args) - ATTR_NONNULL((1,3)); + CHECK_PRINTF(3,0) ATTR_NONNULL((1,3)); int tor_asprintf(char **strp, const char *fmt, ...) CHECK_PRINTF(2,3); -int tor_vasprintf(char **strp, const char *fmt, va_list args); +int tor_vasprintf(char **strp, const char *fmt, va_list args) + CHECK_PRINTF(2,0); const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) ATTR_NONNULL((1,3)); diff --git a/src/common/log.c b/src/common/log.c index df27066f92..f509ddcd6e 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -137,6 +137,13 @@ static void close_log(logfile_t *victim); static char *domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen); +static INLINE char *format_msg(char *buf, size_t buf_len, + log_domain_mask_t domain, int severity, const char *funcname, + const char *format, va_list ap, size_t *msg_len_out) + CHECK_PRINTF(6,0); +static void logv(int severity, log_domain_mask_t domain, const char *funcname, + const char *format, va_list ap) + CHECK_PRINTF(4,0); /** Name of the application: used to generate the message we write at the * start of each new log. */ diff --git a/src/common/util.h b/src/common/util.h index 567efaafef..36601fa790 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -213,7 +213,11 @@ const char *escaped(const char *string); struct smartlist_t; void wrap_string(struct smartlist_t *out, const char *string, size_t width, const char *prefix0, const char *prefixRest); -int tor_vsscanf(const char *buf, const char *pattern, va_list ap); +int tor_vsscanf(const char *buf, const char *pattern, va_list ap) +#ifdef __GNUC__ + __attribute__((format(scanf, 2, 0))) +#endif + ; int tor_sscanf(const char *buf, const char *pattern, ...) #ifdef __GNUC__ __attribute__((format(scanf, 2, 3))) diff --git a/src/or/control.c b/src/or/control.c index 1bba2e18de..91d94fd665 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -136,6 +136,13 @@ typedef int event_format_t; static void connection_printf_to_buf(control_connection_t *conn, const char *format, ...) CHECK_PRINTF(2,3); +static void send_control_event_impl(uint16_t event, event_format_t which, + const char *format, va_list ap) + CHECK_PRINTF(3,0); +static int control_event_status(int type, int severity, const char *format, + va_list args) + CHECK_PRINTF(3,0); + static void send_control_done(control_connection_t *conn); static void send_control_event(uint16_t event, event_format_t which, const char *format, ...) @@ -4208,6 +4215,7 @@ control_event_my_descriptor_changed(void) static int control_event_status(int type, int severity, const char *format, va_list args) { + char *user_buf = NULL; char format_buf[160]; const char *status, *sev; @@ -4239,13 +4247,15 @@ control_event_status(int type, int severity, const char *format, va_list args) log_warn(LD_BUG, "Unrecognized status severity %d", severity); return -1; } - if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s %s\r\n", - status, sev, format)<0) { + if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s\r\n", + status, sev)<0) { log_warn(LD_BUG, "Format string too long."); return -1; } + tor_vasprintf(&user_buf, format, args); - send_control_event_impl(type, ALL_FORMATS, format_buf, args); + send_control_event(type, ALL_FORMATS, "%s %s", format_buf, user_buf); + tor_free(user_buf); return 0; }