el = strcspn(at, " \n\t\r\v\f>");
strbuf_reset(&email);
strbuf_add(&email, at, el);
- strbuf_remove(&f, at - f.buf, el + 1);
+ strbuf_remove(&f, at - f.buf, el + (at[el] ? 1 : 0));
/* The remainder is name. It could be "John Doe <john.doe@xz>"
* or "john.doe@xz (John Doe)", but we have removed the
* the () pair at the end.
*/
strbuf_trim(&f);
- if (f.buf[0] == '(')
- strbuf_remove(&name, 0, 1);
- if (f.len && f.buf[f.len - 1] == ')')
+ if (f.buf[0] == '(' && f.len && f.buf[f.len - 1] == ')') {
+ strbuf_remove(&f, 0, 1);
strbuf_setlen(&f, f.len - 1);
+ }
get_sane_name(&name, &f, &email);
strbuf_release(&f);
message_type = TYPE_OTHER;
if (slurp_attr(line->buf, "boundary=", boundary)) {
strbuf_insert(boundary, 0, "--", 2);
- if (content_top++ >= &content[MAX_BOUNDARIES]) {
+ if (++content_top > &content[MAX_BOUNDARIES]) {
fprintf(stderr, "Too many boundaries to handle\n");
exit(1);
}
static int is_multipart_boundary(const struct strbuf *line)
{
- return !strbuf_cmp(line, *content_top);
+ return (((*content_top)->len <= line->len) &&
+ !memcmp(line->buf, (*content_top)->buf, (*content_top)->len));
}
static void cleanup_subject(struct strbuf *subject)
continue;
case '[':
if ((pos = strchr(subject->buf, ']'))) {
- remove = pos - subject->buf + 1;
- /* Don't remove too much. */
- if (remove <= (subject->len - remove + 1) * 2) {
- strbuf_remove(subject, 0, remove);
+ remove = pos - subject->buf;
+ if (remove <= (subject->len - remove) * 2) {
+ strbuf_remove(subject, 0, remove + 1);
continue;
}
} else
c -= 'a' - 26;
else if ('0' <= c && c <= '9')
c -= '0' - 52;
- else if (c == '=') {
- /* padding is almost like (c == 0), except we do
- * not output NUL resulting only from it;
- * for now we just trust the data.
- */
- c = 0;
- }
else
continue; /* garbage */
switch (pos++) {
rfc2047 = 1;
if (in != ep) {
- strbuf_add(&outbuf, in, ep - in);
+ /*
+ * We are about to process an encoded-word
+ * that begins at ep, but there is something
+ * before the encoded word.
+ */
+ char *scan;
+ for (scan = in; scan < ep; scan++)
+ if (!isspace(*scan))
+ break;
+
+ if (scan != ep || in == it->buf) {
+ /*
+ * We should not lose that "something",
+ * unless we have just processed an
+ * encoded-word, and there is only LWS
+ * before the one we are about to process.
+ */
+ strbuf_add(&outbuf, in, ep - in);
+ }
in = ep;
}
/* E.g.
static int find_boundary(void)
{
while (!strbuf_getline(&line, fin, '\n')) {
- if (is_multipart_boundary(&line))
+ if (*content_top && is_multipart_boundary(&line))
return 1;
}
return 0;
/* technically won't happen as is_multipart_boundary()
will fail first. But just in case..
*/
- if (content_top-- < content) {
+ if (--content_top < content) {
fprintf(stderr, "Detected mismatched boundaries, "
"can't recover\n");
exit(1);
check_header(&line, p_hdr_data, 0);
strbuf_release(&newline);
- /* eat the blank line after section info */
- return (strbuf_getline(&line, fin, '\n') == 0);
+ /* replenish line */
+ if (strbuf_getline(&line, fin, '\n'))
+ return 0;
+ strbuf_addch(&line, '\n');
+ return 1;
}
static inline int patchbreak(const struct strbuf *line)
/* process any boundary lines */
if (*content_top && is_multipart_boundary(&line)) {
/* flush any leftover */
- if (line.len)
- handle_filter(&line);
-
+ if (prev.len) {
+ handle_filter(&prev);
+ strbuf_reset(&prev);
+ }
if (!handle_boundary())
goto handle_body_out;
}
}
output_header_lines(fout, "Subject", hdr);
} else if (!memcmp(header[i], "From", 4)) {
+ cleanup_space(hdr);
handle_from(hdr);
fprintf(fout, "Author: %s\n", name.buf);
fprintf(fout, "Email: %s\n", email.buf);
}
static const char mailinfo_usage[] =
- "git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
+ "git mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";
int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{