diff options
author | Johannes Schindelin <Johannes.Schindelin@gmx.de> | 2008-05-16 14:03:30 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-05-25 13:21:40 -0700 |
commit | cce8d6fdb4d7170a73763586daf6ac4f6b8fce2c (patch) | |
tree | 636ecb4162561aa5bdfa5a86128fa941fc1ea617 /builtin-mailsplit.c | |
parent | 182fb4df9120257c2e6b041dd58eef3de5b530d2 (diff) | |
download | git-cce8d6fdb4d7170a73763586daf6ac4f6b8fce2c.tar.gz |
mailsplit and mailinfo: gracefully handle NUL characters
The function fgets() has a big problem with NUL characters: it reads
them, but nobody will know if the NUL comes from the file stream, or
was appended at the end of the line.
So implement a custom read_line_with_nul() function.
Noticed by Tommy Thorn.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-mailsplit.c')
-rw-r--r-- | builtin-mailsplit.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c index 46b27cdaea..e4d977bafb 100644 --- a/builtin-mailsplit.c +++ b/builtin-mailsplit.c @@ -45,6 +45,25 @@ static int is_from_line(const char *line, int len) /* Could be as small as 64, enough to hold a Unix "From " line. */ static char buf[4096]; +/* We cannot use fgets() because our lines can contain NULs */ +int read_line_with_nul(char *buf, int size, FILE *in) +{ + int len = 0, c; + + for (;;) { + c = getc(in); + buf[len++] = c; + if (c == EOF || c == '\n' || len + 1 >= size) + break; + } + + if (c == EOF) + len--; + buf[len] = '\0'; + + return len; +} + /* Called with the first line (potentially partial) * already in buf[] -- normally that should begin with * the Unix "From " line. Write it into the specified @@ -70,19 +89,19 @@ static int split_one(FILE *mbox, const char *name, int allow_bare) * "From " and having something that looks like a date format. */ for (;;) { - int is_partial = (buf[len-1] != '\n'); + int is_partial = len && buf[len-1] != '\n'; - if (fputs(buf, output) == EOF) + if (fwrite(buf, 1, len, output) != len) die("cannot write output"); - if (fgets(buf, sizeof(buf), mbox) == NULL) { + len = read_line_with_nul(buf, sizeof(buf), mbox); + if (len == 0) { if (feof(mbox)) { status = 1; break; } die("cannot read mbox"); } - len = strlen(buf); if (!is_partial && !is_bare && is_from_line(buf, len)) break; /* done with one message */ } |