mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
net/mail: fix quadratic consumePhrase behavior
Updates #78987 Fixes CVE-2026-42499 Change-Id: I8438e5dee7e6433573d4161baf8fb2151e7fbc2f Reviewed-on: https://go-review.googlesource.com/c/go/+/771520 Reviewed-by: Nicholas Husin <husin@google.com> Reviewed-by: Nicholas Husin <nsh@golang.org> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
a3f569adee
commit
2c59389fcc
2 changed files with 28 additions and 6 deletions
|
|
@ -575,8 +575,10 @@ func (p *addrParser) consumeAddrSpec() (spec string, err error) {
|
|||
func (p *addrParser) consumePhrase() (phrase string, err error) {
|
||||
debug.Printf("consumePhrase: [%s]", p.s)
|
||||
// phrase = 1*word
|
||||
var words []string
|
||||
var isPrevEncoded bool
|
||||
var (
|
||||
words []string
|
||||
sb strings.Builder
|
||||
)
|
||||
for {
|
||||
// obs-phrase allows CFWS after one word
|
||||
if len(words) > 0 {
|
||||
|
|
@ -608,13 +610,22 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
|
|||
break
|
||||
}
|
||||
debug.Printf("consumePhrase: consumed %q", word)
|
||||
if isPrevEncoded && isEncoded {
|
||||
words[len(words)-1] += word
|
||||
} else {
|
||||
switch {
|
||||
case isEncoded:
|
||||
sb.WriteString(word)
|
||||
case !isEncoded && sb.Len() > 0:
|
||||
words = append(words, sb.String())
|
||||
sb.Reset()
|
||||
words = append(words, word)
|
||||
default:
|
||||
words = append(words, word)
|
||||
}
|
||||
isPrevEncoded = isEncoded
|
||||
}
|
||||
|
||||
if sb.Len() > 0 {
|
||||
words = append(words, sb.String())
|
||||
}
|
||||
|
||||
// Ignore any error if we got at least one word.
|
||||
if err != nil && len(words) == 0 {
|
||||
debug.Printf("consumePhrase: hit err: %v", err)
|
||||
|
|
|
|||
|
|
@ -1262,6 +1262,17 @@ func TestEmptyAddress(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkConsumePhrase(b *testing.B) {
|
||||
for _, n := range []int{10, 100, 1000, 10000} {
|
||||
b.Run(fmt.Sprintf("words-%d", n), func(b *testing.B) {
|
||||
input := strings.Repeat("=?utf-8?q?hello?= ", n) + "<user@example.com>"
|
||||
for b.Loop() {
|
||||
(&addrParser{s: input}).consumePhrase()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkConsumeComment(b *testing.B) {
|
||||
for _, n := range []int{10, 100, 1000, 10000} {
|
||||
b.Run(fmt.Sprintf("depth-%d", n), func(b *testing.B) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue