Subject: Extra CRLF on rfc822_output_body()

From: Mark Elvers <[email-masked]>
Date: Tue, 7 Jan 2003 18:32:27 +0000 (GMT)

I am using an IMAP server with mbx mailboxes to keep a drafts folder.
Messages are read, edited and written back.  Each time a message is
written back to the server using rfc822_output(), then mail_append(), it
becomes longer by an extra CRLF.  This is only a problem when the message
is 'simple'.  Text stored in multipart messages is not affected.

I have experimented with patching rfc822_output_body() as follows:

Changed this line:-
// if (!((*f) (s,tmp) && my_rfc822_output_body(&part->body,f,s))) return NIL;
to this:
  if (!((*f) (s,tmp) && my_rfc822_output_body (&part->body,f,s) && (*f)(s,"\015\012"))) return NIL;

And this line:-
//  if (t && *t && !((*f) (s,t) && (*f) (s,"\015\012"))) return NIL;
to this:
  if (t && *t && !(*f)(s,t)) return NIL;

Is it correct to patch as I suggest?

On a separate point, I have noticed that the char* part of SIZEDTEXT must
sometimes be a zero terminated string.  I thought the idea of SIZEDTEXT
was that the zero termination was not needed.

If you take a unterminated SIZEDTEXT string and specify its encoding as
7bit - ie contains no 8bit data, the function rfc822_encode_body_7bit()
skips it (reasonable as it is already 7bit data), then later this
unterminated string is passed directly to i/o function specified as a
parameter to rfc822_output() and described as only a char * (no length).

Alternatively, if you took the same unterminated string from above and set
the body encoding to 8bit, it would have been converted into a zero
terminated string by rfc822_8bit().

I noticed this 'difference' when writing a function to copy body sections
from one message to another.  My function reads something like this:-

destbody->encoding = srcbody->encoding; void *v =
mail_fetch_body_full(stream, uid, section, &destbody->content.text.size,
FT_PEEK | FT_UID); destbody->content.text.data =
malloc(destbody->content.text.size); memcpy(destbody->content.text.data,
v, destbody->content.text.size); ... etc

Which should copy any body part regardless of the encoding, but if the
original encoding is 7bit the copied string is unterminated and later
assumed to be terminated when passed to rfc822_output().

Regards

Mark
-- 
------------------------------------------------------------------
 For information about this mailing list, and its archives, see: 
 http://www.washington.edu/imap/c-client-list.html
------------------------------------------------------------------

---

From: Mark Crispin <[email-masked]>
Date: Tue, 7 Jan 2003 16:21:19 -0800 (Pacific Standard Time)

> is 'simple'.  Text stored in multipart messages is not affected.

If the message is "simple", why not just generate the header, and pass
the concatenation of the header and text to mail_append() without going
through all the complexity of rfc822_output()?

rfc822_output() is intended to be used with SMTP and NNTP sending.  As
such, the trailing CRLF is needed.  Your patch would break that.

> was that the zero termination was not needed.

Not necessarily.  The purpose of the rfc822_encode_body_[78]bit()
functions is to convert SIZEDTEXT strings (which may be binary) into
null-terminated text strings which can be passed to a soutr_t function.
soutr_t functions don't take a size.  They probably should, but it's
entirely too late to change it now.

> v, destbody->content.text.size); ... etc

change the
  destbody->content.text.data = malloc(destbody->content.text.size);
to
  destbody->content.text.data = fs_get (destbody->content.text.size + 1);

Then add:
  destbody->content.text.data[destbody->content.text.size+1] = '\0';

-- Mark --

http://staff.washington.edu/mrc
Science does not emerge from voting, party politics, or public debate.