]> code.citadel.org Git - citadel.git/blobdiff - citadel/mime_parser.c
* tell what we did to the debs
[citadel.git] / citadel / mime_parser.c
index d43690685e3175aadd7eb5c41b8184c8f33ab8e3..c6415f34bb7c2d658ad6befa7c626f11ff2c722d 100644 (file)
@@ -3,8 +3,8 @@
  *
  * This is the MIME parser for Citadel.
  *
- * Copyright (c) 1998-2005 by Art Cancro
- * This code is distributed under the terms of the GNU General Public License.
+ * Copyright (c) 1998-2006 by Art Cancro
+ * This code is distributed under the GNU General Public License v2.
  *
  */
 
@@ -62,68 +62,50 @@ char *fixed_partnum(char *supplied_partnum) {
 
 /*
  * Convert "quoted-printable" to binary.  Returns number of bytes decoded.
+ * according to RFC2045 section 6.7
  */
 int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen) {
-       char buf[SIZ];
-       int buf_length = 0;
-       int soft_line_break = 0;
        unsigned int ch;
-       int decoded_length = 0;
-       int i;
+       int destpos = 1;
+       int sourcepos = 1;
+       int ignore_last = 0;
+       char *check;
 
        decoded[0] = 0;
-       decoded_length = 0;
-       buf[0] = 0;
-       buf_length = 0;
-
-       for (i = 0; i < sourcelen; ++i) {
-
-               buf[buf_length++] = encoded[i];
-
-               if ( (encoded[i] == '\n')
-                  || (encoded[i] == 0)
-                  || (i == (sourcelen-1)) ) {
-                       buf[buf_length++] = 0;
-
-                       /*** begin -- process one line ***/
-
-                       if (buf[strlen(buf)-1] == '\n') {
-                               buf[strlen(buf)-1] = 0;
+       if (sourcelen >0)
+               decoded[0] = encoded[0];
+       while (sourcepos <= sourcelen){
+               check = &decoded[destpos];
+               decoded[destpos] = encoded[sourcepos];
+               if ((ignore_last == 0) && (decoded[destpos-1] == '='))
+               {
+                       if ((*check == '\0') || 
+                           (*check == '\n') ||  
+                           (*check == '\r'))
+                       {
+                               decoded[destpos - 1] = '\0';
+                               destpos-=2;
                        }
-                       if (buf[strlen(buf)-1] == '\r') {
-                               buf[strlen(buf)-1] = 0;
+                       else if (sourcelen - sourcepos > 2)
+                       {
+                               sscanf(&encoded[sourcepos], "%02x", &ch);
+                               decoded[destpos - 1] = ch;
+                               sourcepos++;
+                               destpos --;
+                               ignore_last = 1;
                        }
-                       while (isspace(buf[strlen(buf)-1])) {
-                               buf[strlen(buf)-1] = 0;
-                       }
-                       soft_line_break = 0;
-
-                       while (strlen(buf) > 0) {
-                               if (!strcmp(buf, "=")) {
-                                       soft_line_break = 1;
-                                       strcpy(buf, "");
-                               } else if ((strlen(buf)>=3) && (buf[0]=='=')) {
-                                       sscanf(&buf[1], "%02x", &ch);
-                                       decoded[decoded_length++] = ch;
-                                       strcpy(buf, &buf[3]);
-                               } else {
-                                       decoded[decoded_length++] = buf[0];
-                                       strcpy(buf, &buf[1]);
-                               }
-                       }
-                       if (soft_line_break == 0) {
-                               decoded[decoded_length++] = '\r';
-                               decoded[decoded_length++] = '\n';
-                       }
-                       buf_length = 0;
-                       /*** end -- process one line ***/
                }
+               else 
+                       ignore_last = 0;
+               destpos ++;
+               sourcepos ++;
        }
 
-       decoded[decoded_length++] = 0;
-       return(decoded_length);
+       decoded[destpos] = 0;
+       return(destpos - 1);
 }
 
+
 /*
  * Given a message or message-part body and a length, handle any necessary
  * decoding and pass the request up the stack.
@@ -192,17 +174,19 @@ void mime_decode(char *partnum,
                return;
        }
        
+       /* Fail silently if we hit an unknown encoding. */
        if ((strcasecmp(encoding, "base64"))
            && (strcasecmp(encoding, "quoted-printable"))) {
                return;
        }
+
        /*
-        * Allocate a buffer for the decoded data.  The output buffer is the
-        * same size as the input buffer; this assumes that the decoded data
-        * will never be larger than the encoded data.  This is a safe
-        * assumption with base64, uuencode, and quoted-printable.
+        * Allocate a buffer for the decoded data.  The output buffer is slightly
+        * larger than the input buffer; this assumes that the decoded data
+        * will never be significantly larger than the encoded data.  This is a
+        * safe assumption with base64, uuencode, and quoted-printable.
         */
-       decoded = malloc(length+2048);
+       decoded = malloc(length + 32768);
        if (decoded == NULL) {
                return;
        }
@@ -211,8 +195,7 @@ void mime_decode(char *partnum,
                bytes_decoded = CtdlDecodeBase64(decoded, part_start, length);
        }
        else if (!strcasecmp(encoding, "quoted-printable")) {
-               bytes_decoded = CtdlDecodeQuotedPrintable(decoded,
-                                                       part_start, length);
+               bytes_decoded = CtdlDecodeQuotedPrintable(decoded, part_start, length);
        }
 
        if (bytes_decoded > 0) if (CallBack != NULL) {
@@ -498,8 +481,8 @@ void the_mime_parser(char *partnum,
                        name = content_type_name;
                }
        
-               lprintf(CTDL_DEBUG, "mime_decode part=%s, len=%d, type=%s, charset=%s, encoding=%s\n",
-                       partnum, length, content_type, charset, encoding);
+               /* lprintf(CTDL_DEBUG, "mime_decode part=%s, len=%d, type=%s, charset=%s, encoding=%s\n",
+                       partnum, length, content_type, charset, encoding); */
 
                /* Ok, we've got a non-multipart part here, so do something with it.
                 */