diff --git a/gzip/gunzip.go b/gzip/gunzip.go index dc2362a63b..00a0a2c386 100644 --- a/gzip/gunzip.go +++ b/gzip/gunzip.go @@ -238,6 +238,11 @@ func (z *Reader) readHeader() (hdr Header, err error) { } } + // Reserved FLG bits must be zero. + if flg>>5 != 0 { + return hdr, ErrHeader + } + z.digest = 0 if z.decompressor == nil { z.decompressor = flate.NewReader(z.r) diff --git a/gzip/gunzip_test.go b/gzip/gunzip_test.go index 399149a4b4..997bc77bea 100644 --- a/gzip/gunzip_test.go +++ b/gzip/gunzip_test.go @@ -9,6 +9,7 @@ import ( "bytes" oldgz "compress/gzip" "crypto/rand" + "errors" "io" "os" "strings" @@ -408,11 +409,14 @@ func TestDecompressor(t *testing.T) { } func TestIssue6550(t *testing.T) { - f, err := os.Open("testdata/issue6550.gz") + b, err := os.ReadFile("testdata/issue6550.gz") if err != nil { t.Fatal(err) } - gzip, err := NewReader(f) + // issue6550.gz has invalid flag bit set. + // TestReservedBits tests that. Fix it up for this test. + b[3] &= 0x1f + gzip, err := NewReader(bytes.NewReader(b)) if err != nil { t.Fatalf("NewReader(testdata/issue6550.gz): %v", err) } @@ -435,6 +439,21 @@ func TestIssue6550(t *testing.T) { } } +func TestReservedBits(t *testing.T) { + f, err := os.Open("testdata/issue6550.gz") + if err != nil { + t.Fatal(err) + } + defer f.Close() + _, err = NewReader(f) + if err == nil { + t.Fatalf("Reserved bits did not result in error") + } + if !errors.Is(err, ErrHeader) { + t.Fatal("Expected ErrHeader, got", err) + } +} + func TestInitialReset(t *testing.T) { var r Reader if err := r.Reset(bytes.NewReader(gunzipTests[1].gzip)); err != nil {