nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: jhillyerd/enmime
Pull request #111 (2018-12-14 18:46:02)

check for and decode rfc2047 attribute name in Part header

coveralls: 
[![Coverage Status](https://coveralls.io/builds/20642384/badge)](https://coveralls.io/builds/20642384)

Coverage increased (+0.06%) to 87.176% when pulling **721205c01d8bf5150b77a7b691645b32850a7a43 on requaos:requaos/rfc2047attribute** into **b38c33b2e5b740dda64a88dfc5004b900bf6f5b2 on jhillyerd:develop**.

jhillyerd: Thanks

Patch:
diff --git a/header.go b/header.go
index 84f3e07..5503952 100644
--- a/header.go
+++ b/header.go
@@ -251,11 +251,16 @@ func fixMangledMediaType(mtype, sep string) string {
 			if !strings.Contains(p, "=") {
 				p = p + "=" + pvPlaceholder
 			}
+
+			// RFC-2047 encoded attribute name
+			p = rfc2047AttributeName(p)
+
 			pair := strings.Split(p, "=")
 			if strings.Contains(mtype, pair[0]+"=") {
 				// Ignore repeated parameters.
 				continue
 			}
+
 			if strings.ContainsAny(pair[0], "()<>@,;:\"\\/[]?") {
 				// attribute is a strict token and cannot be a quoted-string
 				// if any of the above characters are present in a token it
@@ -474,3 +479,15 @@ func fixUnquotedSpecials(s string) string {
 func whiteSpaceRune(r rune) bool {
 	return r == ' ' || r == '\t' || r == '\r' || r == '\n'
 }
+
+// rfc2047AttributeName checks if the attribute name is encoded in RFC2047 format
+// RFC2047 Example:
+//     `=?UTF-8?B?bmFtZT0iw7DCn8KUwoo=?=`
+func rfc2047AttributeName(s string) string {
+	if !strings.Contains(s, "?=") {
+		return s
+	}
+	pair := strings.SplitAfter(s, "?=")
+	pair[0] = decodeHeader(pair[0])
+	return strings.Join(pair, "")
+}


Test patch:
diff --git a/header_test.go b/header_test.go
index 171ff20..81465d3 100644
--- a/header_test.go
+++ b/header_test.go
@@ -177,6 +177,11 @@ func TestFixMangledMediaType(t *testing.T) {
 			sep:   ";",
 			want:  "text/html;charset=",
 		},
+		{
+			input: "application/octet-stream;=?UTF-8?B?bmFtZT0iw7DCn8KUwoo=?=You've got a new voice miss call.msg",
+			sep:   ";",
+			want:  "application/octet-stream;name=\"ð\u009f\u0094\u008aYou've got a new voice miss call.msg",
+		},
 		{
 			input: "application/pdf name=\"file.pdf\"",
 			sep:   " ",
Repository: jhillyerd/enmime
Pull request #139 (2019-12-21 17:01:46)

mime: invalid media parameter
While we handle media parameters with missing values if they are the last parameter, this fix allows for the handling of media parameters missing value in the middle of the parameter list.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/27745010/badge)](https://coveralls.io/builds/27745010)

Coverage increased (+0.02%) to 92.45% when pulling **b3e642b6aa00ea69d58b7f428a9e202d3109a24e on requaos:requaos/missingParameterValue** into **cf488a7d428e11c06fa07f9e14e1ac27460347c0 on jhillyerd:develop**.

requaos: Each of the two above commits, solve a different problem. Both problems result in the same error.

1. `text/html; charset=; format=flowed` <-- the middle parameter was not getting fixed
2. `multipart/mixed; boundary=?BE023287982-wefweiuh38839` <-- The first character '?' was not being included in the check to see if the parameter value needs to be quoted.

Patch:
diff --git a/header.go b/header.go
index 778dd02..04ab3e8 100644
--- a/header.go
+++ b/header.go
@@ -383,6 +383,13 @@ findValueStart:
 
 			break findValueStart
 
+		case ';':
+			if value.Len() == 0 {
+				value.WriteString(`"";`)
+			}
+
+			break findValueStart
+
 		default:
 			valueQuotedOriginally = false
 			valueQuoteAdded = false
@@ -400,8 +407,6 @@ findValueStart:
 	} else {
 		// The beginning of the value is not at the end of the string
 
-		s = s[i+1:]
-
 		quoteIfUnquoted := func() {
 			if !valueQuoteNeeded {
 				if !valueQuoteAdded {
@@ -414,6 +419,14 @@ findValueStart:
 			}
 		}
 
+		for _, v := range []byte{'(', ')', '<', '>', '@', ',', ':', '/', '[', ']', '?', '='} {
+			if s[0] == v {
+				quoteIfUnquoted()
+			}
+		}
+
+		s = s[i+1:]
+
 	findValueEnd:
 		for len(s) > 0 {
 			switch s[0] {


Test patch:
diff --git a/header_test.go b/header_test.go
index 11c1e11..387b65e 100644
--- a/header_test.go
+++ b/header_test.go
@@ -323,6 +323,10 @@ func TestFixUnquotedSpecials(t *testing.T) {
 			input: "application/octet-stream; param1=value/1",
 			want:  "application/octet-stream; param1=\"value/1\"",
 		},
+		{
+			input: "multipart/alternative; boundary=?UOAwFjScLp1is-162467503201177404728935166502-",
+			want:  "multipart/alternative; boundary=\"?UOAwFjScLp1is-162467503201177404728935166502-\"",
+		},
 		{
 			input: `text/HTML; charset="UTF-8Return-Path: bounce-810_HTML-769869545-477063-1070564-43@bounce.email.oflce57578375.com`,
 			want:  `text/HTML; charset="UTF-8Return-Path: bounce-810_HTML-769869545-477063-1070564-43@bounce.email.oflce57578375.com"`,
@@ -331,6 +335,10 @@ func TestFixUnquotedSpecials(t *testing.T) {
 			input: `text/html;charset=`,
 			want:  `text/html;charset=""`,
 		},
+		{
+			input: `text/html; charset=; format=flowed`,
+			want:  `text/html; charset=""; format=flowed`,
+		},
 		{
 			input: `text/html;charset="`,
 			want:  `text/html;charset=""`,
Repository: jhillyerd/enmime
Pull request #145 (2020-01-03 21:36:18)

Read into destination by length, not capacity
Fixes the `boundaryReader` implementation of `io.Reader` to fill the slice based on its length, not its capacity. As per [the `io.Reader` documentation](https://pkg.go.dev/io?tab=doc#Reader).

coveralls: 
[![Coverage Status](https://coveralls.io/builds/27907373/badge)](https://coveralls.io/builds/27907373)

Coverage remained the same at 95.522% when pulling **a906bbd423f019490dfd949d6911c511467f443b on dcormier:dc/len** into **7bc1c63531f87d742f365198938c884c023d3c17 on jhillyerd:develop**.

jhillyerd: Good catch, thank you!

Patch:
diff --git a/boundary.go b/boundary.go
index 19da4d9..636f494 100644
--- a/boundary.go
+++ b/boundary.go
@@ -75,7 +75,7 @@ func (b *boundaryReader) Read(dest []byte) (n int, err error) {
 		return b.buffer.Read(dest)
 	}
 
-	for i := 0; i < cap(dest); i++ {
+	for i := 0; i < len(dest); i++ {
 		cs, err := b.r.Peek(1)
 		if err != nil && err != io.EOF {
 			return 0, errors.WithStack(err)


Test patch:
diff --git a/boundary_test.go b/boundary_test.go
index 2146836..ca13792 100644
--- a/boundary_test.go
+++ b/boundary_test.go
@@ -457,3 +457,47 @@ func TestBoundaryReaderReadErrors(t *testing.T) {
 		t.Fatal("Read() should have returned bufio.ErrBufferFull error, failed")
 	}
 }
+
+// TestReadLenNotCap checks that the `boundaryReader` `io.Reader` implementation fills the provided
+// slice based on its length (as per the `io.Reader` documentation), and not its capacity.
+func TestReadLenNotCap(t *testing.T) {
+	t.Parallel()
+
+	input := "--STOP\nabcdefghijklm\n--STOP\nnopqrstuvwxyz\n--STOP--\n"
+	boundary := "STOP"
+	parts := []string{"abcdefghijklm", "nopqrstuvwxyz"}
+
+	ir := bufio.NewReader(strings.NewReader(input))
+	br := newBoundaryReader(ir, boundary)
+
+	for i, want := range parts {
+		next, err := br.Next()
+		if err != nil {
+			t.Fatalf("Error %q on part %v, input %q", err, i, input)
+		}
+		if !next {
+			t.Fatal("Next() = false, want: true")
+		}
+
+		var out []byte
+		b := make([]byte, 6, 20) // Ensure the capacity is greater than the length.
+		max := len(b)
+		var c int
+		for err == nil {
+			c, err = br.Read(b)
+			if c > max {
+				t.Errorf("Per the docuemtation for io.Reader, should not have read more than %d bytes, but read %d", max, c)
+			}
+
+			out = append(out, b[0:c]...)
+		}
+
+		if err != io.EOF {
+			t.Errorf("Expected %v, but got: %+v", io.EOF, err)
+		}
+
+		if want != string(out) {
+			t.Errorf("Expected part to be read as %q, but got %q", want, out)
+		}
+	}
+}
Repository: jhillyerd/enmime
Pull request #149 (2020-03-05 20:39:59)

Header line incorrectly beginning with a space
results in "mime: invalid media parameter" error

This is a best effort attempt to correct an invalid continuation.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/29162169/badge)](https://coveralls.io/builds/29162169)

Coverage increased (+0.02%) to 95.587% when pulling **eebd72dcaea5944152993d68671e93953893d1c1 on requaos:requaos/invalidContinuation** into **11470584bd1939caa6d6a196b9b1633ce961f9dd on jhillyerd:develop**.

jhillyerd: Looks good, thanks.

Patch:
diff --git a/header.go b/header.go
index 09a4f30..3f0ffe2 100644
--- a/header.go
+++ b/header.go
@@ -101,10 +101,21 @@ func readHeader(r *bufio.Reader, p *Part) (textproto.MIMEHeader, error) {
 		firstColon := bytes.IndexByte(s, ':')
 		firstSpace := bytes.IndexAny(s, " \t\n\r")
 		if firstSpace == 0 {
-			// Starts with space: continuation
-			buf.WriteByte(' ')
-			buf.Write(textproto.TrimBytes(s))
-			continue
+			// If there is a single colon followed immediately by a space and there
+			// is no equal sign, or comes before any equal sign, then it should not
+			// be considered as a continuation.
+			colonSpaceIdx := bytes.Index(s, []byte{':', ' '})
+			equalIdx := bytes.IndexByte(s, '=')
+			if bytes.Count(s, []byte{':'}) == 1 && colonSpaceIdx != -1 &&
+				(equalIdx == -1 || equalIdx > colonSpaceIdx) {
+				s = textproto.TrimBytes(s)
+				firstColon = bytes.IndexByte(s, ':')
+			} else {
+				// Starts with space: continuation
+				buf.WriteByte(' ')
+				buf.Write(textproto.TrimBytes(s))
+				continue
+			}
 		}
 		if firstColon == 0 {
 			// Can't parse line starting with colon: skip


Test patch:
diff --git a/header_test.go b/header_test.go
index f4978e7..b3d2de9 100644
--- a/header_test.go
+++ b/header_test.go
@@ -510,6 +510,12 @@ func TestReadHeader(t *testing.T) {
 			want:    "line1=foo;",
 			correct: true,
 		},
+		{
+			input:   "X-Not-Continuation: line1=foo;\n X-Next-Header: bar\n",
+			hname:   "X-Not-Continuation",
+			want:    "line1=foo;",
+			correct: true,
+		},
 		{
 			input: "Authentication-Results: mx.google.com;\n" +
 				"       spf=pass (google.com: sender)\n" +
Repository: jhillyerd/enmime
Pull request #154 (2020-05-22 04:03:50)

Handle trailing separators in header
Hello. This is a fix for https://github.com/jhillyerd/enmime/issues/153.

If my understanding is correct, here is what was happening. When the `Content-Type` header value was something like `text/plain;`, it would turn into `text/plain;=not-a-param-value`, then `=not-a-param-value` parsed on its own would cause a `mime: invalid media parameter` error in turn.

Thanks!

coveralls: 
[![Coverage Status](https://coveralls.io/builds/30961350/badge)](https://coveralls.io/builds/30961350)

Coverage decreased (-0.04%) to 95.546% when pulling **5ca68e05e7abe670defd20b65bcf60295e618554 on joekamibeppu:joekamibeppu/trailing-comma** into **2505a646df59dc80689c22c89478327e8177d4fa on jhillyerd:develop**.


Patch:
diff --git a/header.go b/header.go
index 3f0ffe2..fd5cffd 100644
--- a/header.go
+++ b/header.go
@@ -287,6 +287,11 @@ func fixMangledMediaType(mtype, sep string) string {
 				}
 			}
 		default:
+			if len(p) == 0 {
+				// Ignore trailing separators.
+				continue
+			}
+
 			if !strings.Contains(p, "=") {
 				p = p + "=" + pvPlaceholder
 			}


Test patch:
diff --git a/header_test.go b/header_test.go
index b3d2de9..7ad3422 100644
--- a/header_test.go
+++ b/header_test.go
@@ -189,6 +189,11 @@ func TestFixMangledMediaType(t *testing.T) {
 			sep:   ";",
 			want:  "multipart/mixed;charset=",
 		},
+		{
+			input: "text/plain;",
+			sep:   ";",
+			want:  "text/plain",
+		},
 		{
 			input: "application/octet-stream;=?UTF-8?B?bmFtZT0iw7DCn8KUwoo=?=You've got a new voice miss call.msg",
 			sep:   ";",
Repository: jhillyerd/enmime
Pull request #166 (2020-09-10 14:33:35)

Feature/159
Fix reported issue #159 and test cases


dcormier: @requaos, how's your memory on this one? I'm sure this change is there because of something you encountered.

Patch:
diff --git a/header.go b/header.go
index 2674408..a52468b 100644
--- a/header.go
+++ b/header.go
@@ -101,19 +101,19 @@ func readHeader(r *bufio.Reader, p *Part) (textproto.MIMEHeader, error) {
 		firstColon := bytes.IndexByte(s, ':')
 		firstSpace := bytes.IndexAny(s, " \t\n\r")
 		if firstSpace == 0 {
-			// If there is a single colon followed immediately by a space and there
-			// is no equal sign, or comes before any equal sign, then it should not
-			// be considered as a continuation.
-			colonSpaceIdx := bytes.Index(s, []byte{':', ' '})
-			equalIdx := bytes.IndexByte(s, '=')
-			if bytes.Count(s, []byte{':'}) == 1 && colonSpaceIdx != -1 &&
-				(equalIdx == -1 || equalIdx > colonSpaceIdx) {
-				s = textproto.TrimBytes(s)
-				firstColon = bytes.IndexByte(s, ':')
+			// Do not consider as a continuation if the first whitespace
+			//  in the trimmed line comes right after a colon which,
+			//  in turn, follows at least one character.
+			sTrimmed := textproto.TrimBytes(s)
+			firstTrimmedColon := bytes.IndexByte(sTrimmed, ':')
+			firstTrimmedSpace := bytes.IndexAny(sTrimmed, " \t\n\r")
+			if firstTrimmedColon > 0 && firstTrimmedSpace == firstTrimmedColon+1 {
+				s = sTrimmed
+				firstColon = firstTrimmedColon
 			} else {
 				// Starts with space: continuation
 				buf.WriteByte(' ')
-				buf.Write(textproto.TrimBytes(s))
+				buf.Write(sTrimmed)
 				continue
 			}
 		}


Test patch:
diff --git a/header_test.go b/header_test.go
index e7a02cb..5d36af3 100644
--- a/header_test.go
+++ b/header_test.go
@@ -529,6 +529,18 @@ func TestReadHeader(t *testing.T) {
 			want:    "line1=foo;",
 			correct: true,
 		},
+		{
+			input:   "X-Continuation: line1=foo;\n not-a-header 15 X-Not-Header: bar\n",
+			hname:   "X-Continuation",
+			want:    "line1=foo; not-a-header 15 X-Not-Header: bar",
+			correct: true,
+		},
+		{
+			input:   "X-Continuation-DKIM-like: line1=foo;\n h=Subject:From:Reply-To:To:Date:Message-ID: List-ID:List-Unsubscribe:\n Content-Type:MIME-Version;\n",
+			hname:   "X-Continuation-DKIM-like",
+			want:    "line1=foo; h=Subject:From:Reply-To:To:Date:Message-ID: List-ID:List-Unsubscribe: Content-Type:MIME-Version;",
+			correct: true,
+		},
 		{
 			input: "Authentication-Results: mx.google.com;\n" +
 				"       spf=pass (google.com: sender)\n" +
Repository: jhillyerd/enmime
Pull request #172 (2020-10-31 21:14:02)

Revert accidental continuation detection
See #171 for context

coveralls: 
[![Coverage Status](https://coveralls.io/builds/34613752/badge)](https://coveralls.io/builds/34613752)

Coverage decreased (-0.02%) to 95.356% when pulling **f0718a1f4afc83d3275ef9c1afaa8c0edb06fe72 on revert-continuation** into **e8f7e6d3e1553896325ad6b9eea14b99d90ffe1b on master**.


Patch:
diff --git a/header.go b/header.go
index a52468b..9f588fb 100644
--- a/header.go
+++ b/header.go
@@ -101,21 +101,10 @@ func readHeader(r *bufio.Reader, p *Part) (textproto.MIMEHeader, error) {
 		firstColon := bytes.IndexByte(s, ':')
 		firstSpace := bytes.IndexAny(s, " \t\n\r")
 		if firstSpace == 0 {
-			// Do not consider as a continuation if the first whitespace
-			//  in the trimmed line comes right after a colon which,
-			//  in turn, follows at least one character.
-			sTrimmed := textproto.TrimBytes(s)
-			firstTrimmedColon := bytes.IndexByte(sTrimmed, ':')
-			firstTrimmedSpace := bytes.IndexAny(sTrimmed, " \t\n\r")
-			if firstTrimmedColon > 0 && firstTrimmedSpace == firstTrimmedColon+1 {
-				s = sTrimmed
-				firstColon = firstTrimmedColon
-			} else {
-				// Starts with space: continuation
-				buf.WriteByte(' ')
-				buf.Write(sTrimmed)
-				continue
-			}
+			// Starts with space: continuation
+			buf.WriteByte(' ')
+			buf.Write(textproto.TrimBytes(s))
+			continue
 		}
 		if firstColon == 0 {
 			// Can't parse line starting with colon: skip


Test patch:
diff --git a/header_test.go b/header_test.go
index b5919e4..4cdbbdb 100644
--- a/header_test.go
+++ b/header_test.go
@@ -543,14 +543,6 @@ func TestReadHeader(t *testing.T) {
 			correct: true,
 			extras:  []string{"line2"},
 		},
-		{
-			label:   "correctable accidental continuation",
-			input:   "X-Not-Continuation: line1=foo;\n X-Next-Header: bar\n",
-			hname:   "X-Not-Continuation",
-			want:    "line1=foo;",
-			correct: true,
-			extras:  []string{"X-Next-Header"},
-		},
 		{
 			label:   "continuation with header style",
 			input:   "X-Continuation: line1=foo;\n not-a-header 15 X-Not-Header: bar\n",
@@ -582,6 +574,17 @@ func TestReadHeader(t *testing.T) {
 				" dkim=pass header.i=@2",
 			correct: true,
 		},
+		{
+			label: "continuation containing early name-colon",
+			input: "DKIM-Signature: a=rsa-sha256; v=1; q=dns/txt;\r\n" +
+				"  s=krs; t=1603674005; h=Content-Transfer-Encoding: Mime-Version:\r\n" +
+				"  Content-Type: Subject: From: To: Message-Id: Sender: Date;\r\n",
+			hname: "DKIM-Signature",
+			want: "a=rsa-sha256; v=1; q=dns/txt;" +
+				" s=krs; t=1603674005; h=Content-Transfer-Encoding: Mime-Version:" +
+				" Content-Type: Subject: From: To: Message-Id: Sender: Date;",
+			correct: true,
+		},
 	}
 
 	for _, tt := range ttable {
Repository: jhillyerd/enmime
Pull request #195 (2021-06-08 08:39:04)

Remove whitespace between parameter=value and ; in headers
This is a fix for the problem of PR: [193](https://github.com/jhillyerd/enmime/pull/193)

Sorry for taking over, but I really need the fix :(

Let me know if there is anything you would like me to change.

Thanks for the package.

jhillyerd: Looks good, thanks!

Patch:
diff --git a/header.go b/header.go
index 9a4c942..de40296 100644
--- a/header.go
+++ b/header.go
@@ -308,6 +308,8 @@ func fixMangledMediaType(mtype string, sep rune) string {
 		// Only terminate with semicolon if not the last parameter and if it doesn't already have a
 		// semicolon.
 		if i != len(parts)-1 && !strings.HasSuffix(mtype, ";") {
+			// Remove whitespace between parameter=value and ;
+			mtype = strings.TrimRight(mtype, " \t")
 			mtype += ";"
 		}
 	}


Test patch:
diff --git a/header_test.go b/header_test.go
index cfaa47d..539f6af 100644
--- a/header_test.go
+++ b/header_test.go
@@ -799,6 +799,48 @@ func TestParseMediaType(t *testing.T) {
 			mtype:  "text/html",
 			params: map[string]string{"name": "index;a.html", "hash": "8675309"},
 		},
+		{
+			label:  "with whitespace",
+			input:  "text/plain; charset=\"UTF-8\" ; format=flowed",
+			mtype:  "text/plain",
+			params: map[string]string{"charset": "UTF-8", "format": "flowed"},
+		},
+		{
+			label:  "with whitespace tab",
+			input:  "text/plain; charset=\"UTF-8\"\t; format=flowed",
+			mtype:  "text/plain",
+			params: map[string]string{"charset": "UTF-8", "format": "flowed"},
+		},
+		{
+			label:  "with newline and tab",
+			input:  "text/plain; charset=\"UTF-8\"\n\t; format=flowed",
+			mtype:  "text/plain",
+			params: map[string]string{"charset": "UTF-8", "format": "flowed"},
+		},
+		{
+			label:  "with newline and space",
+			input:  "application/pdf; name=foo\n ; format=flowed",
+			mtype:  "application/pdf",
+			params: map[string]string{"name": "foo", "format": "flowed"},
+		},
+		{
+			label:  "with more spaces",
+			input:  "application/pdf; name=foo      ; format=flowed",
+			mtype:  "application/pdf",
+			params: map[string]string{"name": "foo", "format": "flowed"},
+		},
+		{
+			label:  "with more tabs",
+			input:  "application/pdf; name=foo \t\t; format=flowed",
+			mtype:  "application/pdf",
+			params: map[string]string{"name": "foo", "format": "flowed"},
+		},
+		{
+			label:  "with more newlines",
+			input:  "application/pdf; name=foo \n\n; format=flowed",
+			mtype:  "application/pdf",
+			params: map[string]string{"name": "foo", "format": "flowed"},
+		},
 	}
 	for _, tc := range testCases {
 		t.Run(tc.label, func(t *testing.T) {
Repository: jhillyerd/enmime
Pull request #200 (2021-06-30 12:17:57)

Boundary reader - long lines processing fixed
Hi,

when there is a line longer than 4096 bytes, message parsing fails, because boundary reader returns bufio.ErrBufferFull.

This patch handles reading longer lines than 4096 bytes.

jhillyerd: I like the new approach, thanks.

Patch:
diff --git a/boundary.go b/boundary.go
index f2ce8e4..5382db0 100644
--- a/boundary.go
+++ b/boundary.go
@@ -181,10 +181,25 @@ func (b *boundaryReader) Next() (bool, error) {
 		_, _ = io.Copy(ioutil.Discard, b)
 	}
 	for {
-		line, err := b.r.ReadSlice('\n')
-		if err != nil && err != io.EOF {
-			return false, errors.WithStack(err)
+		var line []byte = nil
+		var err error
+		for {
+			// Read whole line, handle extra long lines in cycle
+			var segment []byte
+			segment, err = b.r.ReadSlice('\n')
+			if line == nil {
+				line = segment
+			} else {
+				line = append(line, segment...)
+			}
+
+			if err == nil || err == io.EOF {
+				break
+			} else if err != bufio.ErrBufferFull || len(segment) == 0 {
+				return false, errors.WithStack(err)
+			}
 		}
+
 		if len(line) > 0 && (line[0] == '\r' || line[0] == '\n') {
 			// Blank line
 			continue


Test patch:
diff --git a/boundary_test.go b/boundary_test.go
index 2f7ffe0..84f5af1 100644
--- a/boundary_test.go
+++ b/boundary_test.go
@@ -477,6 +477,24 @@ func TestBoundaryReaderReadErrors(t *testing.T) {
 	}
 }
 
+// TestBoundaryReaderLongLine checks that boundaryReader can read lines longer than the `peekBufferSize`.
+func TestBoundaryReaderLongLine(t *testing.T) {
+	data := bytes.Repeat([]byte{1}, 7*1024)
+	data[6*1024] = '\n'
+
+	br := &boundaryReader{
+		r: bufio.NewReader(bytes.NewReader(data)),
+	}
+
+	next, err := br.Next()
+	if next {
+		t.Fatal("Next() should have returned false, failed")
+	}
+	if err != nil {
+		t.Fatal("Next() should have returned no error, failed")
+	}
+}
+
 // TestReadLenNotCap checks that the `boundaryReader` `io.Reader` implementation fills the provided
 // slice based on its length (as per the `io.Reader` documentation), and not its capacity.
 func TestReadLenNotCap(t *testing.T) {
Repository: jhillyerd/enmime
Pull request #202 (2021-07-17 03:19:56)

mime-dump: Add stack trace for errors
Aids in debugging #185 


Patch:
diff --git a/cmd/mime-dump/mime-dump.go b/cmd/mime-dump/mime-dump.go
index 66e6e5d..6627834 100644
--- a/cmd/mime-dump/mime-dump.go
+++ b/cmd/mime-dump/mime-dump.go
@@ -42,16 +42,16 @@ func (d *dumper) dump(args []string) int {
 		return 1
 	}
 
-	// basename is used as the markdown title
+	// basename is used as the markdown title.
 	basename := filepath.Base(args[1])
 	e, err := enmime.ReadEnvelope(reader)
 	if err != nil {
-		fmt.Fprintln(d.errOut, "During enmime.ReadEnvelope:", err)
+		fmt.Fprintf(d.errOut, "Failed to read envelope:\n%+v", err)
 		return 1
 	}
 
 	if err = cmd.EnvelopeToMarkdown(d.stdOut, e, basename); err != nil {
-		fmt.Fprintln(d.errOut, err)
+		fmt.Fprintf(d.errOut, "Failed to render markdown:\n%+v", err)
 		return 1
 	}
 	return 0


Test patch:
diff --git a/cmd/mime-dump/mime-dump_test.go b/cmd/mime-dump/mime-dump_test.go
index 596cbc0..b547fad 100644
--- a/cmd/mime-dump/mime-dump_test.go
+++ b/cmd/mime-dump/mime-dump_test.go
@@ -50,8 +50,8 @@ func TestFailedToParseFile(t *testing.T) {
 	if exitCode != 1 {
 		t.Fatal("Should have returned an exit code of 1, failed")
 	}
-	if !strings.HasPrefix(b.String(), "During enmime.ReadEnvelope") {
-		t.Fatal("Should have failed to parse file, failed")
+	if !strings.HasPrefix(b.String(), "Failed to read envelope") {
+		t.Fatal("Should have failed to parse file, but couldn't find error message")
 	}
 }