Bug in IdCoderQuotedPrintable

Giganews Newsgroups
Subject: Bug in IdCoderQuotedPrintable
Posted by:  Scott Bussinger (scot…@opto-pps.com)
Date: Thu, 26 Feb 2004

There's a bug in Indy's TIdEncoderQuotedPrintable.Encode routine from the
IdCoderQuotedPrintable.pas file (it's in the development snapshots for both
Indy 9 and 10). Basically it doesn't encode lines that are exactly 70
characters long correctly.

When the encoder tries to encode a line that has exactly 70 characters plus
a CRLF (the CRLF is automatically added in the TIdMessageClient.SendBody
routine when it calls TIdEncoderQuotedPrintable.Encode), it puts all 72 of
those characters into it's internal line buffer. Then it notices that the
line buffer is >71 bytes, appends an "=", adds that result into an internal
TStringList, then starts a new line buffer. Since the line has now been
completely processed, it converts the TStringList into a text line which
looks something like:

    ... 'wxyz'#13#10'='#13#10

It then strips away the last CRLF (because normally it's an extra pair)
leaving:

    ...'wxyz'#13#10'='

and the next line added to the stream has magically gotten prefixed with an
unencoded "=" sign.

The routine really needs to be rewritten so that it works the other way
around (put in a soft break just before the character that goes over a limit
instead just after). But I'm a bit leary of mucking around too much and
breaking something else. The routine could be certainly be more cleanly
written but I'm not clear on what contracts exist between the various layers
in Indy.

A very quickie fix would be to change the line that reads

          if Length(Line) > 71 then

to

          if (Length(Line) > 71) and not (Buffer[i] in [#10,#13]) then

But, while short, this isn't a good fix and makes many assumptions such as
that there will be no CRLF's embedded in the string being converted (aside
from the CRLF automatically appended to the end of the line).

Your thoughts? Use this ugly fix or more significantly rewrite the routine?

Be seeing you.

Replies