Skip Menu |

This queue is for tickets about the MIME-Base64 CPAN distribution.

Report information
The Basics
Id: 128456
Status: new
Priority: 0/
Queue: MIME-Base64

People
Owner: Nobody in particular
Requestors: chipsbarrier [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)

Attachments


Subject: decode_qp destroys PDF Signatures for no reason
Date: Thu, 7 Feb 2019 21:52:41 +0100
To: bug-MIME-Base64 [...] rt.cpan.org
From: Sebastian Rose <chipsbarrier [...] gmail.com>
Hello MIME::Base64 maintainers, I use MIME::Decoder::QuotedPrint and other modules that rely on the XS Code in the MIME::Base64 distribution. Unfortunately, the decode_qp destroys signatures in PDF files created on UNIXoids and signed and sent from a windows box using Outlook. Outlook decides to send some PDFs quoted-printable encoded (...) and qp-encodes \n-only linefeeds only as it considers \r\n the cannonical MIME LF. The line distructing the signatures (and earning us nothing in MIME-mail environments) is the insertion of linefeeds NOT found in the encoded document (plus NOT being MIME-message LFs). This happens in Base64.xs, line 459 ff: else if (*str == '\r' && (str + 1) < end && str[1] == '\n') { str++; } else if (*str == '\n') { whitespace = 0; *r++ = *str++; } It says: - skip \r - consider \n a whitspace. It should say: - If no qp-encoded LF was found before end of line, then insert the one found in the user data. The attached dirty hack fixes the problem for me. Its a little Perl project and features a few simple tests. perl Makefile.PL make make test prove -vrc t It is sure not the best Fix one could think of. But I urgently needed to fix the LF problem in Base64.xs' encode_qp to stop it from destroying customer data - and it seems to work perfectly well so far. As you can see in the attached lib/MIME/QuotedPrintMsCompat.pm, I overwrite *MIME::Decoder::QutotedPrint::decode_it()*, too (as I use MIME::Parser::Filer). Not sure if that is necessary or even advisable. Here's a diff between my proposal and the original, cut down to the decode_qp function in Base64.xs: --- ext/decode_qp-only.xs 2019-02-07 20:33:07.384921636 +0100 +++ ext/decode_qp_ms_compat.xs 2019-02-07 21:43:22.359144067 +0100 @@ -1,6 +1,5 @@ - SV* -decode_qp(sv) +decode_qp_ms_compat(sv) SV* sv PROTOTYPE: $ @@ -10,6 +9,8 @@ char const* end = str + len; char *r; char *whitespace = 0; + /* True, if we indeed did encounter an encoded LF at and of line: */ + int rfc_nl = 0; CODE: RETVAL = newSV(len ? len : 1); @@ -22,13 +23,33 @@ str++; } else if (*str == '\r' && (str + 1) < end && str[1] == '\n') { - str++; + whitespace = 0; + if( rfc_nl ) { + /* We've already found an encoded LF. Hence, we skip the + * original LF found in the document. */ + rfc_nl = 0; + str += 2; + } + else { + /* Otherwise, add the original LF found in the document: */ + *r++ = *str++; + *r++ = *str++; + } } else if (*str == '\n') { whitespace = 0; + if( rfc_nl ) { + /* We've already found encoded LF(s) */ + str++; + rfc_nl = 0; + } + else { + /* NOTE: Not canonical LF in MIME-messages! */ *r++ = *str++; } + } else { + rfc_nl = 0; if (whitespace) { while (whitespace < str) { *r++ = *whitespace++; @@ -43,6 +64,10 @@ buf[1] = *str++; buf[2] = '\0'; *r++ = (char)strtol(buf, 0, 16); + if( '0' == buf[0] && ('A' == buf[1] || 'D' == buf[1]) ) { + /* Encoded LF at hand. */ + rfc_nl = 1; + } } else { /* look for soft line break */ Best regards, - Sebastian

Message body not shown because it is not plain text.