log_write_email_headers: use strbufs

When we write a MIME attachment, we write the mime headers
into fixed-size buffers. These are likely to be big enough
in practice, but technically the input could be arbitrarily
large (e.g., if the caller provided a lot of content in the
extra_headers string), in which case we'd quietly truncate
it and generate bogus output. Let's convert these buffers to
strbufs.

The memory ownership here is a bit funny. The original fixed
buffers were static, and we merely pass out pointers to them
to be used by the caller (and in one case, we even just
stuff our value into the opt->diffopt.stat_sep value).
Ideally we'd actually pass back heap buffers, and the caller
would be responsible for freeing them.

This patch punts on that cleanup for now, and instead just
marks the strbufs as static. That means we keep ownership in
this function, making it not a complete leak. This also
takes us one step closer to fixing it in the long term
(since we can eventually use strbuf_detach() to hand
ownership to the caller, once it's ready).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2018-05-18 18:57:44 -07:00 коммит произвёл Junio C Hamano
Родитель 390c6cbc5e
Коммит d50b69b868
1 изменённых файлов: 10 добавлений и 6 удалений

Просмотреть файл

@ -386,11 +386,15 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
graph_show_oneline(opt->graph);
}
if (opt->mime_boundary) {
static char subject_buffer[1024];
static char buffer[1024];
static struct strbuf subject_buffer = STRBUF_INIT;
static struct strbuf buffer = STRBUF_INIT;
struct strbuf filename = STRBUF_INIT;
*need_8bit_cte_p = -1; /* NEVER */
snprintf(subject_buffer, sizeof(subject_buffer) - 1,
strbuf_reset(&subject_buffer);
strbuf_reset(&buffer);
strbuf_addf(&subject_buffer,
"%s"
"MIME-Version: 1.0\n"
"Content-Type: multipart/mixed;"
@ -405,13 +409,13 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
extra_headers ? extra_headers : "",
mime_boundary_leader, opt->mime_boundary,
mime_boundary_leader, opt->mime_boundary);
extra_headers = subject_buffer;
extra_headers = subject_buffer.buf;
if (opt->numbered_files)
strbuf_addf(&filename, "%d", opt->nr);
else
fmt_output_commit(&filename, commit, opt);
snprintf(buffer, sizeof(buffer) - 1,
strbuf_addf(&buffer,
"\n--%s%s\n"
"Content-Type: text/x-patch;"
" name=\"%s\"\n"
@ -422,7 +426,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
filename.buf,
opt->no_inline ? "attachment" : "inline",
filename.buf);
opt->diffopt.stat_sep = buffer;
opt->diffopt.stat_sep = buffer.buf;
strbuf_release(&filename);
}
*extra_headers_p = extra_headers;