From cd0112749e457c3c4663adbc3d0d22a5c4728687 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Sun, 10 Nov 2019 19:03:05 +0100 Subject: [PATCH] Fix inconsistent zstd error When a data ended exactly where a block is supposed to start, always return io.ErrUnexpectedEOF --- zstd/blockdec.go | 3 ++- zstd/bytebuf.go | 3 +++ zstd/decoder_test.go | 40 ++++++++++++++++++++++++++++++++++- zstd/testdata/regression.zip | Bin 1452256 -> 1457951 bytes 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/zstd/blockdec.go b/zstd/blockdec.go index 972a304a40..47cc21d6d3 100644 --- a/zstd/blockdec.go +++ b/zstd/blockdec.go @@ -161,7 +161,8 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { b.data, err = br.readBig(cSize, b.dataStorage) if err != nil { if debug { - println("Reading block:", err) + println("Reading block:", err, "(", cSize, ")", len(b.data)) + printf("%T", br) } return err } diff --git a/zstd/bytebuf.go b/zstd/bytebuf.go index 3538063f1a..07321acb18 100644 --- a/zstd/bytebuf.go +++ b/zstd/bytebuf.go @@ -101,6 +101,9 @@ func (r *readerWrapper) readBig(n int, dst []byte) ([]byte, error) { dst = make([]byte, n) } n2, err := io.ReadFull(r.r, dst[:n]) + if err == io.EOF && n > 0 { + err = io.ErrUnexpectedEOF + } return dst[:n2], err } diff --git a/zstd/decoder_test.go b/zstd/decoder_test.go index 3afd568923..018c0f8492 100644 --- a/zstd/decoder_test.go +++ b/zstd/decoder_test.go @@ -342,7 +342,7 @@ func TestNewDecoderFlushed(t *testing.T) { } func TestDecoderRegression(t *testing.T) { - defer timeout(60 * time.Second)() + defer timeout(160 * time.Second)() data, err := ioutil.ReadFile("testdata/regression.zip") if err != nil { t.Fatal(err) @@ -443,6 +443,44 @@ func TestDecoderRegression(t *testing.T) { } } }) + t.Run("Match-"+tt.Name, func(t *testing.T) { + r, err := tt.Open() + if err != nil { + t.Error(err) + return + } + in, err := ioutil.ReadAll(r) + if err != nil { + t.Error(err) + } + got, gotErr := dec.DecodeAll(in, nil) + t.Log("Received:", len(got), gotErr) + + // Check a fresh instance + decL, err := NewReader(bytes.NewBuffer(in), WithDecoderConcurrency(1), WithDecoderLowmem(true), WithDecoderMaxMemory(1<<20)) + if err != nil { + t.Error(err) + return + } + defer decL.Close() + got2, gotErr2 := ioutil.ReadAll(decL) + t.Log("Reader Reader received:", len(got2), gotErr2) + if gotErr != gotErr2 { + if gotErr != nil && gotErr2 != nil && gotErr.Error() != gotErr2.Error() { + t.Error(gotErr, "!=", gotErr2) + } + if (gotErr == nil) != (gotErr2 == nil) { + t.Error(gotErr, "!=", gotErr2) + } + } + if !bytes.Equal(got2, got) { + if gotErr != nil { + t.Log("Buffer mismatch") + } else { + t.Error("Buffer mismatch") + } + } + }) } } diff --git a/zstd/testdata/regression.zip b/zstd/testdata/regression.zip index 3b87c17682006f417760cba1efab55229c42486d..34f332db47cfed8822080179034d6a8925c17cbb 100644 GIT binary patch delta 5765 zcmaEGF=GC|h=vx%7N!>F7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQ7NHj57LgXw zEn+6}lFTe33``6h3<7ys{;G<5r*0Ny00IF9h3Vz8Vv6;;MsF`=`-p`wusz^ExqDe% zs+dz^&_ZPy(LAf0AzT+0uvYK}aR-LaTIQT?#*;p6Sxd`0?iDW%83lW3xN4o%TXxsr z^dU20eV3G#r}d}JYTtZ_3y1QSAITsQ22E_A@}GG-^+G8 zR_49S-&|f>x8drCkM-{9V$+|ts-B-QWom4tYr^T+>EBj*y`8%y;osKn->fa)mR$MD z9~Qd3Wd4k)lQ%Ckw0^!=FknrB%%A@D-RBD@H@?naQS;ChSF^8{?s8XeFOjWz7U275Wy_aT@&1`x^*635cz)~CvzGdK$>vki zTSTTTa~G4jH+$#ejM$gl8z+Aje*He*YTEVB7kLwvH@}aXwRg>rlTUW8zOL>XcXeld zV5HZrN2l(s{+x9$`nyB1*Y3H&%iho4{HNV~@&5VdQVi(tlSaqovlMdd1}jte$&kIaeRmc`JQ)-&fPaMr}`7mig7xMb9qtJ^FU>`Cz>_ z6N0WQURYWD;HBdB_Oi7yLL4kj@9kse81DE!D_#8i8}W`_?)b0wZhmM|e7(5q)vf;} z>8E*>)p_bqNs9dZ_)S)GuGah7>=%!>p5@tEdtANEGM#)3}dZzm8 z)x}q~Z3|r7eq7D}@9Gz?+iinGKII;|XwPN;?8W@;f7U;nQtw||``12KqOR`Yr|sVJ z;$k)$WnZ2%Et=_}XrZEYk-VJr%%fXKGg2_zgd_1rcwQ|+|PgetL7DR3Me=< zFfcN)aA0H9R6TB|(Zl+NdYmCc7wZ}7aYYP$tY@spkuKJn3}h8N+Wr~X z2FPgpXJ9)(qy4Xe?EsCIKLcC-B+$ppw0|g)n fR6V^?R!m+(*C@c7l?@~=2ZYZ!85opJ#eh5jLI*`j delta 80 zcmbRLFXF+)h=vx%7N!>F7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQ7NHj57LgXw fEn+6}+f_})W^jtIvM~UGED+A%WMD9o7X$JD9-I__