1package moxio
2
3import (
4 "github.com/mjl-/flate"
5)
6
7// FlateWriter wraps a flate.Writer and ensures no Write/Flush/Close calls are made
8// again on the underlying flate writer when a panic came out of the flate writer
9// (e.g. raised by the destination writer of the flate writer). After a panic
10// "through" a flate.Writer, its state is inconsistent and further calls could
11// panic with out of bounds slice accesses.
12type FlateWriter struct {
13 w *flate.Writer
14 panic any
15}
16
17func NewFlateWriter(w *flate.Writer) *FlateWriter {
18 return &FlateWriter{w, nil}
19}
20
21func (w *FlateWriter) checkBroken() func() {
22 if w.panic != nil {
23 panic(w.panic)
24 }
25 return func() {
26 x := recover()
27 if x == nil {
28 return
29 }
30 w.panic = x
31 panic(x)
32 }
33}
34
35func (w *FlateWriter) Write(data []byte) (int, error) {
36 defer w.checkBroken()()
37 return w.w.Write(data)
38}
39
40func (w *FlateWriter) Flush() error {
41 defer w.checkBroken()()
42 return w.w.Flush()
43}
44
45func (w *FlateWriter) Close() error {
46 defer w.checkBroken()()
47 return w.w.Close()
48}
49