Skip to content

net/textproto: dont't ignore error in skipSpace function #54281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/net/textproto/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([
r.buf = append(r.buf[:0], trim(line)...)

// Read continuation lines.
for r.skipSpace() > 0 {
for {
n, err := r.skipSpace()
if n == 0 || err != nil {
return r.buf, err
}
line, err := r.readLineSlice()
if err != nil {
break
Expand All @@ -169,21 +173,21 @@ func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([
}

// skipSpace skips R over all spaces and returns the number of bytes skipped.
func (r *Reader) skipSpace() int {
func (r *Reader) skipSpace() (int, error) {
n := 0
for {
c, err := r.R.ReadByte()
if err != nil {
// Bufio will keep err until next read.
break
return n, err
}
if c != ' ' && c != '\t' {
r.R.UnreadByte()
break
}
n++
}
return n
return n, nil
}

func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message string, err error) {
Expand Down
48 changes: 47 additions & 1 deletion src/net/textproto/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestReadContinuedLine(t *testing.T) {
t.Fatalf("Line 2: %s, %v", s, err)
}
s, err = r.ReadContinuedLine()
if s != "line3" || err != nil {
if s != "line3" {
t.Fatalf("Line 3: %s, %v", s, err)
}
s, err = r.ReadContinuedLine()
Expand Down Expand Up @@ -225,6 +225,52 @@ func TestReadMIMEHeaderTrimContinued(t *testing.T) {
}
}

type autoRewind struct {
buf string
r io.Reader
}

func (r *autoRewind) Read(p []byte) (int, error) {
if r.r == nil {
r.r = strings.NewReader(r.buf)
}

n, err := r.r.Read(p)
if err == io.EOF {
// rewind
r.r = strings.NewReader(r.buf)
}

return n, err
}

// Special io reader that does not hold errors. Issue 53858
func TestReadMimeHeaderRewind(t *testing.T) {
// Improper message, expect EOF as error
r := &autoRewind{
buf: "From: Gopher <[email protected]>\n" +
"To: Another Gopher <[email protected]>\n",
}

tp := NewReader(bufio.NewReader(r))
_, err := tp.ReadMIMEHeader()
if err != io.EOF {
t.Fatalf("ReadMIMEHeaderRewind mismatch.\n got: %v\nwant: EOF", err)
}

// Proper message, expect nil as err
r = &autoRewind{
buf: "From: Gopher <[email protected]>\r\n" +
"To: Another Gopher <[email protected]>\r\n" +
"\r\n",
}
tp = NewReader(bufio.NewReader(r))
_, err = tp.ReadMIMEHeader()
if err != nil {
t.Fatalf("ReadMIMEHeaderRewind mismatch.\n got: %v\nwant: nil", err)
}
}

type readResponseTest struct {
in string
inCode int
Expand Down