github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/ioutil.go (about) 1 package keeper 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "io" 7 "io/ioutil" 8 9 "github.com/fibonacci-chain/fbc/x/wasm/types" 10 ) 11 12 // magic bytes to identify gzip. 13 // See https://www.ietf.org/rfc/rfc1952.txt 14 // and https://github.com/golang/go/blob/master/src/net/http/sniff.go#L186 15 var gzipIdent = []byte("\x1F\x8B\x08") 16 17 // uncompress returns gzip uncompressed content or given src when not gzip. 18 func uncompress(src []byte, limit uint64) ([]byte, error) { 19 switch n := uint64(len(src)); { 20 case n < 3: 21 return src, nil 22 case n > limit: 23 return nil, types.ErrLimit 24 } 25 if !bytes.Equal(gzipIdent, src[0:3]) { 26 return src, nil 27 } 28 zr, err := gzip.NewReader(bytes.NewReader(src)) 29 if err != nil { 30 return nil, err 31 } 32 zr.Multistream(false) 33 defer zr.Close() 34 return ioutil.ReadAll(LimitReader(zr, int64(limit))) 35 } 36 37 // LimitReader returns a Reader that reads from r 38 // but stops with types.ErrLimit after n bytes. 39 // The underlying implementation is a *io.LimitedReader. 40 func LimitReader(r io.Reader, n int64) io.Reader { 41 return &LimitedReader{r: &io.LimitedReader{R: r, N: n}} 42 } 43 44 type LimitedReader struct { 45 r *io.LimitedReader 46 } 47 48 func (l *LimitedReader) Read(p []byte) (n int, err error) { 49 if l.r.N <= 0 { 50 return 0, types.ErrLimit 51 } 52 return l.r.Read(p) 53 }