Browse Source

net/spdy: handle corrupted zlib data on read

R=mikioh.mikioh
CC=golang-dev, rsc
https://golang.org/cl/6786055
Jeff Hodges 13 years ago
parent
commit
06fe5ee616
2 changed files with 39 additions and 3 deletions
  1. 12 3
      spdy/read.go
  2. 27 0
      spdy/spdy_test.go

+ 12 - 3
spdy/read.go

@@ -200,7 +200,10 @@ func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame)
 
 	reader := f.r
 	if !f.headerCompressionDisabled {
-		f.uncorkHeaderDecompressor(int64(h.length - 10))
+		err := f.uncorkHeaderDecompressor(int64(h.length - 10))
+		if err != nil {
+			return err
+		}
 		reader = f.headerDecompressor
 	}
 
@@ -234,7 +237,10 @@ func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) e
 	}
 	reader := f.r
 	if !f.headerCompressionDisabled {
-		f.uncorkHeaderDecompressor(int64(h.length - 6))
+		err := f.uncorkHeaderDecompressor(int64(h.length - 6))
+		if err != nil {
+			return err
+		}
 		reader = f.headerDecompressor
 	}
 	frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
@@ -267,7 +273,10 @@ func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) err
 	}
 	reader := f.r
 	if !f.headerCompressionDisabled {
-		f.uncorkHeaderDecompressor(int64(h.length - 6))
+		err := f.uncorkHeaderDecompressor(int64(h.length - 6))
+		if err != nil {
+			return err
+		}
 		reader = f.headerDecompressor
 	}
 	frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)

+ 27 - 0
spdy/spdy_test.go

@@ -6,6 +6,8 @@ package spdy
 
 import (
 	"bytes"
+	"compress/zlib"
+	"encoding/base64"
 	"io"
 	"net/http"
 	"reflect"
@@ -495,3 +497,28 @@ func TestMultipleSPDYFrames(t *testing.T) {
 		t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
 	}
 }
+
+func TestReadMalformedZlibHeader(t *testing.T) {
+	// These were constructed by corrupting the first byte of the zlib
+	// header after writing.
+	malformedStructs := map[string]string{
+		"SynStreamFrame": "gAIAAQAAABgAAAACAAAAAAAAF/nfolGyYmAAAAAA//8=",
+		"SynReplyFrame":  "gAIAAgAAABQAAAACAAAX+d+iUbJiYAAAAAD//w==",
+		"HeadersFrame":   "gAIACAAAABQAAAACAAAX+d+iUbJiYAAAAAD//w==",
+	}
+	for name, bad := range malformedStructs {
+		b, err := base64.StdEncoding.DecodeString(bad)
+		if err != nil {
+			t.Errorf("Unable to decode base64 encoded frame %s: %v", name, err)
+		}
+		buf := bytes.NewBuffer(b)
+		reader, err := NewFramer(buf, buf)
+		if err != nil {
+			t.Fatalf("NewFramer: %v", err)
+		}
+		_, err = reader.ReadFrame()
+		if err != zlib.ErrHeader {
+			t.Errorf("Frame %s, expected: %#v, actual: %#v", name, zlib.ErrHeader, err)
+		}
+	}
+}