[evolution-patches] 70303, digitial signatures fail on some content




pretty broken canonicalisation filter, i think this fixes the cases i could find, without adding new ones.

now with regression test case.


Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/ChangeLog,v
retrieving revision 1.2414
diff -u -p -r1.2414 ChangeLog
--- camel/ChangeLog	31 Jan 2005 06:08:26 -0000	1.2414
+++ camel/ChangeLog	31 Jan 2005 10:59:50 -0000
@@ -1,5 +1,16 @@
 2005-01-31  Not Zed  <NotZed Ximian com>
 
+	** See bug #70303.
+
+	* tests/mime-filter/test1.c: added new test for
+	camel-mime-filter-canon.c
+
+	* camel-mime-filter-canon.c (filter_run): separated out from
+	filter.  Fix a case when it finds an embedded "From " not to
+	create "=46rom rom".
+	(complete): Properly canonicalise \n -> \r\n rather than just
+	copying it across (use filter_run now).
+
 	** See bug #68741.
 
 	* camel-vtrash-folder.h: move Junk and Trash into the ".#evolution"
Index: camel/camel-mime-filter-canon.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-mime-filter-canon.c,v
retrieving revision 1.5
diff -u -p -r1.5 camel-mime-filter-canon.c
--- camel/camel-mime-filter-canon.c	20 Jul 2004 03:28:05 -0000	1.5
+++ camel/camel-mime-filter-canon.c	31 Jan 2005 10:59:50 -0000
@@ -68,7 +68,7 @@ camel_mime_filter_canon_get_type (void)
 }
 
 static void
-filter(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
+filter_run(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace, int last)
 {
 	register unsigned char *inptr, c;
 	const unsigned char *inend, *start;
@@ -104,10 +104,13 @@ filter(CamelMimeFilter *f, char *in, siz
 			if (inptr < inend-4) {
 				if (strncmp(inptr, "rom ", 4) == 0) {
 					strcpy(o, "=46rom ");
+					inptr+=4;
 					o+= 7;
 				} else
 					*o++ = 'F';
-			} else
+			} else if (last)
+				*o++ = 'F';
+			else
 				break;
 		}
 
@@ -147,73 +150,27 @@ filter(CamelMimeFilter *f, char *in, siz
 	   otherwise we potentially backup a full line, which could be large */
 
 	/* we got to the end of the data without finding anything, backup to start and re-process next time around */
-	camel_mime_filter_backup(f, start, inend - start);
+	if (last) {
+		*outlen = o - f->outbuf;
+	} else {
+		camel_mime_filter_backup(f, start, inend - start);
+		*outlen = starto - f->outbuf;
+	}
 
 	*out = f->outbuf;
-	*outlen = starto - f->outbuf;
 	*outprespace = f->outpre;
 }
 
+static void
+filter(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
+{
+	filter_run(f, in, len, prespace, out, outlen, outprespace, FALSE);
+}
+
 static void 
 complete(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
 {
-	unsigned char *inptr, *inend;
-	char *o, *starto;
-	guint32 flags;
-
-	if (len)
-		filter(f, in, len, prespace, out, outlen, outprespace);
-
-	/* the data didn't contain an eol or was too short for "From ", we only need to check for "From" and add an eol */
-	if (f->backlen) {
-		inptr = (unsigned char *)f->backbuf;
-		inend = (unsigned char *)f->backbuf + f->backlen;
-		starto = o = *out + *outlen;
-		flags = ((CamelMimeFilterCanon *)f)->flags;
-
-		/* Check any embedded "From " */
-		if (f->backlen >= 5
-		    && (flags & CAMEL_MIME_FILTER_CANON_FROM)
-		    && strcmp(inptr, "From ") == 0) {
-			strcpy(o, "=46rom ");
-			o += 7;
-			inptr += 5;
-		}
-
-		/* copy the rest of it */
-		while (inptr < inend)
-			*o++ = *inptr++;
-		
-		/* check to strip trailing space */
-		if (flags & CAMEL_MIME_FILTER_CANON_STRIP) {
-			while (o>starto && (o[-1] == ' ' || o[-1] == '\t' || o[-1]=='\r'))
-				o--;
-		}
-		
-#if 0
-		/* Note: #if 0'd out because we do not want to add a
-		 * \r\n for PGP/MIME verification if it isn't there in
-		 * the original content stream */
-		
-		/* check end of line canonicalisation */
-		if (o>starto) {
-			if (flags & CAMEL_MIME_FILTER_CANON_CRLF) {
-				if (o[-1] != '\r')
-					*o++ = '\r';
-			} else {
-				if (o[-1] == '\r')
-					o--;
-			}
-		}
-		
-		/* and always finish with an eol */
-		*o++ = '\n';
-#endif
-		
-		*outlen = o - *out;
-		
-		f->backlen = 0;
-	}
+	filter_run(f, in, len, prespace, out, outlen, outprespace, TRUE);
 }
 
 static void
Index: camel/tests/mime-filter/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/tests/mime-filter/Makefile.am,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile.am
--- camel/tests/mime-filter/Makefile.am	13 Dec 2004 03:08:52 -0000	1.10
+++ camel/tests/mime-filter/Makefile.am	31 Jan 2005 10:59:50 -0000
@@ -24,11 +24,13 @@ EXTRA_DIST =				\
 	charset-gb2312.0.out
 
 check_PROGRAMS =  		\
+	test1			\
 	test-crlf		\
 	test-charset		\
 	test-tohtml
 
-TESTS = test-crlf test-charset test-tohtml
+TESTS = test1 \
+	test-crlf test-charset test-tohtml
 
 
 
Index: camel/tests/mime-filter/test1.c
===================================================================
RCS file: camel/tests/mime-filter/test1.c
diff -N camel/tests/mime-filter/test1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ camel/tests/mime-filter/test1.c	31 Jan 2005 10:59:50 -0000
@@ -0,0 +1,108 @@
+/*
+  test-crlf.c
+
+  Test the CamelMimeFilterCanon class
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "camel-test.h"
+
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-mime-filter-canon.h>
+
+#define d(x) x
+
+#define NUM_CASES 1
+#define CHUNK_SIZE 4096
+
+struct {
+	int flags;
+	char *in;
+	char *out;
+} tests[] = {
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF,
+	  "From \nRussia - with love.\n\n",
+	  "=46rom \r\nRussia - with love.\r\n\r\n" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF,
+	  "From \r\nRussia - with love.\r\n\n",
+	  "=46rom \r\nRussia - with love.\r\n\r\n" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF,
+	  "Tasmiania with fur    \nFrom",
+	  "Tasmiania with fur    \r\nFrom" },
+	{ CAMEL_MIME_FILTER_CANON_FROM,
+	  "Tasmiania with fur    \nFrom",
+	  "Tasmiania with fur    \nFrom" },
+	{ CAMEL_MIME_FILTER_CANON_CRLF,
+	  "Tasmiania with fur    \nFrom",
+	  "Tasmiania with fur    \r\nFrom" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF,
+	  "Tasmiania with fur    \nFrom here",
+	  "Tasmiania with fur    \r\n=46rom here" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_STRIP,
+	  "Tasmiania with fur    \nFrom here",
+	  "Tasmiania with fur\r\n=46rom here" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_STRIP,
+	  "Tasmiania with fur    \nFrom here\n",
+	  "Tasmiania with fur\r\n=46rom here\r\n" },
+	{ CAMEL_MIME_FILTER_CANON_FROM|CAMEL_MIME_FILTER_CANON_CRLF|CAMEL_MIME_FILTER_CANON_STRIP,
+	  "Tasmiania with fur    \nFrom here or there ? \n",
+	  "Tasmiania with fur\r\n=46rom here or there ?\r\n" },
+};
+
+int 
+main (int argc, char **argv)
+{
+	CamelStreamFilter *filter;
+	CamelMimeFilter *sh;
+	int i;
+	
+	camel_test_init(argc, argv);
+
+	camel_test_start("canonicalisation filter tests");
+
+	for (i=0;i<sizeof(tests)/sizeof(tests[0]);i++) {
+		int step;
+
+		camel_test_push("Data test %d '%s'\n", i, tests[i].in);
+
+		/* try all write sizes */
+		for (step=1;step<20;step++) {
+			CamelStreamMem *out;
+			char *p;
+
+			camel_test_push("Chunk size %d\n", step);
+
+			out = (CamelStreamMem *)camel_stream_mem_new();
+			filter = camel_stream_filter_new_with_stream((CamelStream *)out);
+			sh = camel_mime_filter_canon_new(tests[i].flags);
+			check(camel_stream_filter_add(filter, sh) != -1);
+			check_unref(sh, 2);
+
+			p = tests[i].in;
+			while (*p) {
+				int w = MIN(strlen(p), step);
+
+				check(camel_stream_write((CamelStream *)filter, p, w) == w);
+				p += w;
+			}
+			camel_stream_flush((CamelStream *)filter);
+
+			check_msg(out->buffer->len == strlen(tests[i].out), "Buffer length mismatch: expected %d got %d\n or '%s' got '%.*s'", strlen(tests[i].out), out->buffer->len, tests[i].out, out->buffer->len, out->buffer->data);
+			check_msg(0 == memcmp(out->buffer->data, tests[i].out, out->buffer->len), "Buffer mismatch: expected '%s' got '%.*s'", tests[i].out, out->buffer->len, out->buffer->data);
+			check_unref(filter, 1);
+			check_unref(out, 1);
+
+			camel_test_pull();
+		}
+
+		camel_test_pull();
+	}
+
+	camel_test_end();
+	
+	return 0;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]