brotli icon indicating copy to clipboard operation
brotli copied to clipboard

First reading empty compressed data doesnt return io.EOF

Open newacorn opened this issue 1 year ago • 1 comments

Description

The gzip package and strings.NewReader always return io.EOF when calling their Read methods with any size slice if the data is empty. However, the brotli Read method requires using a non-empty slice to read first for empty compressed data, and only subsequent reads can return io.EOF. If you continuously use an empty slice to read, io.EOF is never returned, potentially causing an infinite loop in certain scenarios.

Test

brotil first read never io.EOF for empty compressed data.

func TestBrotliReaderEmptyData(t *testing.T) {
	readPLen := [][]int{{0, 1, 0, 2, 4}, {2, 3, 0, 4}}
	for _, pLen := range readPLen {
		tmp := pLen
		t.Run("read p len order: "+fmt.Sprintf("%v", pLen), func(t *testing.T) {
			buf := bytes.Buffer{}
			w := brotli.NewWriterV2(&buf, 4)
			err := w.Close()
			if err != nil {
				t.Fatal(err)
			}
			r := brotli.NewReader(&buf)
			for _, l1 := range tmp {
				p := make([]byte, l1)
				n1, err1 := r.Read(p)
				if n1 != 0 {
					t.Fatalf("expected %d but got %d", 0, n1)
				}
				if err1 != io.EOF {
					t.Fatal(err1)
				}
			}
		})

	}
}

Gzip success with any order.

func TestGzipReaderEmptyData(t *testing.T) {
	readPLen := [][]int{{0, 1, 0, 2, 4}, {2, 3, 0, 4}}
	for _, pLen := range readPLen {
		tmp := pLen
		t.Run("read p len order: "+fmt.Sprintf("%v", pLen), func(t *testing.T) {
			buf := bytes.Buffer{}
			w, _ := gzip.NewWriterLevel(&buf, 4)
			err := w.Close()
			if err != nil {
				t.Fatal(err)
			}
			r, _ := gzip.NewReader(&buf)
			for _, l1 := range tmp {
				p := make([]byte, l1)
				n1, err1 := r.Read(p)
				if n1 != 0 {
					t.Fatalf("expected %d but got %d", 0, n1)
				}
				if err1 != io.EOF {
					t.Fatal(err1)
				}
			}
		})

	}
}

newacorn avatar Jul 28 '24 08:07 newacorn

I think the current behavior makes about as much sense as is possible for a basically meaningless operation like reading 0 bytes.

andybalholm avatar Jul 29 '24 17:07 andybalholm