]> Cypherpunks repositories - gostls13.git/commitdiff
mime/multipart: limit line length to prevent abuse
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 21 Apr 2011 17:45:49 +0000 (10:45 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 21 Apr 2011 17:45:49 +0000 (10:45 -0700)
Fixes #1528

R=rsc
CC=golang-dev
https://golang.org/cl/4425060

src/pkg/mime/multipart/multipart.go
src/pkg/mime/multipart/multipart_test.go

index 0a65a447db999ec90527b56b17de7990f960d02e..22576cff462f08de0f54a2c3c03312cf73343e91 100644 (file)
@@ -97,10 +97,11 @@ func newPart(mr *multiReader) (bp *Part, err os.Error) {
 
 func (bp *Part) populateHeaders() os.Error {
        for {
-               line, err := bp.mr.bufReader.ReadString('\n')
+               lineBytes, err := bp.mr.bufReader.ReadSlice('\n')
                if err != nil {
                        return err
                }
+               line := string(lineBytes)
                if line == "\n" || line == "\r\n" {
                        return nil
                }
@@ -179,11 +180,12 @@ func (mr *multiReader) eof() bool {
 }
 
 func (mr *multiReader) readLine() bool {
-       line, err := mr.bufReader.ReadString('\n')
+       lineBytes, err := mr.bufReader.ReadSlice('\n')
        if err != nil {
                // TODO: care about err being EOF or not?
                return false
        }
+       line := string(lineBytes)
        mr.bufferedLine = &line
        return true
 }
index 1f3d32d7ed6e91bd20698e21fac4b8b3a7988ae4..f8f10f3e162b2448df0a2db1d2082d97978836eb 100644 (file)
@@ -9,6 +9,7 @@ import (
        "fmt"
        "io"
        "json"
+       "os"
        "regexp"
        "strings"
        "testing"
@@ -205,3 +206,34 @@ func TestVariousTextLineEndings(t *testing.T) {
 
        }
 }
+
+type maliciousReader struct {
+       t *testing.T
+       n int
+}
+
+const maxReadThreshold = 1 << 20
+
+func (mr *maliciousReader) Read(b []byte) (n int, err os.Error) {
+       mr.n += len(b)
+       if mr.n >= maxReadThreshold {
+               mr.t.Fatal("too much was read")
+               return 0, os.EOF
+       }
+       return len(b), nil
+}
+
+func TestLineLimit(t *testing.T) {
+       mr := &maliciousReader{t: t}
+       r := NewReader(mr, "fooBoundary")
+       part, err := r.NextPart()
+       if part != nil {
+               t.Errorf("unexpected part read")
+       }
+       if err == nil {
+               t.Errorf("expected an error")
+       }
+       if mr.n >= maxReadThreshold {
+               t.Errorf("expected to read < %d bytes; read %d", maxReadThreshold, mr.n)
+       }
+}