Browse Source

use readVarInt in header representation decoding

Brad Fitzpatrick 11 years ago
parent
commit
03bb8a45de
1 changed files with 21 additions and 7 deletions
  1. 21 7
      hpack/hpack.go

+ 21 - 7
hpack/hpack.go

@@ -12,6 +12,7 @@ package hpack
 import (
 import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
+	"io"
 )
 )
 
 
 // A DecodingError is something the spec defines as a decoding error.
 // A DecodingError is something the spec defines as a decoding error.
@@ -120,18 +121,21 @@ func (dt *dynamicTable) evict() {
 	}
 	}
 }
 }
 
 
+func (d *Decoder) maxTableIndex() int {
+	return len(d.dynTab.ents) + len(staticTable)
+}
+
 func (d *Decoder) at(i int) (hf HeaderField, ok bool) {
 func (d *Decoder) at(i int) (hf HeaderField, ok bool) {
 	if i < 1 {
 	if i < 1 {
 		return
 		return
 	}
 	}
-	dents := d.dynTab.ents
-	max := len(dents) + len(staticTable)
-	if i > max {
+	if i > d.maxTableIndex() {
 		return
 		return
 	}
 	}
 	if i <= len(staticTable) {
 	if i <= len(staticTable) {
 		return staticTable[i-1], true
 		return staticTable[i-1], true
 	}
 	}
+	dents := d.dynTab.ents
 	return dents[len(dents)-(i-len(staticTable))], true
 	return dents[len(dents)-(i-len(staticTable))], true
 }
 }
 
 
@@ -154,16 +158,26 @@ func (d *Decoder) Decode(p []byte) ([]HeaderField, error) {
 		case p[0]&(1<<7) != 0:
 		case p[0]&(1<<7) != 0:
 			// Indexed representation.
 			// Indexed representation.
 			// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
 			// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
-			idx := p[0] & ((1 << 7) - 1)
-			if idx == 127 {
-				panic("TODO: varuint decoding")
+			idx, size, err := readVarInt(7, p)
+			if err != nil {
+				return nil, err
+			}
+			if size == 0 {
+				// TODO: will later stop processing
+				// here and wait for more (buffering
+				// what we've got), but this is the
+				// all-at-once Decode debug version.
+				return nil, io.ErrUnexpectedEOF
+			}
+			if idx > uint64(d.maxTableIndex()) {
+				return nil, DecodingError{InvalidIndexError(idx)}
 			}
 			}
 			hf, ok := d.at(int(idx))
 			hf, ok := d.at(int(idx))
 			if !ok {
 			if !ok {
 				return nil, DecodingError{InvalidIndexError(idx)}
 				return nil, DecodingError{InvalidIndexError(idx)}
 			}
 			}
 			d.emit(hf, false /* TODO: sensitive ? */)
 			d.emit(hf, false /* TODO: sensitive ? */)
-			p = p[1:]
+			p = p[size:]
 		default:
 		default:
 			panic("TODO")
 			panic("TODO")
 		}
 		}