diff --git a/http3/request.go b/http3/request.go index ce85405c..6105144f 100644 --- a/http3/request.go +++ b/http3/request.go @@ -96,12 +96,13 @@ func requestFromHeaders(headers []qpack.HeaderField) (*http.Request, error) { var contentLength int64 if len(contentLengthStr) > 0 { - cl, err := strconv.ParseInt(contentLengthStr, 10, 64) + // use ParseUint instead of ParseInt, so that parsing fails on negative values + cl, err := strconv.ParseUint(contentLengthStr, 10, 63) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid content length: %w", err) } httpHeaders.Set("Content-Length", contentLengthStr) - contentLength = cl + contentLength = int64(cl) } return &http.Request{ diff --git a/http3/request_test.go b/http3/request_test.go index 57b348c2..0edfa285 100644 --- a/http3/request_test.go +++ b/http3/request_test.go @@ -66,6 +66,18 @@ var _ = Describe("Request", func() { Expect(err).To(MatchError(`invalid header field value for content: "\n"`)) }) + It("rejects negative Content-Length values", func() { + headers := []qpack.HeaderField{ + {Name: ":path", Value: "/foo"}, + {Name: ":authority", Value: "quic.clemente.io"}, + {Name: ":method", Value: "GET"}, + {Name: "content-length", Value: "-42"}, + } + _, err := requestFromHeaders(headers) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("invalid content length")) + }) + It("parses path with leading double slashes", func() { headers := []qpack.HeaderField{ {Name: ":path", Value: "//foo"},