]> Cypherpunks repositories - gostls13.git/commitdiff
textproto: prevent long lines in HTTP headers from causing HTTP 400 responses.
authorMike Solomon <msolo@gmail.com>
Tue, 1 Nov 2011 17:31:29 +0000 (10:31 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 1 Nov 2011 17:31:29 +0000 (10:31 -0700)
This fixes the issue without an extra copy in the average case.

R=golang-dev, ality, bradfitz
CC=golang-dev
https://golang.org/cl/5272049

src/pkg/net/textproto/reader.go
src/pkg/net/textproto/reader_test.go

index ece9a99ffbb0012d685361c65d13d8e37614eb18..98b39276b8a9ef0ea45e979c1aad780ed6b14c19 100644 (file)
@@ -50,8 +50,22 @@ func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
 
 func (r *Reader) readLineSlice() ([]byte, os.Error) {
        r.closeDot()
-       line, _, err := r.R.ReadLine()
-       return line, err
+       var line []byte
+       for {
+               l, more, err := r.R.ReadLine()
+               if err != nil {
+                       return nil, err
+               }
+               // Avoid the copy if the first call produced a full line.
+               if line == nil && !more {
+                       return l, nil
+               }
+               line = append(line, l...)
+               if !more {
+                       break
+               }
+       }
+       return line, nil
 }
 
 // ReadContinuedLine reads a possibly continued line from r,
index 23ebc3f61e87e10f371a1eeae58ddc2ad0725443..a087e29d914515db776f36b753ef91a3630d5c45 100644 (file)
@@ -139,6 +139,23 @@ func TestReadMIMEHeader(t *testing.T) {
        }
 }
 
+func TestLargeReadMIMEHeader(t *testing.T) {
+       data := make([]byte, 16*1024)
+       for i := 0; i < len(data); i++ {
+               data[i] = 'x'
+       }
+       sdata := string(data)
+       r := reader("Cookie: " + sdata + "\r\n\n")
+       m, err := r.ReadMIMEHeader()
+       if err != nil {
+               t.Fatalf("ReadMIMEHeader: %v", err)
+       }
+       cookie := m.Get("Cookie")
+       if cookie != sdata {
+               t.Fatalf("ReadMIMEHeader: %v bytes, want %v bytes", len(cookie), len(sdata))
+       }
+}
+
 type readResponseTest struct {
        in       string
        inCode   int