Minimum usable counts [was: Question]

David Relson relson at osagesoftware.com
Tue May 26 01:39:59 CEST 2009


On Mon, 25 May 2009 23:39:14 +0200 (CEST)
Pavel Kankovsky wrote:

> On Mon, 25 May 2009, Stephen Davies wrote:
> 
> > The actual texts were:
> > 
> > h=<CR><LF>ere
> > 
> > and 
> > 
> > h=<LF>ere
> > 
> > The first case is the raw text received by sendmail, amavis-milter
> > and amavisd.
> > 
> > The second is the text presented by kmail.
> 
> What was the transfer encoding of (that part of) the message? Was is
> quoted printable?
> 
> qp_decode() seems to recognize only "=\n" as a QP line continuation
> and this makes it choke on raw RFC 822/2822 message texts with lines 
> terminated by CRLF pair.

H'lo Pavel,

Thanks for taking a look at the code.  I think you spotted the
problem.  

Attached is a patch for src/qp.c so that qp_decode calls qp_eol_check -
a new function that checks for both "=\n" and "=\r\n". 

Stephen:

Give it a test.

Regards,

David
-------------- next part --------------
Index: src/qp.c
===================================================================
--- src/qp.c	(revision 6806)
+++ src/qp.c	(working copy)
@@ -41,6 +41,10 @@
     }
 }
 
+/* Function Prototypes  */
+
+static int qp_eol_check( byte *s, byte *e );
+
 /* Function Definitions  */
 
 uint qp_decode(word_t *word, qp_mode mode)
@@ -56,10 +60,13 @@
 	int x, y;
 	switch (ch) {
 	    case '=':
-		if (mode == RFC2045 && s + 1 <= e && s[0] == '\n') {
-		    /* continuation line, trailing = */
-		    s++;
-		    continue;
+		if (mode == RFC2045) {
+		    int c = qp_eol_check( s, e );
+		    if (c != 0) {
+			/* continuation line, trailing = */
+			s += c;
+			continue;
+		    }
 		}
 		if (s + 2 <= e && 
 			(y = hex_to_bin(s[0])) >= 0 && (x = hex_to_bin(s[1])) >= 0) {
@@ -129,3 +136,26 @@
 
     return true;
 }
+
+static int qp_eol_check( byte *s, byte *e )
+{
+    /* test for LF */
+    if (s + 1 <= e && s[0] == '\n')
+    {
+	/* only LF */
+	return 1;
+    }
+
+    /* test for CR */
+    if (s + 1 <= e && s[0] == '\r')
+    { 
+	if (s + 2 <= e && s[1] == '\n')
+	    /* CR LF */
+	    return 2;
+	else
+	    /* only CR */
+	    return 1;
+    }
+
+    return 0;
+}


More information about the bogofilter mailing list