Commit 5d92aefc authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

vendor, net/http: update vendored hpack

Updates x/net/http2/hpack to rev 6050c111 for:

   http2/hpack: forbid excess and invalid padding in hpack decoder
   https://golang.org/cl/23067

Updates #15614

Change-Id: I3fbf9b265bfa5e49e6aa97d8c34e08214cfcc49a
Reviewed-on: https://go-review.googlesource.com/23208Reviewed-by: default avatarCarl Mastrangelo <notcarl@google.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1119af89
...@@ -524,6 +524,47 @@ func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) { ...@@ -524,6 +524,47 @@ func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) {
} }
} }
func TestHuffmanDecodeExcessPadding(t *testing.T) {
tests := [][]byte{
{0xff}, // Padding Exceeds 7 bits
{0x1f, 0xff}, // {"a", 1 byte excess padding}
{0x1f, 0xff, 0xff}, // {"a", 2 byte excess padding}
{0x1f, 0xff, 0xff, 0xff}, // {"a", 3 byte excess padding}
{0xff, 0x9f, 0xff, 0xff, 0xff}, // {"a", 29 bit excess padding}
{'R', 0xbc, '0', 0xff, 0xff, 0xff, 0xff}, // Padding ends on partial symbol.
}
for i, in := range tests {
var buf bytes.Buffer
if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
t.Errorf("test-%d: decode(%q) = %v; want ErrInvalidHuffman", i, in, err)
}
}
}
func TestHuffmanDecodeEOS(t *testing.T) {
in := []byte{0xff, 0xff, 0xff, 0xff, 0xfc} // {EOS, "?"}
var buf bytes.Buffer
if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
t.Errorf("error = %v; want ErrInvalidHuffman", err)
}
}
func TestHuffmanDecodeMaxLengthOnTrailingByte(t *testing.T) {
in := []byte{0x00, 0x01} // {"0", "0", "0"}
var buf bytes.Buffer
if err := huffmanDecode(&buf, 2, in); err != ErrStringLength {
t.Errorf("error = %v; want ErrStringLength", err)
}
}
func TestHuffmanDecodeCorruptPadding(t *testing.T) {
in := []byte{0x00}
var buf bytes.Buffer
if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
t.Errorf("error = %v; want ErrInvalidHuffman", err)
}
}
func TestHuffmanDecode(t *testing.T) { func TestHuffmanDecode(t *testing.T) {
tests := []struct { tests := []struct {
inHex, want string inHex, want string
......
...@@ -48,12 +48,16 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") ...@@ -48,12 +48,16 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
// maxLen bytes will return ErrStringLength. // maxLen bytes will return ErrStringLength.
func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
n := rootHuffmanNode n := rootHuffmanNode
cur, nbits := uint(0), uint8(0) // cur is the bit buffer that has not been fed into n.
// cbits is the number of low order bits in cur that are valid.
// sbits is the number of bits of the symbol prefix being decoded.
cur, cbits, sbits := uint(0), uint8(0), uint8(0)
for _, b := range v { for _, b := range v {
cur = cur<<8 | uint(b) cur = cur<<8 | uint(b)
nbits += 8 cbits += 8
for nbits >= 8 { sbits += 8
idx := byte(cur >> (nbits - 8)) for cbits >= 8 {
idx := byte(cur >> (cbits - 8))
n = n.children[idx] n = n.children[idx]
if n == nil { if n == nil {
return ErrInvalidHuffman return ErrInvalidHuffman
...@@ -63,22 +67,40 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { ...@@ -63,22 +67,40 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
return ErrStringLength return ErrStringLength
} }
buf.WriteByte(n.sym) buf.WriteByte(n.sym)
nbits -= n.codeLen cbits -= n.codeLen
n = rootHuffmanNode n = rootHuffmanNode
sbits = cbits
} else { } else {
nbits -= 8 cbits -= 8
} }
} }
} }
for nbits > 0 { for cbits > 0 {
n = n.children[byte(cur<<(8-nbits))] n = n.children[byte(cur<<(8-cbits))]
if n.children != nil || n.codeLen > nbits { if n == nil {
return ErrInvalidHuffman
}
if n.children != nil || n.codeLen > cbits {
break break
} }
if maxLen != 0 && buf.Len() == maxLen {
return ErrStringLength
}
buf.WriteByte(n.sym) buf.WriteByte(n.sym)
nbits -= n.codeLen cbits -= n.codeLen
n = rootHuffmanNode n = rootHuffmanNode
sbits = cbits
}
if sbits > 7 {
// Either there was an incomplete symbol, or overlong padding.
// Both are decoding errors per RFC 7541 section 5.2.
return ErrInvalidHuffman
} }
if mask := uint(1<<cbits - 1); cur&mask != mask {
// Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
return ErrInvalidHuffman
}
return nil return nil
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment