diff options
Diffstat (limited to 'builtin-mailinfo.c')
-rw-r--r-- | builtin-mailinfo.c | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index f0c420976f..e1e094f29e 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -434,6 +434,7 @@ static int read_one_header_line(char *line, int sz, FILE *in) static int decode_q_segment(char *in, char *ot, unsigned otsize, char *ep, int rfc2047) { + char *otbegin = ot; char *otend = ot + otsize; int c; while ((c = *in++) != 0 && (in <= ep)) { @@ -453,13 +454,14 @@ static int decode_q_segment(char *in, char *ot, unsigned otsize, char *ep, int r *ot++ = c; } *ot = 0; - return 0; + return (ot - otbegin); } static int decode_b_segment(char *in, char *ot, unsigned otsize, char *ep) { /* Decode in..ep, possibly in-place to ot */ int c, pos = 0, acc = 0; + char *otbegin = ot; char *otend = ot + otsize; while ((c = *in++) != 0 && (in <= ep)) { @@ -505,7 +507,7 @@ static int decode_b_segment(char *in, char *ot, unsigned otsize, char *ep) } } *ot = 0; - return 0; + return (ot - otbegin); } /* @@ -623,21 +625,20 @@ static void decode_header(char *it, unsigned itsize) convert_to_utf8(it, itsize, ""); } -static void decode_transfer_encoding(char *line, unsigned linesize) +static int decode_transfer_encoding(char *line, unsigned linesize, int inputlen) { char *ep; switch (transfer_encoding) { case TE_QP: - ep = line + strlen(line); - decode_q_segment(line, line, linesize, ep, 0); - break; + ep = line + inputlen; + return decode_q_segment(line, line, linesize, ep, 0); case TE_BASE64: - ep = line + strlen(line); - decode_b_segment(line, line, linesize, ep); - break; + ep = line + inputlen; + return decode_b_segment(line, line, linesize, ep); case TE_DONTCARE: - break; + default: + return inputlen; } } @@ -806,17 +807,19 @@ static void handle_body(void) /* process any boundary lines */ if (content_top->boundary && is_multipart_boundary(line)) { /* flush any leftover */ - if ((transfer_encoding == TE_BASE64) && - (np != newline)) { + if (np != newline) handle_filter(newline, sizeof(newline), - strlen(newline)); - } + np - newline); if (!handle_boundary()) return; } /* Unwrap transfer encoding */ - decode_transfer_encoding(line, sizeof(line)); + len = decode_transfer_encoding(line, sizeof(line), len); + if (len < 0) { + error("Malformed input line"); + return; + } switch (transfer_encoding) { case TE_BASE64: @@ -830,13 +833,13 @@ static void handle_body(void) break; } - /* this is a decoded line that may contain + /* + * This is a decoded line that may contain * multiple new lines. Pass only one chunk * at a time to handle_filter() */ - do { - while (*op != '\n' && *op != 0) + while (op < line + len && *op != '\n') *np++ = *op++; *np = *op; if (*np != 0) { @@ -846,9 +849,10 @@ static void handle_body(void) rc = handle_filter(newline, sizeof(newline), np - newline); np = newline; } - } while (*op != 0); - /* the partial chunk is saved in newline and - * will be appended by the next iteration of fgets + } while (op < line + len); + /* + * The partial chunk is saved in newline and will be + * appended by the next iteration of read_line_with_nul(). */ break; } |