aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/mime/multipart/multipart.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/mime/multipart/multipart.go')
-rw-r--r--libgo/go/mime/multipart/multipart.go18
1 files changed, 14 insertions, 4 deletions
diff --git a/libgo/go/mime/multipart/multipart.go b/libgo/go/mime/multipart/multipart.go
index 6f65a55..3b746a5 100644
--- a/libgo/go/mime/multipart/multipart.go
+++ b/libgo/go/mime/multipart/multipart.go
@@ -25,6 +25,11 @@ import (
var emptyParams = make(map[string]string)
+// This constant needs to be at least 76 for this package to work correctly.
+// This is because \r\n--separator_of_len_70- would fill the buffer and it
+// wouldn't be safe to consume a single byte from it.
+const peekBufferSize = 4096
+
// A Part represents a single part in a multipart body.
type Part struct {
// The headers of the body, if any, with the keys canonicalized
@@ -91,7 +96,7 @@ func (p *Part) parseContentDisposition() {
func NewReader(r io.Reader, boundary string) *Reader {
b := []byte("\r\n--" + boundary + "--")
return &Reader{
- bufReader: bufio.NewReader(r),
+ bufReader: bufio.NewReaderSize(r, peekBufferSize),
nl: b[:2],
nlDashBoundary: b[:len(b)-2],
dashBoundaryDash: b[2:],
@@ -148,7 +153,7 @@ func (pr partReader) Read(d []byte) (n int, err error) {
// the read request. No need to parse more at the moment.
return p.buffer.Read(d)
}
- peek, err := p.mr.bufReader.Peek(4096) // TODO(bradfitz): add buffer size accessor
+ peek, err := p.mr.bufReader.Peek(peekBufferSize) // TODO(bradfitz): add buffer size accessor
// Look for an immediate empty part without a leading \r\n
// before the boundary separator. Some MIME code makes empty
@@ -229,6 +234,7 @@ func (r *Reader) NextPart() (*Part, error) {
expectNewPart := false
for {
line, err := r.bufReader.ReadSlice('\n')
+
if err == io.EOF && r.isFinalBoundary(line) {
// If the buffer ends in "--boundary--" without the
// trailing "\r\n", ReadSlice will return an error
@@ -343,20 +349,24 @@ func (mr *Reader) peekBufferIsEmptyPart(peek []byte) bool {
// peekBufferSeparatorIndex returns the index of mr.nlDashBoundary in
// peek and whether it is a real boundary (and not a prefix of an
// unrelated separator). To be the end, the peek buffer must contain a
-// newline after the boundary.
+// newline after the boundary or contain the ending boundary (--separator--).
func (mr *Reader) peekBufferSeparatorIndex(peek []byte) (idx int, isEnd bool) {
idx = bytes.Index(peek, mr.nlDashBoundary)
if idx == -1 {
return
}
+
peek = peek[idx+len(mr.nlDashBoundary):]
+ if len(peek) == 0 || len(peek) == 1 && peek[0] == '-' {
+ return idx, false
+ }
if len(peek) > 1 && peek[0] == '-' && peek[1] == '-' {
return idx, true
}
peek = skipLWSPChar(peek)
// Don't have a complete line after the peek.
if bytes.IndexByte(peek, '\n') == -1 {
- return -1, false
+ return idx, false
}
if len(peek) > 0 && peek[0] == '\n' {
return idx, true