From 19247e5510279f018f8358a72b38cc5aa62fac8a Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 20 Sep 2007 10:43:11 +0200 Subject: nfv?asprintf are broken without va_copy, workaround them. * drop nfasprintf. * move nfvasprintf into imap-send.c back, and let it work on a 8k buffer, and die() in case of overflow. It should be enough for imap commands, if someone cares about imap-send, he's welcomed to fix it properly. * replace nfvasprintf use in merge-recursive with a copy of the strbuf_addf logic, it's one place, we'll live with it. To ease the change, output_buffer string list is replaced with a strbuf ;) * rework trace.c to call vsnprintf itself. It's used to format strerror()s and git command names, it should never be more than a few octets long, let it work on a 8k static buffer with vsnprintf or die loudly. Signed-off-by: Pierre Habouzit --- trace.c | 90 ++++++++++++++++++++--------------------------------------------- 1 file changed, 27 insertions(+), 63 deletions(-) (limited to 'trace.c') diff --git a/trace.c b/trace.c index 7961a27a2e..91548a56ec 100644 --- a/trace.c +++ b/trace.c @@ -25,33 +25,6 @@ #include "cache.h" #include "quote.h" -/* Stolen from "imap-send.c". */ -int nfvasprintf(char **strp, const char *fmt, va_list ap) -{ - int len; - char tmp[1024]; - - if ((len = vsnprintf(tmp, sizeof(tmp), fmt, ap)) < 0 || - !(*strp = xmalloc(len + 1))) - die("Fatal: Out of memory\n"); - if (len >= (int)sizeof(tmp)) - vsprintf(*strp, fmt, ap); - else - memcpy(*strp, tmp, len + 1); - return len; -} - -int nfasprintf(char **str, const char *fmt, ...) -{ - int rc; - va_list args; - - va_start(args, fmt); - rc = nfvasprintf(str, fmt, args); - va_end(args); - return rc; -} - /* Get a trace file descriptor from GIT_TRACE env variable. */ static int get_trace_fd(int *need_close) { @@ -89,63 +62,54 @@ static int get_trace_fd(int *need_close) static const char err_msg[] = "Could not trace into fd given by " "GIT_TRACE environment variable"; -void trace_printf(const char *format, ...) +void trace_printf(const char *fmt, ...) { - char *trace_str; - va_list rest; - int need_close = 0; - int fd = get_trace_fd(&need_close); + char buf[8192]; + va_list ap; + int fd, len, need_close = 0; + fd = get_trace_fd(&need_close); if (!fd) return; - va_start(rest, format); - nfvasprintf(&trace_str, format, rest); - va_end(rest); - - write_or_whine_pipe(fd, trace_str, strlen(trace_str), err_msg); - - free(trace_str); + va_start(ap, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (len >= sizeof(buf)) + die("unreasonnable trace length"); + write_or_whine_pipe(fd, buf, len, err_msg); if (need_close) close(fd); } -void trace_argv_printf(const char **argv, int count, const char *format, ...) +void trace_argv_printf(const char **argv, int count, const char *fmt, ...) { - char *argv_str, *format_str, *trace_str; - size_t argv_len, format_len, trace_len; - va_list rest; - int need_close = 0; - int fd = get_trace_fd(&need_close); + char buf[8192]; + va_list ap; + char *argv_str; + size_t argv_len; + int fd, len, need_close = 0; + fd = get_trace_fd(&need_close); if (!fd) return; + va_start(ap, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (len >= sizeof(buf)) + die("unreasonnable trace length"); + /* Get the argv string. */ argv_str = sq_quote_argv(argv, count); argv_len = strlen(argv_str); - /* Get the formated string. */ - va_start(rest, format); - nfvasprintf(&format_str, format, rest); - va_end(rest); - - /* Allocate buffer for trace string. */ - format_len = strlen(format_str); - trace_len = argv_len + format_len + 1; /* + 1 for \n */ - trace_str = xmalloc(trace_len + 1); - - /* Copy everything into the trace string. */ - strncpy(trace_str, format_str, format_len); - strncpy(trace_str + format_len, argv_str, argv_len); - strcpy(trace_str + trace_len - 1, "\n"); - - write_or_whine_pipe(fd, trace_str, trace_len, err_msg); + write_or_whine_pipe(fd, buf, len, err_msg); + write_or_whine_pipe(fd, argv_str, argv_len, err_msg); + write_or_whine_pipe(fd, "\n", 1, err_msg); free(argv_str); - free(format_str); - free(trace_str); if (need_close) close(fd); -- cgit v1.2.1 From 7a33bcbe802080f3a926e93d66b65ff7c5e8c5ed Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 20 Sep 2007 00:42:13 +0200 Subject: sq_quote_argv and add_to_string rework with strbuf's. * sq_quote_buf is made public, and works on a strbuf. * sq_quote_argv also works on a strbuf. * make sq_quote_argv take a "maxlen" argument to check the buffer won't grow too big. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- trace.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'trace.c') diff --git a/trace.c b/trace.c index 91548a56ec..69fa05e644 100644 --- a/trace.c +++ b/trace.c @@ -64,7 +64,7 @@ static const char err_msg[] = "Could not trace into fd given by " void trace_printf(const char *fmt, ...) { - char buf[8192]; + struct strbuf buf; va_list ap; int fd, len, need_close = 0; @@ -72,12 +72,22 @@ void trace_printf(const char *fmt, ...) if (!fd) return; + strbuf_init(&buf, 0); va_start(ap, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, ap); + len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); va_end(ap); - if (len >= sizeof(buf)) - die("unreasonnable trace length"); - write_or_whine_pipe(fd, buf, len, err_msg); + if (len >= strbuf_avail(&buf)) { + strbuf_grow(&buf, len - strbuf_avail(&buf) + 128); + va_start(ap, fmt); + len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); + va_end(ap); + if (len >= strbuf_avail(&buf)) + die("broken vsnprintf"); + } + strbuf_setlen(&buf, len); + + write_or_whine_pipe(fd, buf.buf, buf.len, err_msg); + strbuf_release(&buf); if (need_close) close(fd); @@ -85,31 +95,32 @@ void trace_printf(const char *fmt, ...) void trace_argv_printf(const char **argv, int count, const char *fmt, ...) { - char buf[8192]; + struct strbuf buf; va_list ap; - char *argv_str; - size_t argv_len; int fd, len, need_close = 0; fd = get_trace_fd(&need_close); if (!fd) return; + strbuf_init(&buf, 0); va_start(ap, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, ap); + len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); va_end(ap); - if (len >= sizeof(buf)) - die("unreasonnable trace length"); - - /* Get the argv string. */ - argv_str = sq_quote_argv(argv, count); - argv_len = strlen(argv_str); - - write_or_whine_pipe(fd, buf, len, err_msg); - write_or_whine_pipe(fd, argv_str, argv_len, err_msg); - write_or_whine_pipe(fd, "\n", 1, err_msg); + if (len >= strbuf_avail(&buf)) { + strbuf_grow(&buf, len - strbuf_avail(&buf) + 128); + va_start(ap, fmt); + len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap); + va_end(ap); + if (len >= strbuf_avail(&buf)) + die("broken vsnprintf"); + } + strbuf_setlen(&buf, len); - free(argv_str); + sq_quote_argv(&buf, argv, count, 0); + strbuf_addch(&buf, '\n'); + write_or_whine_pipe(fd, buf.buf, buf.len, err_msg); + strbuf_release(&buf); if (need_close) close(fd); -- cgit v1.2.1