diff --git a/src/pkg/compress/flate/inflate.go b/src/pkg/compress/flate/inflate.go
index a4be91b6f78821ceed1ebf2d49f219de38b44e31..92670126e6fd67df887479a8ea83d2681786c5b5 100644
--- a/src/pkg/compress/flate/inflate.go
+++ b/src/pkg/compress/flate/inflate.go
@@ -16,9 +16,10 @@ import (
 const (
 	maxCodeLen = 16    // max length of Huffman code
 	maxHist    = 32768 // max history required
-	maxLit     = 286
-	maxDist    = 32
-	numCodes   = 19 // number of codes in Huffman meta-code
+	// The next three numbers come from the RFC, section 3.2.7.
+	maxLit   = 286
+	maxDist  = 32
+	numCodes = 19 // number of codes in Huffman meta-code
 )
 
 // A CorruptInputError reports the presence of corrupt input at a given offset.
@@ -306,10 +307,15 @@ func (f *decompressor) readHuffman() error {
 		}
 	}
 	nlit := int(f.b&0x1F) + 257
+	if nlit > maxLit {
+		return CorruptInputError(f.roffset)
+	}
 	f.b >>= 5
 	ndist := int(f.b&0x1F) + 1
+	// maxDist is 32, so ndist is always valid.
 	f.b >>= 5
 	nclen := int(f.b&0xF) + 4
+	// numCodes is 19, so nclen is always valid.
 	f.b >>= 4
 	f.nb -= 5 + 5 + 4
 
diff --git a/src/pkg/compress/flate/reader_test.go b/src/pkg/compress/flate/reader_test.go
index 84cc953ee36fa652ee8f2009c8b44835e26c9af8..54ed788dbd3e50f3a13fbc353ca66dbc2ba8ffe7 100644
--- a/src/pkg/compress/flate/reader_test.go
+++ b/src/pkg/compress/flate/reader_test.go
@@ -9,9 +9,19 @@ import (
 	"io"
 	"io/ioutil"
 	"runtime"
+	"strings"
 	"testing"
 )
 
+func TestNlitOutOfRange(t *testing.T) {
+	// Trying to decode this bogus flate data, which has a Huffman table
+	// with nlit=288, should not panic.
+	io.Copy(ioutil.Discard, NewReader(strings.NewReader(
+		"\xfc\xfe\x36\xe7\x5e\x1c\xef\xb3\x55\x58\x77\xb6\x56\xb5\x43\xf4"+
+			"\x6f\xf2\xd2\xe6\x3d\x99\xa0\x85\x8c\x48\xeb\xf8\xda\x83\x04\x2a"+
+			"\x75\xc4\xf8\x0f\x12\x11\xb9\xb4\x4b\x09\xa0\xbe\x8b\x91\x4c")))
+}
+
 const (
 	digits = iota
 	twain