Skip to content

Commit af25d77

Browse files
authored
zstd: Fix WriteTo error forwarding (#411)
Fix error forwarding when writing the final block. Fixes #408
1 parent 83be565 commit af25d77

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

zstd/decoder.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,10 @@ func (d *Decoder) WriteTo(w io.Writer) (int64, error) {
260260
if len(d.current.b) > 0 {
261261
n2, err2 := w.Write(d.current.b)
262262
n += int64(n2)
263-
if err2 != nil && d.current.err == nil {
263+
if err2 != nil && (d.current.err == nil || d.current.err == io.EOF) {
264264
d.current.err = err2
265-
break
265+
} else if n2 != len(d.current.b) {
266+
d.current.err = io.ErrShortWrite
266267
}
267268
}
268269
if d.current.err != nil {

zstd/decoder_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,40 @@ func TestErrorReader(t *testing.T) {
165165
}
166166
}
167167

168+
type failingWriter struct {
169+
err error
170+
}
171+
172+
func (f failingWriter) Write(_ []byte) (n int, err error) {
173+
return 0, f.err
174+
}
175+
176+
func TestErrorWriter(t *testing.T) {
177+
input := make([]byte, 100)
178+
cmp := bytes.Buffer{}
179+
w, err := NewWriter(&cmp)
180+
if err != nil {
181+
t.Fatal(err)
182+
}
183+
_, _ = rand.Read(input)
184+
_, err = w.Write(input)
185+
if err != nil {
186+
t.Fatal(err)
187+
}
188+
err = w.Close()
189+
if err != nil {
190+
t.Fatal(err)
191+
}
192+
wantErr := fmt.Errorf("i'm a failure")
193+
zr, err := NewReader(&cmp)
194+
defer zr.Close()
195+
out := failingWriter{err: wantErr}
196+
_, err = zr.WriteTo(out)
197+
if !errors.Is(err, wantErr) {
198+
t.Errorf("error: wanted: %v, got: %v", wantErr, err)
199+
}
200+
}
201+
168202
func TestNewDecoder(t *testing.T) {
169203
defer timeout(60 * time.Second)()
170204
testDecoderFile(t, "testdata/decoder.zip")

0 commit comments

Comments
 (0)