mailinfo: apply the same fix not to lose NULs in BASE64 and QP codepaths
authorJunio C Hamano <gitster@pobox.com>
Sun, 25 May 2008 08:16:05 +0000 (01:16 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 25 May 2008 20:22:18 +0000 (13:22 -0700)
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-mailinfo.c
t/t5100-mailinfo.sh
t/t5100/nul-b64.expect [new file with mode: 0644]
t/t5100/nul-b64.in [new file with mode: 0644]

index f0c420976f0f41ea0402a2c20f3f443dd0781b83..e1e094f29ef3e7f7af3b0a20047b67a70c8c3e18 100644 (file)
@@ -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;
                }
index 5a4610b8607cc47bc813291ecb7a16085f7f5393..a8b78ebf7d021cb626d4452545b5f4d1e0efe34f 100755 (executable)
@@ -34,4 +34,13 @@ test_expect_success 'respect NULs' '
 
 '
 
+test_expect_success 'Preserve NULs out of MIME encoded message' '
+
+       git mailsplit -d5 -o. ../t5100/nul-b64.in &&
+       cmp ../t5100/nul-b64.in 00001 &&
+       git mailinfo msg patch <00001 &&
+       cmp ../t5100/nul-b64.expect patch
+
+'
+
 test_done
diff --git a/t/t5100/nul-b64.expect b/t/t5100/nul-b64.expect
new file mode 100644 (file)
index 0000000..d7d680f
Binary files /dev/null and b/t/t5100/nul-b64.expect differ
diff --git a/t/t5100/nul-b64.in b/t/t5100/nul-b64.in
new file mode 100644 (file)
index 0000000..16540d9
--- /dev/null
@@ -0,0 +1,37 @@
+From 667d8940e719cddee1cfe237cbbe215e20270b09 Mon Sep 17 00:00:00 2001
+From: Junio C Hamano <gitster@pobox.com>
+Date: Sun, 25 May 2008 00:38:18 -0700
+Subject: [PATCH] second
+Content-Transfer-Encoding: base64
+
+LS0tCiBmaWxlIHwgIEJpbiAxMzU3IC0+IDEzNTcgYnl0ZXMKIDEgZmlsZXMgY2hhbmdlZCwg
+MCBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2ZpbGUgYi9m
+aWxlCmluZGV4IDc3MzYxZDguLjllMDJiZTYgMTAwNjQ0Ci0tLSBhL2ZpbGUKKysrIGIvZmls
+ZQpAQCAtMSwxMiArMSwxMiBAQAogTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl
+Y3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIFN1c3BlbmRpc3NlCiBzaXQgYW1ldCB0dXJwaXMg
+ZWdldCBlc3QgY3Vyc3VzIGxhb3JlZXQuIEFsaXF1YW0gbWF1cmlzLiBQcmFlc2VudAotdm9s
+dXRwYXQuIFByb2luIGluIHB1cnVzLiBOdWxsYSB1cm5hIHNhcGllbiwgZGFwaWJ1cyBzaXQg
+YW1ldCwKK3ZvbHV0cGF0LiBQcm9pbiBpbiBwdXJ1cy4gTnVsbGEgdXJuYSBzYXBpZW4sIGRh
+cGkAdXMgc2l0IGFtZXQsCiBoZW5kcmVyaXQgbmVjLCB0ZW1wdXMgZXUsIG1pLiBVdCBwb3J0
+YSwgbGVvIGlkIHRpbmNpZHVudCB1bGxhbWNvcnBlciwKLXZlbGl0IGZlbGlzIHRyaXN0aXF1
+ZSBhbnRlLCBhdCBsb2JvcnRpcyBkaWFtIHBlZGUgdXQgZHVpLiBQcm9pbiBhYwordmVsaXQg
+ZmVsaXMgdHJpc3RpcXVlIGFudGUsIGF0IGxvAG9ydGlzIGRpYW0gcGVkZSB1dCBkdWkuIFBy
+b2luIGFjCiBsZWN0dXMuIERvbmVjIGF0IG1hc3NhIGFjIGlwc3VtIGhlbmRyZXJpdCBzb2xs
+aWNpdHVkaW4uIE5hbSBkaWN0dW0KIG5pc2kgc2VkIG1pLiBEdWlzIHNlZCBhbnRlLiBVdCB2
+aXRhZSBlc3QgdXQgZHVpIHVsdHJpY2llcyBkaWduaXNzaW0uCiAKLUluIHZlbCBvZGlvIGVn
+ZXQgbmlzbCBjb252YWxsaXMgdm9sdXRwYXQuIE1vcmJpIHZpdGFlIG5pYmguIE51bGxhbQor
+SW4gdmVsIG9kaW8gZWdldCBuaXNsIGNvbnZhbGxpcyB2b2x1dHBhdC4gTW9yAGkgdml0YWUg
+bmkAaC4gTnVsbGFtCiBhY2N1bXNhbiwgZG9sb3IgcXVpcyBhbGlxdWFtIHNjZWxlcmlzcXVl
+LCBlbGl0IGVuaW0gY29uZGltZW50dW0KIG1hdXJpcywgbm9uIHRyaXN0aXF1ZSBtYXVyaXMg
+dHVycGlzIGV0IG1hdXJpcy4gVXQgbm9uIG5pc2wuIE5hbSBkaWFtCiBtaSwgc2VtcGVyIHBv
+c3VlcmUsIGVsZWlmZW5kIHV0LCBhdWN0b3IgdmVsLCBlcmF0LiBTZWQgcG9zdWVyZQpAQCAt
+MTYsNyArMTYsNyBAQCBzZWQgZXN0LiBFdGlhbSBkaWFtIGZlbGlzLCBmZXJtZW50dW0gZWdl
+dCwgYWRpcGlzY2luZyBhdCwgcG9zdWVyZSBpbiwKIGR1aS4gRXRpYW0gbHVjdHVzLgogCiBO
+dWxsYSBpZCBhdWd1ZS4gTmFtIGlhY3VsaXMgYWNjdW1zYW4gbmlzaS4gU3VzcGVuZGlzc2Ug
+cG90ZW50aS4gTnVuYwotdmFyaXVzIGF1Z3VlIG5lYyBvcmNpLiBVdCBjb25kaW1lbnR1bSBk
+b2xvciBzYWdpdHRpcyBuaWJoLiBTdXNwZW5kaXNzZQordmFyaXVzIGF1Z3VlIG5lYyBvcmNp
+LiBVdCBjb25kaW1lbnR1bSBkb2xvciBzYWdpdHRpcyBuaQBoLiBTdXNwZW5kaXNzZQogdGVt
+cG9yIGxlY3R1cyBzZWQgbWFnbmEuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE51bGxhbSB0ZW1w
+b3IgaXBzdW0uIFNlZAogbW9sZXN0aWUgdGVsbHVzLiBQaGFzZWxsdXMgbGlndWxhLiBJbiB2
+ZWhpY3VsYSB1bHRyaWNlcwogbmlzaS4gU3VzcGVuZGlzc2UgZmVsaXMgYXVndWUsIHBlbGxl
+bnRlc3F1ZSBhdCwgZGljdHVtIHZpdmVycmEsCi0tIAoxLjUuNS4xLjU0MC5nNTc3ODAKCg==