Skip to content

Commit 87d0f13

Browse files
author
Sebastian Rose, Hannover, Germany
committed
FIX breaking signed content
The strategy is, to not change user supplied eols when decoding. If an encoded eol was found, use it. If not, go with the one the user gave us.
1 parent d647dce commit 87d0f13

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

Base64.xs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static const unsigned char index_64[256] = {
6868
? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
6969
static char *
7070
my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
71-
{
71+
{
7272
sv_utf8_downgrade(sv,0);
7373
return SvPV(sv,*lp);
7474
}
@@ -128,7 +128,7 @@ encode_base64(sv,...)
128128

129129
/* allocate a result buffer */
130130
RETVAL = newSV(rlen ? rlen : 1);
131-
SvPOK_on(RETVAL);
131+
SvPOK_on(RETVAL);
132132
SvCUR_set(RETVAL, rlen);
133133
r = SvPVX(RETVAL);
134134

@@ -210,7 +210,7 @@ decode_base64(sv)
210210
break;
211211
}
212212
} while (i < 4);
213-
213+
214214
if (c[0] == EQ || c[1] == EQ) {
215215
break;
216216
}
@@ -439,6 +439,8 @@ decode_qp(sv)
439439
char const* end = str + len;
440440
char *r;
441441
char *whitespace = 0;
442+
/* True, if we indeed did encounter an encoded LF at and of line: */
443+
int rfc_nl = 0;
442444

443445
CODE:
444446
RETVAL = newSV(len ? len : 1);
@@ -451,13 +453,33 @@ decode_qp(sv)
451453
str++;
452454
}
453455
else if (*str == '\r' && (str + 1) < end && str[1] == '\n') {
454-
str++;
456+
whitespace = 0;
457+
if( rfc_nl ) {
458+
/* We've already found an encoded LF. Hence, we skip the
459+
* original LF found in the document. */
460+
rfc_nl = 0;
461+
str += 2;
462+
}
463+
else {
464+
/* Otherwise, add the original LF found in the document: */
465+
*r++ = *str++;
466+
*r++ = *str++;
467+
}
455468
}
456469
else if (*str == '\n') {
457470
whitespace = 0;
458-
*r++ = *str++;
471+
if( rfc_nl ) {
472+
/* We've already found encoded LF(s) */
473+
str++;
474+
rfc_nl = 0;
475+
}
476+
else {
477+
/* NOTE: Not canonical LF in MIME-messages! */
478+
*r++ = *str++;
479+
}
459480
}
460481
else {
482+
rfc_nl = 0;
461483
if (whitespace) {
462484
while (whitespace < str) {
463485
*r++ = *whitespace++;
@@ -472,6 +494,10 @@ decode_qp(sv)
472494
buf[1] = *str++;
473495
buf[2] = '\0';
474496
*r++ = (char)strtol(buf, 0, 16);
497+
if( '0' == buf[0] && ('A' == buf[1] || 'D' == buf[1]) ) {
498+
/* Encoded LF at hand. */
499+
rfc_nl = 1;
500+
}
475501
}
476502
else {
477503
/* look for soft line break */

t/quoted-print.t

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,11 @@ print "not " unless decode_qp("foo \n\nfoo =\n\nfoo=20\n\n") eq
233233
"foo\n\nfoo \nfoo \n\n";
234234
$testno++; print "ok $testno\n";
235235

236-
# Same test but with "\r\n" terminated lines
236+
# Same test but with "\r\n" terminated lines. NOTE: If no encoded eol is found,
237+
# take the one supplied by the user! Electronic signatures are destroyed, if we
238+
# enforce some "standard" eol.
237239
print "not " unless decode_qp("foo \r\n\r\nfoo =\r\n\r\nfoo=20\r\n\r\n") eq
238-
"foo\n\nfoo \nfoo \n\n";
240+
"foo\r\n\r\nfoo \r\nfoo \r\n\r\n";
239241
$testno++; print "ok $testno\n";
240242

241243
# Trailing whitespace
@@ -248,7 +250,7 @@ $testno++; print "ok $testno\n";
248250
print "not " unless decode_qp("foo = \t\x20\nbar\t\x20\n") eq "foo bar\n";
249251
$testno++; print "ok $testno\n";
250252

251-
print "not " unless decode_qp("foo = \t\x20\r\nbar\t\x20\r\n") eq "foo bar\n";
253+
print "not " unless decode_qp("foo = \t\x20\r\nbar\t\x20\r\n") eq "foo bar\r\n";
252254
$testno++; print "ok $testno\n";
253255

254256
print "not " unless decode_qp("foo = \t\x20\n") eq "foo ";
@@ -257,7 +259,7 @@ $testno++; print "ok $testno\n";
257259
print "not " unless decode_qp("foo = \t\x20\r\n") eq "foo ";
258260
$testno++; print "ok $testno\n";
259261

260-
print "not " unless decode_qp("foo = \t\x20y\r\n") eq "foo = \t\x20y\n";
262+
print "not " unless decode_qp("foo = \t\x20y\r\n") eq "foo = \t\x20y\r\n";
261263
$testno++; print "ok $testno\n";
262264

263265
print "not " unless decode_qp("foo =xy\n") eq "foo =xy\n";
@@ -359,4 +361,3 @@ print "not " if $] >= 5.006 && (eval 'encode_qp("XXX \x{100}")' || !$@);
359361
$testno++; print "ok $testno\n";
360362

361363
}
362-

0 commit comments

Comments
 (0)