@@ -25,6 +25,11 @@ import (
25
25
26
26
var emptyParams = make (map [string ]string )
27
27
28
+ // This constant needs to be at least 76 for this package to work correctly.
29
+ // This is because \r\n--separator_of_len_70- would fill the buffer and it
30
+ // wouldn't be safe to consume a single byte from it.
31
+ const peekBufferSize = 4096
32
+
28
33
// A Part represents a single part in a multipart body.
29
34
type Part struct {
30
35
// The headers of the body, if any, with the keys canonicalized
@@ -91,7 +96,7 @@ func (p *Part) parseContentDisposition() {
91
96
func NewReader (r io.Reader , boundary string ) * Reader {
92
97
b := []byte ("\r \n --" + boundary + "--" )
93
98
return & Reader {
94
- bufReader : bufio .NewReader ( r ),
99
+ bufReader : bufio .NewReaderSize ( r , peekBufferSize ),
95
100
nl : b [:2 ],
96
101
nlDashBoundary : b [:len (b )- 2 ],
97
102
dashBoundaryDash : b [2 :],
@@ -148,7 +153,7 @@ func (pr partReader) Read(d []byte) (n int, err error) {
148
153
// the read request. No need to parse more at the moment.
149
154
return p .buffer .Read (d )
150
155
}
151
- peek , err := p .mr .bufReader .Peek (4096 ) // TODO(bradfitz): add buffer size accessor
156
+ peek , err := p .mr .bufReader .Peek (peekBufferSize ) // TODO(bradfitz): add buffer size accessor
152
157
153
158
// Look for an immediate empty part without a leading \r\n
154
159
// before the boundary separator. Some MIME code makes empty
@@ -229,6 +234,7 @@ func (r *Reader) NextPart() (*Part, error) {
229
234
expectNewPart := false
230
235
for {
231
236
line , err := r .bufReader .ReadSlice ('\n' )
237
+
232
238
if err == io .EOF && r .isFinalBoundary (line ) {
233
239
// If the buffer ends in "--boundary--" without the
234
240
// trailing "\r\n", ReadSlice will return an error
@@ -343,13 +349,17 @@ func (mr *Reader) peekBufferIsEmptyPart(peek []byte) bool {
343
349
// peekBufferSeparatorIndex returns the index of mr.nlDashBoundary in
344
350
// peek and whether it is a real boundary (and not a prefix of an
345
351
// unrelated separator). To be the end, the peek buffer must contain a
346
- // newline after the boundary.
352
+ // newline after the boundary or contain the ending boundary (--separator--) .
347
353
func (mr * Reader ) peekBufferSeparatorIndex (peek []byte ) (idx int , isEnd bool ) {
348
354
idx = bytes .Index (peek , mr .nlDashBoundary )
349
355
if idx == - 1 {
350
356
return
351
357
}
358
+
352
359
peek = peek [idx + len (mr .nlDashBoundary ):]
360
+ if len (peek ) == 0 || len (peek ) == 1 && peek [0 ] == '-' {
361
+ return idx , false
362
+ }
353
363
if len (peek ) > 1 && peek [0 ] == '-' && peek [1 ] == '-' {
354
364
return idx , true
355
365
}
0 commit comments