From f7fce1e2088ed888c5ced3f2649af84bc0a672b9 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Mon, 22 Aug 2016 17:20:57 -0400 Subject: [PATCH] mime/quotedprintable: accept trailing soft line-break at the end of message Fixes #15486. Change-Id: Id879dc9acef9232003df9a0f6f54312191374a60 Reviewed-on: https://go-review.googlesource.com/27530 Run-TryBot: Minux Ma TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/mime/quotedprintable/reader.go | 6 +++++- src/mime/quotedprintable/reader_test.go | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mime/quotedprintable/reader.go b/src/mime/quotedprintable/reader.go index 3bd6833da5fb8f..7645777ab2170d 100644 --- a/src/mime/quotedprintable/reader.go +++ b/src/mime/quotedprintable/reader.go @@ -74,6 +74,9 @@ func (r *Reader) Read(p []byte) (n int, err error) { // 1. in addition to "=\r\n", "=\n" is also treated as soft line break. // 2. it will pass through a '\r' or '\n' not preceded by '=', consistent // with other broken QP encoders & decoders. + // 3. it accepts soft line-break (=) at end of message (issue 15486); i.e. + // the final byte read from the underlying reader is allowed to be '=', + // and it will be silently ignored. for len(p) > 0 { if len(r.line) == 0 { if r.rerr != nil { @@ -89,7 +92,8 @@ func (r *Reader) Read(p []byte) (n int, err error) { if bytes.HasSuffix(r.line, softSuffix) { rightStripped := wholeLine[len(r.line):] r.line = r.line[:len(r.line)-1] - if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) { + if !bytes.HasPrefix(rightStripped, lf) && !bytes.HasPrefix(rightStripped, crlf) && + !(len(rightStripped) == 0 && len(r.line) > 0 && r.rerr == io.EOF) { r.rerr = fmt.Errorf("quotedprintable: invalid bytes after =: %q", rightStripped) } } else if hasLF { diff --git a/src/mime/quotedprintable/reader_test.go b/src/mime/quotedprintable/reader_test.go index e77b2610ec104a..966f33e6c0efb6 100644 --- a/src/mime/quotedprintable/reader_test.go +++ b/src/mime/quotedprintable/reader_test.go @@ -58,6 +58,9 @@ func TestReader(t *testing.T) { {in: "foo=\nbar", want: "foobar"}, {in: "foo=\rbar", want: "foo", err: "quotedprintable: invalid hex byte 0x0d"}, {in: "foo=\r\r\r \nbar", want: "foo", err: `quotedprintable: invalid bytes after =: "\r\r\r \n"`}, + // Issue 15486, accept trailing soft line-break at end of input. + {in: "foo=", want: "foo"}, + {in: "=", want: "", err: `quotedprintable: invalid bytes after =: ""`}, // Example from RFC 2045: {in: "Now's the time =\n" + "for all folk to come=\n" + " to the aid of their country.",