Skip to content

Commit 58da30b

Browse files
neildrickystewart
authored andcommitted
[release-branch.go1.24] net/mail: avoid quadratic behavior in mail address parsing
RFC 5322 domain-literal parsing built the dtext value one character at a time with string concatenation, resulting in excessive resource consumption when parsing very large domain-literal values. Replace with a subslice. Benchmark not included in this CL because it's too narrow to be of general ongoing use, but for: ParseAddress("alice@[" + strings.Repeat("a", 0x40000) + "]") goos: darwin goarch: arm64 pkg: net/mail cpu: Apple M4 Pro │ /tmp/bench.0 │ /tmp/bench.1 │ │ sec/op │ sec/op vs base │ ParseAddress-14 1987.732m ± 9% 1.524m ± 5% -99.92% (p=0.000 n=10) │ /tmp/bench.0 │ /tmp/bench.1 │ │ B/op │ B/op vs base │ ParseAddress-14 33692.767Mi ± 0% 1.282Mi ± 0% -100.00% (p=0.000 n=10) │ /tmp/bench.0 │ /tmp/bench.1 │ │ allocs/op │ allocs/op vs base │ ParseAddress-14 263711.00 ± 0% 17.00 ± 0% -99.99% (p=0.000 n=10) Thanks to Philippe Antoine (Catena cyber) for reporting this issue. Fixes CVE-2025-61725 For golang#75680 Fixes golang#75700 Change-Id: Id971c2d5b59882bb476e22fceb7e01ec08234bb7 Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2840 Reviewed-by: Roland Shoemaker <[email protected]> Reviewed-by: Nicholas Husin <[email protected]> Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2962 Reviewed-by: Damien Neil <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/709835 Auto-Submit: Michael Pratt <[email protected]> TryBot-Bypass: Michael Pratt <[email protected]> Reviewed-by: Carlos Amedee <[email protected]>
1 parent 50c70e4 commit 58da30b

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

src/net/mail/message.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,8 @@ func (p *addrParser) consumeDomainLiteral() (string, error) {
725725
}
726726

727727
// Parse the dtext
728-
var dtext string
728+
dtext := p.s
729+
dtextLen := 0
729730
for {
730731
if p.empty() {
731732
return "", errors.New("mail: unclosed domain-literal")
@@ -742,9 +743,10 @@ func (p *addrParser) consumeDomainLiteral() (string, error) {
742743
return "", fmt.Errorf("mail: bad character in domain-literal: %q", r)
743744
}
744745

745-
dtext += p.s[:size]
746+
dtextLen += size
746747
p.s = p.s[size:]
747748
}
749+
dtext = dtext[:dtextLen]
748750

749751
// Skip the trailing ]
750752
if !p.consume(']') {

0 commit comments

Comments
 (0)