Skip to content

Commit 080c635

Browse files
committed
net/textproto: fix issue of skipspace not returning error
1 parent c7971d0 commit 080c635

File tree

2 files changed

+20
-17
lines changed

2 files changed

+20
-17
lines changed

src/net/textproto/reader.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ import (
1717
// A Reader implements convenience methods for reading requests
1818
// or responses from a text protocol network connection.
1919
type Reader struct {
20-
R *bufio.Reader
21-
dot *dotReader
22-
buf []byte // a re-usable buffer for readContinuedLineSlice
23-
reachEnd bool
20+
R *bufio.Reader
21+
dot *dotReader
22+
buf []byte // a re-usable buffer for readContinuedLineSlice
2423
}
2524

2625
// NewReader returns a new Reader reading from r.
@@ -158,7 +157,15 @@ func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([
158157
r.buf = append(r.buf[:0], trim(line)...)
159158

160159
// Read continuation lines.
161-
for r.skipSpace() > 0 {
160+
for {
161+
n, err := r.skipSpace()
162+
if n == 0 || err != nil {
163+
// Return nil instead of EOF if have non-empty line to return
164+
if err == io.EOF && len(r.buf) > 0 {
165+
err = nil
166+
}
167+
return r.buf, err
168+
}
162169
line, err := r.readLineSlice()
163170
if err != nil {
164171
break
@@ -170,24 +177,21 @@ func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([
170177
}
171178

172179
// skipSpace skips R over all spaces and returns the number of bytes skipped.
173-
func (r *Reader) skipSpace() int {
180+
func (r *Reader) skipSpace() (int, error) {
174181
n := 0
175182
for {
176183
c, err := r.R.ReadByte()
177184
if err != nil {
178-
// Bufio may not keep err until next read.
179-
if err == io.EOF {
180-
r.reachEnd = true
181-
}
182-
break
185+
// Bufio will keep err until next read.
186+
return n, err
183187
}
184188
if c != ' ' && c != '\t' {
185189
r.R.UnreadByte()
186190
break
187191
}
188192
n++
189193
}
190-
return n
194+
return n, nil
191195
}
192196

193197
func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message string, err error) {
@@ -505,7 +509,7 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
505509
return m, ProtocolError("malformed MIME header initial line: " + string(line))
506510
}
507511

508-
for !r.reachEnd {
512+
for {
509513
kv, err := r.readContinuedLineSlice(mustHaveFieldNameColon)
510514
if len(kv) == 0 {
511515
return m, err
@@ -545,8 +549,6 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
545549
return m, err
546550
}
547551
}
548-
549-
return m, io.EOF
550552
}
551553

552554
// noValidation is a no-op validation func for readContinuedLineSlice

src/net/textproto/reader_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,10 @@ func (r *autoRewind) Read(p []byte) (int, error) {
248248

249249
// Test method can be applied on rewind readers. Issue #53858
250250
func TestReadRewindReader(t *testing.T) {
251+
// Sample MIMEHeader string ending with new line
251252
msg1 := "From: Gopher <[email protected]>\r\n" +
252253
"To: Another Gopher <[email protected]>\r\n" +
253-
"Subject: Gophers at Gophercon\r\n"
254+
"Subject: Gophers at Gophercon\r\n\r\n"
254255

255256
r := &autoRewind{
256257
buf: msg1,
@@ -259,7 +260,7 @@ func TestReadRewindReader(t *testing.T) {
259260
tp := NewReader(bufio.NewReader(r))
260261
_, err := tp.ReadMIMEHeader()
261262

262-
if err != io.EOF {
263+
if err != nil {
263264
t.Fatal(err)
264265
}
265266
}

0 commit comments

Comments
 (0)