Browse code

Better handling of RFC822 comments

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

Nigel Horne authored on 2004/09/17 18:11:06
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Sep 17 10:10:13 BST 2004 (njh)
2
+----------------------------------
3
+  * libclamav/mbox.c:	Improved handling of RFC822 comments in headers
4
+
1 5
 Thu Sep 16 21:14:08 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * sigtool: add support for new database names
... ...
@@ -17,6 +17,9 @@
17 17
  *
18 18
  * Change History:
19 19
  * $Log: mbox.c,v $
20
+ * Revision 1.128  2004/09/17 09:09:44  nigelhorne
21
+ * Better handling of RFC822 comments
22
+ *
20 23
  * Revision 1.127  2004/09/16 18:00:43  nigelhorne
21 24
  * Handle RFC2047
22 25
  *
... ...
@@ -369,7 +372,7 @@
369 369
  * Compilable under SCO; removed duplicate code with message.c
370 370
  *
371 371
  */
372
-static	char	const	rcsid[] = "$Id: mbox.c,v 1.127 2004/09/16 18:00:43 nigelhorne Exp $";
372
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.128 2004/09/17 09:09:44 nigelhorne Exp $";
373 373
 
374 374
 #if HAVE_CONFIG_H
375 375
 #include "clamav-config.h"
... ...
@@ -484,6 +487,7 @@ static	bool	continuationMarker(const char *line);
484 484
 static	int	parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const char *arg);
485 485
 static	void	saveTextPart(message *m, const char *dir);
486 486
 static	char	*rfc2047(const char *in);
487
+static	char	*rfc822comments(const char *in);
487 488
 
488 489
 static	void	checkURLs(message *m, const char *dir);
489 490
 #ifdef	WITH_CURL
... ...
@@ -2079,65 +2083,11 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
2079 2079
 
2080 2080
 	cli_dbgmsg("parseMimeHeader: cmd='%s', arg='%s'\n", cmd, arg);
2081 2081
 
2082
-	if(strchr(cmd, '(')) {
2083
-		/*
2084
-		 * The command includes comments, see section 3.4.3 of RFC822
2085
-		 * Remove the comment from the command
2086
-		 */
2087
-		char *ccopy = strdup(cmd);
2088
-		char *cptr;
2089
-		int backslash, inquote, commentlevel;
2090
-		char *newcmd, *nptr;
2091
-
2092
-		if(ccopy == NULL)
2093
-			return -1;
2094
-
2095
-		newcmd = cli_malloc(strlen(cmd) + 1);
2096
-		if(newcmd == NULL) {
2097
-			free(ccopy);
2098
-			return -1;
2099
-		}
2100
-
2101
-		backslash = commentlevel = inquote = 0;
2102
-		nptr = newcmd;
2103
-
2104
-		cli_dbgmsg("parseMimeHeader: cmd contains a comment\n");
2105
-
2106
-		for(cptr = ccopy; *cptr; cptr++)
2107
-			if(backslash) {
2108
-				*nptr++ = *cptr;
2109
-				backslash = 0;
2110
-			} else switch(*cptr) {
2111
-				case '\\':
2112
-					backslash = 1;
2113
-					break;
2114
-				case '\"':
2115
-					inquote = !inquote;
2116
-					break;
2117
-				case '(':
2118
-					commentlevel++;
2119
-					break;
2120
-				case ')':
2121
-					if(commentlevel > 0)
2122
-						commentlevel--;
2123
-					break;
2124
-				default:
2125
-					if(commentlevel == 0)
2126
-						*nptr++ = *cptr;
2127
-			}
2128
-
2129
-		if(backslash)	/* last character was a single backslash */
2130
-			*nptr++ = '\\';
2131
-		*nptr = '\0';
2132
-
2133
-		free(ccopy);
2134
-		commandNumber = tableFind(rfc821Table, newcmd);
2135
-		free(newcmd);
2136
-	} else
2137
-		commandNumber = tableFind(rfc821Table, cmd);
2082
+	ptr = rfc822comments(cmd);
2083
+	commandNumber = tableFind(rfc821Table, ptr);
2084
+	free(ptr);
2138 2085
 
2139
-	copy = strdup(arg ? arg : "");
2140
-	strstrip(copy);
2086
+	copy = rfc822comments(arg);
2141 2087
 	ptr = copy;
2142 2088
 	if(copy == NULL)
2143 2089
 		return -1;
... ...
@@ -2262,6 +2212,66 @@ saveTextPart(message *m, const char *dir)
2262 2262
 	}
2263 2263
 }
2264 2264
 
2265
+/*
2266
+ * Handle RFC822 comments in headers. Returns a malloc'd buffer that the
2267
+ * caller must free, or NULL on error. See seciont 3.4.3 of RFC822
2268
+ * TODO: handle comments that go on to more than one line
2269
+ */
2270
+static char *
2271
+rfc822comments(const char *in)
2272
+{
2273
+	const char *iptr;
2274
+	char *out, *optr;
2275
+	int backslash, inquote, commentlevel;
2276
+
2277
+	if(in == NULL)
2278
+		in = "";
2279
+
2280
+	if(strchr(in, '(') == NULL)
2281
+		return strdup(in);
2282
+
2283
+	out = cli_malloc(strlen(in) + 1);
2284
+	if(out == NULL)
2285
+		return NULL;
2286
+
2287
+	backslash = commentlevel = inquote = 0;
2288
+	optr = out;
2289
+
2290
+	cli_dbgmsg("rfc822comments: contains a comment\n");
2291
+
2292
+	for(iptr = in; *iptr; iptr++)
2293
+		if(backslash) {
2294
+			*optr++ = *iptr;
2295
+			backslash = 0;
2296
+		} else switch(*iptr) {
2297
+			case '\\':
2298
+				backslash = 1;
2299
+				break;
2300
+			case '\"':
2301
+				inquote = !inquote;
2302
+				break;
2303
+			case '(':
2304
+				commentlevel++;
2305
+				break;
2306
+			case ')':
2307
+				if(commentlevel > 0)
2308
+					commentlevel--;
2309
+				break;
2310
+			default:
2311
+				if(commentlevel == 0)
2312
+					*optr++ = *iptr;
2313
+		}
2314
+
2315
+	if(backslash)	/* last character was a single backslash */
2316
+		*optr++ = '\\';
2317
+	*optr = '\0';
2318
+
2319
+	strstrip(out);
2320
+
2321
+	cli_dbgmsg("rfc822comments '%s'=>'%s'\n", in, out);
2322
+
2323
+	return out;
2324
+}
2265 2325
 
2266 2326
 /*
2267 2327
  * Handle RFC2047 encoding. Returns a malloc'd buffer that the caller must