aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-01-24 16:33:47 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-01-25 20:46:45 +0000
commit3caf4e05cf337fa9b395dd887aa3e8d2e26eecdf (patch)
treeffb58213405bfc6576f19938060184d0b279efe4 /src/net/http
parent801bebefa91205b0b69f2458701aac8169294884 (diff)
downloadgo-3caf4e05cf337fa9b395dd887aa3e8d2e26eecdf.tar.xz
net/http: check max size of HTTP chunks
Thanks to Régis Leroy for noticing. Change-Id: I5ca2402efddab4e63d884a9d315fc1394e514cb7 Reviewed-on: https://go-review.googlesource.com/18871 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/internal/chunked.go7
-rw-r--r--src/net/http/internal/chunked_test.go38
2 files changed, 32 insertions, 13 deletions
diff --git a/src/net/http/internal/chunked.go b/src/net/http/internal/chunked.go
index 3967ad614f..2e62c00d5d 100644
--- a/src/net/http/internal/chunked.go
+++ b/src/net/http/internal/chunked.go
@@ -220,8 +220,7 @@ type FlushAfterChunkWriter struct {
}
func parseHexUint(v []byte) (n uint64, err error) {
- for _, b := range v {
- n <<= 4
+ for i, b := range v {
switch {
case '0' <= b && b <= '9':
b = b - '0'
@@ -232,6 +231,10 @@ func parseHexUint(v []byte) (n uint64, err error) {
default:
return 0, errors.New("invalid byte in chunk length")
}
+ if i == 16 {
+ return 0, errors.New("http chunk length too large")
+ }
+ n <<= 4
n |= uint64(b)
}
return
diff --git a/src/net/http/internal/chunked_test.go b/src/net/http/internal/chunked_test.go
index 7c1c91662f..a136dc99a6 100644
--- a/src/net/http/internal/chunked_test.go
+++ b/src/net/http/internal/chunked_test.go
@@ -139,19 +139,35 @@ func TestChunkReaderAllocs(t *testing.T) {
}
func TestParseHexUint(t *testing.T) {
+ type testCase struct {
+ in string
+ want uint64
+ wantErr string
+ }
+ tests := []testCase{
+ {"x", 0, "invalid byte in chunk length"},
+ {"0000000000000000", 0, ""},
+ {"0000000000000001", 1, ""},
+ {"ffffffffffffffff", 1<<64 - 1, ""},
+ {"000000000000bogus", 0, "invalid byte in chunk length"},
+ {"00000000000000000", 0, "http chunk length too large"}, // could accept if we wanted
+ {"10000000000000000", 0, "http chunk length too large"},
+ {"00000000000000001", 0, "http chunk length too large"}, // could accept if we wanted
+ }
for i := uint64(0); i <= 1234; i++ {
- line := []byte(fmt.Sprintf("%x", i))
- got, err := parseHexUint(line)
- if err != nil {
- t.Fatalf("on %d: %v", i, err)
- }
- if got != i {
- t.Errorf("for input %q = %d; want %d", line, got, i)
- }
+ tests = append(tests, testCase{in: fmt.Sprintf("%x", i), want: i})
}
- _, err := parseHexUint([]byte("bogus"))
- if err == nil {
- t.Error("expected error on bogus input")
+ for _, tt := range tests {
+ got, err := parseHexUint([]byte(tt.in))
+ if tt.wantErr != "" {
+ if !strings.Contains(fmt.Sprint(err), tt.wantErr) {
+ t.Errorf("parseHexUint(%q) = %v, %v; want error %q", tt.in, got, err, tt.wantErr)
+ }
+ } else {
+ if err != nil || got != tt.want {
+ t.Errorf("parseHexUint(%q) = %v, %v; want %v", tt.in, got, err, tt.want)
+ }
+ }
}
}