Hi,

The patch below fixes a bug where mh would see the '\n\nFrom ' pattern
in the middle of a mail message and think it was the start of a new
message.  I finally got tired of this bug, so I decided to fix it,
especially after I discovered the nmh project.

The fix makes nmh obey the "Content-Length" header if it exists in the
headers of the mail message, and thus won't let it be fooled into
thinking it's found a new message just because it found '\n\nFrom '.

To reproduce the bug, use "comp" to send a message like this to
yourself:

------- Included Message
To: yourself
Subject: test

This one is okay.
>From here to eternity.
The next one is not.

>From here to eternity.
You get a BAD MSG from
the above line.

The end
------- End of Included Message

BTW, who's responsibility is it to make sure that no '\n\nFrom ' pattern
appears in an email message?  The mail client sending the mail, the MTA
(like sendmail), or the mail client retrieving the mail?  I thought the
mail client that sends the message is supposed to ensure this, but I'm
not sure.

Comments?

Please Cc: me on any replies since I'm not subscribed to the list.

Dave
--
David D. Kilzer              \          ``One person with a belief
Software Designer            /      is equal to a force of ninety nine
Raytheon Systems Company     \            who only have interest.''
[EMAIL PROTECTED]              /                John Stuart Mill


--- nmh-0.28-pre9/sbr/m_getfld.c.cln    Fri Jul 31 17:48:37 1998
+++ nmh-0.28-pre9/sbr/m_getfld.c        Sat Jan 30 19:30:08 1999
@@ -155,6 +155,22 @@
 extern int msg_count;
 
 /*
+ * used in uip/scansbr.c
+ * The value of the Content-Length header field if it exists,
+ * otherwise it is set to -1.  Used to prevent the false 
+ * identification of '\n\nFrom ' within the body of a message
+ * with a Content-Length header.
+ */
+int content_length;
+
+/*
+ * used in uip/scansbr.c
+ * Keeps track of how many characters we've seen in the body
+ * of the message so far.  Used with content_length.
+ */
+int body_count;
+
+/*
  * defined in sbr/m_msgdef.c = MS_DEFAULT
  */
 extern int msg_style;
@@ -633,6 +649,18 @@
     }
 
     if (msg_style == MS_MBOX) {
+       /*
+        * Check to make sure we've actually made it to the end
+        * of the current message and not found '\n\nFrom ' in
+        * the body of the message.
+        */
+       if (content_length != -1 && body_count < content_length)
+       {
+           fseek (iob, (long)(pos-1), SEEK_SET);
+           getc (iob);         /* should be OK */
+           return 0;
+       }
+
 #ifndef RPATHS
        while ((c = getc (iob)) != '\n')
            if (c < 0)
--- nmh-0.28-pre9/uip/scansbr.c.cln     Fri Jul 31 17:46:20 1998
+++ nmh-0.28-pre9/uip/scansbr.c Sat Jan 30 19:43:13 1999
@@ -50,6 +50,22 @@
 
 char *scanl = 0;                       /* text of most recent scanline    */
 
+/*
+ * defined in ../sbr/m_getfld.c
+ * The value of the Content-Length header field if it exists,
+ * otherwise it is set to -1.  Used to prevent the false 
+ * identification of '\n\nFrom ' within the body of a message 
+ * with a Content-Length header.
+ */
+extern int content_length;
+
+/*
+ * defined in ../sbr/m_getfld.c
+ * Keeps track of how many characters we've seen in the body
+ * of the message so far.  Used with content_length.
+ */
+extern int body_count;
+
 #define FPUTS(buf) {\
                if (mh_fputs(buf,scnout) == EOF)\
                    adios (scnmsg, "write error on");\
@@ -138,6 +154,8 @@
     dat[0] = innum ? innum : outnum;
     dat[1] = curflg;
     dat[4] = unseen;
+    content_length = -1;
+    body_count = 0;
 
     /*
      * Get the first field.  If the message is non-empty
@@ -213,6 +231,11 @@
                    } while ((cptr = cptr->c_next));
                }
 
+               if (strncasecmp(name, "content-length", 14) == 0)
+               {
+                   content_length = atoi(tmpbuf);
+               }
+
                while (state == FLDPLUS) {
                    state = m_getfld (state, name, tmpbuf, rlwidth, inb);
                    if (outnum)
@@ -240,6 +263,8 @@
                 * returned in the global "msg_count".
                 */
 body:;
+               body_count += msg_count;        /* catch first msg_count */
+
                while (state == BODY) {
 #ifdef LINUX_STDIO
                    if (scnout->_IO_write_ptr == scnout->_IO_write_end) {
@@ -258,6 +283,7 @@
                    scnout->_cnt -= msg_count;
                    scnout->_ptr += msg_count;
 #endif
+                   body_count += msg_count;
                }
                goto finished;
 

Reply via email to