]> mj.ucw.cz Git - checkmail.git/blobdiff - charset.c
Fix rfc2047 decoding buffer overflow
[checkmail.git] / charset.c
index 921be697c528af615c7dffadf2c16548b34a55d6..d32a414eead4eacb54fafccc4822931d1b46f640 100644 (file)
--- a/charset.c
+++ b/charset.c
@@ -232,7 +232,8 @@ static const char *find_encoded_word (const char *s, const char **x)
       ;
     if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')
       continue;
-    for (q = q + 3; 0x20 < *q && *q < 0x7f && *q != '?'; q++)
+    /* non-strict check since many MUAs will not encode spaces and question marks */
+    for (q = q + 3; 0x20 <= *q && *q < 0x7f && (*q != '?' || q[1] != '='); q++)
       ;
     if (q[0] != '?' || q[1] != '=')
     {
@@ -362,7 +363,12 @@ static void rfc2047_decode (char **pd)
     }
 
     if (rfc2047_decode_word (d, p, dlen) < 0)
-      strcpy(d, p);
+    {
+      n = q - p;
+      if (n > dlen)
+       n = dlen;
+      memcpy (d, p, n);
+    }
     found_encoded = 1;
     s = q;
     n = strlen (d);
@@ -429,6 +435,16 @@ add_snippet(char **ppos, char *term, char *add)
   *pos = 0;
 }
 
+void
+add_snippet_raw(char **ppos, char *term, char *add)
+{
+  char *pos = *ppos;
+  while (pos < term && *add)
+    *pos++ = *add++;
+  *ppos = pos;
+  *pos = 0;
+}
+
 void
 add_subject_snippet(char **ppos, char *term, char *add)
 {
@@ -448,8 +464,8 @@ add_addr_snippet(char **ppos, char *term, char *add, int add_mbox, int add_perso
       add_subject_snippet(ppos, term, add);
       return;
     }
-  // debug("%s: pers=%s mbox=%s\n", add, addr->personal, addr->mailbox);
   rfc2047_decode(&addr->personal);
+  // debug("%s: pers=%s mbox=%s\n", add, addr->personal, addr->mailbox);
   if (!addr->mailbox || !addr->mailbox[0])
     add_mbox = 0;
   if (!addr->personal || !addr->personal[0])
@@ -468,13 +484,13 @@ add_addr_snippet(char **ppos, char *term, char *add, int add_mbox, int add_perso
       if (add_personal)
        add_snippet(ppos, term, addr->personal);
       if (add_mbox && add_personal)
-       add_snippet(ppos, term, " <");
+       add_snippet_raw(ppos, term, " <");
       if (add_mbox)
        add_snippet(ppos, term, addr->mailbox);
       if (add_mbox && add_personal)
-       add_snippet(ppos, term, ">");
+       add_snippet_raw(ppos, term, ">");
     }
   else
-    add_snippet(ppos, term, "???");
+    add_snippet_raw(ppos, term, "???");
   rfc822_free_address(&addr);
 }