mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net/textproto: avoid quadratic complexity in Reader.ReadResponse
Reader.ReadResponse constructed a response string from repeated string concatenation, permitting a malicious sender to cause excessive memory allocation and CPU consumption by sending a response consisting of many short lines. Use a strings.Builder to construct the string instead. Thanks to Jakub Ciolek for reporting this issue. Fixes CVE-2025-61724 Fixes #75716 Change-Id: I1a98ce85a21b830cb25799f9ac9333a67400d736 Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2940 Reviewed-by: Roland Shoemaker <bracewell@google.com> Reviewed-by: Nicholas Husin <husin@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/709859 TryBot-Bypass: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Pratt <mpratt@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
parent
5ce8cd16f3
commit
5ede095649
1 changed files with 8 additions and 3 deletions
|
|
@ -285,8 +285,10 @@ func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err err
|
||||||
//
|
//
|
||||||
// An expectCode <= 0 disables the check of the status code.
|
// An expectCode <= 0 disables the check of the status code.
|
||||||
func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error) {
|
func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error) {
|
||||||
code, continued, message, err := r.readCodeLine(expectCode)
|
code, continued, first, err := r.readCodeLine(expectCode)
|
||||||
multi := continued
|
multi := continued
|
||||||
|
var messageBuilder strings.Builder
|
||||||
|
messageBuilder.WriteString(first)
|
||||||
for continued {
|
for continued {
|
||||||
line, err := r.ReadLine()
|
line, err := r.ReadLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -297,12 +299,15 @@ func (r *Reader) ReadResponse(expectCode int) (code int, message string, err err
|
||||||
var moreMessage string
|
var moreMessage string
|
||||||
code2, continued, moreMessage, err = parseCodeLine(line, 0)
|
code2, continued, moreMessage, err = parseCodeLine(line, 0)
|
||||||
if err != nil || code2 != code {
|
if err != nil || code2 != code {
|
||||||
message += "\n" + strings.TrimRight(line, "\r\n")
|
messageBuilder.WriteByte('\n')
|
||||||
|
messageBuilder.WriteString(strings.TrimRight(line, "\r\n"))
|
||||||
continued = true
|
continued = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
message += "\n" + moreMessage
|
messageBuilder.WriteByte('\n')
|
||||||
|
messageBuilder.WriteString(moreMessage)
|
||||||
}
|
}
|
||||||
|
message = messageBuilder.String()
|
||||||
if err != nil && multi && message != "" {
|
if err != nil && multi && message != "" {
|
||||||
// replace one line error message with all lines (full message)
|
// replace one line error message with all lines (full message)
|
||||||
err = &Error{code, message}
|
err = &Error{code, message}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue