Browse code

Decode text/plain parts marked as being encoded

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1151 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2004/12/01 22:16:08
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Wed Dec  1 13:14:33 GMT 2004 (njh)
2
+----------------------------------
3
+  * libclamav/mbox.c:	Decode text/plain parts marked as being encoded,
4
+		reported by Trog
5
+
1 6
 Wed Dec  1 12:14:46 GMT 2004 (njh)
2 7
 ----------------------------------
3 8
   * libeclamav/message.c:	Part of rule 3 of paragraph 5.1 of RFC1521 was
... ...
@@ -17,6 +17,9 @@
17 17
  *
18 18
  * Change History:
19 19
  * $Log: mbox.c,v $
20
+ * Revision 1.196  2004/12/01 13:12:35  nigelhorne
21
+ * Decode text/plain parts marked as being encoded
22
+ *
20 23
  * Revision 1.195  2004/11/29 13:21:20  nigelhorne
21 24
  * Remove the old continuation marker method
22 25
  *
... ...
@@ -573,7 +576,7 @@
573 573
  * Compilable under SCO; removed duplicate code with message.c
574 574
  *
575 575
  */
576
-static	char	const	rcsid[] = "$Id: mbox.c,v 1.195 2004/11/29 13:21:20 nigelhorne Exp $";
576
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.196 2004/12/01 13:12:35 nigelhorne Exp $";
577 577
 
578 578
 #if HAVE_CONFIG_H
579 579
 #include "clamav-config.h"
... ...
@@ -967,8 +970,6 @@ cli_mbox(const char *dir, int desc, unsigned int options)
967 967
 
968 968
 		cli_dbgmsg("Deal with email number %d\n", messagenumber);
969 969
 	} else {
970
-		int inHeader = 1;
971
-
972 970
 		/*
973 971
 		 * It's a single message, parse the headers then the body
974 972
 		 * Ignore blank lines at the start of the message
... ...
@@ -1019,8 +1020,6 @@ cli_mbox(const char *dir, int desc, unsigned int options)
1019 1019
 			 */
1020 1020
 			if(messageAddStr(m, ptr) < 0)
1021 1021
 				break;
1022
-			if(*ptr == '\0')
1023
-				inHeader = 0;
1024 1022
 		} while(fgets(buffer, sizeof(buffer) - 1, fd) != NULL);
1025 1023
 	}
1026 1024
 
... ...
@@ -1378,6 +1377,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
1378 1378
 				checkURLs(mainMessage, dir);
1379 1379
 			break;
1380 1380
 		case MULTIPART:
1381
+			cli_dbgmsg("Content-type 'multipart' handler\n");
1381 1382
 			boundary = messageFindArgument(mainMessage, "boundary");
1382 1383
 
1383 1384
 			if(boundary == NULL) {
... ...
@@ -1568,7 +1568,10 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
1568 1568
 						inMimeHead = continuationMarker(line);
1569 1569
 						messageAddArgument(aMessage, line);
1570 1570
 					} else if(inhead) {	/* handling normal headers */
1571
-						char *ptr;
1571
+						int quotes;
1572
+						char *fullline, *ptr;
1573
+						const char *qptr;
1574
+						const text *next;
1572 1575
 
1573 1576
 						if(line == NULL) {
1574 1577
 							/* empty line */
... ...
@@ -1603,73 +1606,55 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
1603 1603
 							continue;
1604 1604
 						}
1605 1605
 
1606
-						/*
1607
-						 * Some clients are broken and
1608
-						 * put white space after the ;
1609
-						 */
1610
-						inMimeHead = continuationMarker(line);
1611
-						if(!inMimeHead) {
1612
-							const text *next = t_line->t_next;
1613
-							char *fullline;
1614
-							int quotes = 0;
1615
-							const char *qptr;
1616
-
1617
-							assert(strlen(line) <= LINE_LENGTH);
1618
-
1619
-							fullline = rfc822comments(line);
1620
-							if(fullline == NULL)
1621
-								fullline = strdup(line);
1622
-
1623
-							for(qptr = fullline; *qptr; qptr++)
1624
-								if(*qptr == '\"')
1625
-									quotes++;
1626
-
1627
-							/*
1628
-							 * Fold next lines to the end of this
1629
-							 * if they start with a white space
1630
-							 * or if this line has an odd number of quotes:
1631
-							 * Content-Type: application/octet-stream; name="foo
1632
-							 * "
1633
-							 */
1634
-							while(next && next->t_line) {
1635
-								const char *data = lineGetData(next->t_line);
1606
+						inMimeHead = FALSE;
1636 1607
 
1637
-								if((!isspace(data[0])) &&
1638
-								   ((quotes & 1) == 0))
1639
-									break;
1608
+						assert(strlen(line) <= LINE_LENGTH);
1640 1609
 
1641
-								ptr = cli_realloc(fullline,
1642
-									strlen(fullline) + strlen(data) + 1);
1610
+						fullline = rfc822comments(line);
1611
+						if(fullline == NULL)
1612
+							fullline = strdup(line);
1643 1613
 
1644
-								if(ptr == NULL)
1645
-									break;
1614
+						quotes = 0;
1615
+						for(qptr = fullline; *qptr; qptr++)
1616
+							if(*qptr == '\"')
1617
+								quotes++;
1646 1618
 
1647
-								fullline = ptr;
1648
-								strcat(fullline, data);
1619
+						/*
1620
+						 * Fold next lines to the end of this
1621
+						 * if they start with a white space
1622
+						 * or if this line has an odd number of quotes:
1623
+						 * Content-Type: application/octet-stream; name="foo
1624
+						 * "
1625
+						 */
1626
+						next = t_line->t_next;
1627
+						while(next && next->t_line) {
1628
+							const char *data = lineGetData(next->t_line);
1649 1629
 
1650
-								for(qptr = data; *qptr; qptr++)
1651
-									if(*qptr == '\"')
1652
-										quotes++;
1630
+							if((!isspace(data[0])) &&
1631
+							   ((quotes & 1) == 0))
1632
+								break;
1653 1633
 
1654
-								t_line = next;
1655
-								next = next->t_next;
1656
-							}
1657
-							cli_dbgmsg("Multipart %d: About to parse folded header '%s'\n",
1658
-								multiparts, fullline);
1634
+							ptr = cli_realloc(fullline,
1635
+								strlen(fullline) + strlen(data) + 1);
1659 1636
 
1660
-							parseEmailHeader(aMessage, fullline, rfc821Table);
1661
-							free(fullline);
1662
-						} else {
1663
-							cli_dbgmsg("Multipart %d: About to parse header '%s'\n",
1664
-								multiparts, line);
1637
+							if(ptr == NULL)
1638
+								break;
1665 1639
 
1666
-							ptr = rfc822comments(line);
1640
+							fullline = ptr;
1641
+							strcat(fullline, data);
1667 1642
 
1668
-							parseEmailHeader(aMessage, (ptr) ? ptr : line, rfc821Table);
1643
+							for(qptr = data; *qptr; qptr++)
1644
+								if(*qptr == '\"')
1645
+									quotes++;
1669 1646
 
1670
-							if(ptr)
1671
-								free(ptr);
1647
+							t_line = next;
1648
+							next = next->t_next;
1672 1649
 						}
1650
+						cli_dbgmsg("Multipart %d: About to parse folded header '%s'\n",
1651
+							multiparts, fullline);
1652
+
1653
+						parseEmailHeader(aMessage, fullline, rfc821Table);
1654
+						free(fullline);
1673 1655
 					} else if(endOfMessage(line, boundary)) {
1674 1656
 						/*
1675 1657
 						 * Some viruses put information
... ...
@@ -1930,7 +1915,8 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
1930 1930
 								cli_dbgmsg("Found uuencoded message in multipart/mixed text portion\n");
1931 1931
 								messageSetEncoding(aMessage, "x-uuencode");
1932 1932
 								addAttachment = TRUE;
1933
-							} else if(tableFind(subtypeTable, cptr) == PLAIN) {
1933
+							} else if((tableFind(subtypeTable, cptr) == PLAIN) &&
1934
+								  (messageGetEncoding(aMessage) == NOENCODING)) {
1934 1935
 								char *filename;
1935 1936
 								/*
1936 1937
 								 * Strictly speaking
... ...
@@ -2108,7 +2094,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t
2108 2108
 
2109 2109
 			if(aText && (textIn == NULL)) {
2110 2110
 				if((fb = fileblobCreate()) != NULL) {
2111
-					cli_dbgmsg("Save non mime part\n");
2111
+					cli_dbgmsg("Save non mime and/or text/plain part\n");
2112 2112
 					fileblobSetFilename(fb, dir, "textpart");
2113 2113
 					/*fileblobAddData(fb, "Received: by clamd (textpart)\n", 30);*/
2114 2114
 
... ...
@@ -2600,11 +2586,41 @@ strstrip(char *s)
2600 2600
 }
2601 2601
 
2602 2602
 /*
2603
- * No longer used - TODO: remove it
2603
+ * Some broken email headers use ';' at the end of a line to continue
2604
+ * to the next line and don't add a leading white space on the next line
2604 2605
  */
2605 2606
 static bool
2606 2607
 continuationMarker(const char *line)
2607 2608
 {
2609
+	const char *ptr;
2610
+
2611
+	if(line == NULL)
2612
+		return FALSE;
2613
+
2614
+#ifdef	CL_DEBUG
2615
+	cli_dbgmsg("continuationMarker(%s)\n", line);
2616
+#endif
2617
+
2618
+	if(strlen(line) == 0)
2619
+		return FALSE;
2620
+
2621
+	ptr = strchr(line, '\0');
2622
+
2623
+	assert(ptr != NULL);
2624
+
2625
+	while(ptr > line)
2626
+		switch(*--ptr) {
2627
+			case '\n':
2628
+			case '\r':
2629
+			case ' ':
2630
+			case '\t':
2631
+				continue;
2632
+			case ';':
2633
+				return TRUE;
2634
+			default:
2635
+				return FALSE;
2636
+		}
2637
+
2608 2638
 	return FALSE;
2609 2639
 }
2610 2640