diff --git a/src/net/mail/message.go b/src/net/mail/message.go index 1502b3596252ba..fbf1fca68f5e68 100644 --- a/src/net/mail/message.go +++ b/src/net/mail/message.go @@ -832,7 +832,7 @@ func (p *addrParser) consumeComment() (string, bool) { // '(' already consumed. depth := 1 - var comment string + var comment strings.Builder for { if p.empty() || depth == 0 { break @@ -846,12 +846,12 @@ func (p *addrParser) consumeComment() (string, bool) { depth-- } if depth > 0 { - comment += p.s[:1] + comment.WriteByte(p.s[0]) } p.s = p.s[1:] } - return comment, depth == 0 + return comment.String(), depth == 0 } func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) { diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go index dad9c367f3e451..3393b03af54bf2 100644 --- a/src/net/mail/message_test.go +++ b/src/net/mail/message_test.go @@ -6,6 +6,7 @@ package mail import ( "bytes" + "fmt" "io" "mime" "reflect" @@ -1260,3 +1261,21 @@ func TestEmptyAddress(t *testing.T) { t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err) } } + +func BenchmarkConsumeComment(b *testing.B) { + for _, n := range []int{10, 100, 1000, 10000} { + b.Run(fmt.Sprintf("depth-%d", n), func(b *testing.B) { + // Build a deeply nested comment: (((...a...))) + open := strings.Repeat("(", n) + close := strings.Repeat(")", n) + // consumeComment expects the leading '(' already consumed, + // so we start with one fewer opening paren and the parser + // will handle nesting from there. + input := open[:n-1] + "a" + close + for b.Loop() { + p := addrParser{s: input} + p.consumeComment() + } + }) + } +}