mirror of https://github.com/certusone/wasmd.git
Reject wasm zips exceeding limit
This commit is contained in:
parent
41cf73dae9
commit
e55cc9f3b5
|
@ -5,6 +5,8 @@ import (
|
|||
"compress/gzip"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
)
|
||||
|
||||
// magic bytes to identify gzip.
|
||||
|
@ -28,6 +30,24 @@ func uncompress(src []byte) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
zr.Multistream(false)
|
||||
|
||||
return ioutil.ReadAll(io.LimitReader(zr, maxSize))
|
||||
defer zr.Close()
|
||||
return ioutil.ReadAll(LimitReader(zr, maxSize))
|
||||
}
|
||||
|
||||
// LimitReader returns a Reader that reads from r
|
||||
// but stops with types.ErrLimit after n bytes.
|
||||
// The underlying implementation is a *io.LimitedReader.
|
||||
func LimitReader(r io.Reader, n int64) io.Reader {
|
||||
return &LimitedReader{r: &io.LimitedReader{R: r, N: n}}
|
||||
}
|
||||
|
||||
type LimitedReader struct {
|
||||
r *io.LimitedReader
|
||||
}
|
||||
|
||||
func (l *LimitedReader) Read(p []byte) (n int, err error) {
|
||||
if l.r.N <= 0 {
|
||||
return 0, types.ErrLimit
|
||||
}
|
||||
return l.r.Read(p)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -20,6 +21,7 @@ func TestUncompress(t *testing.T) {
|
|||
wasmGzipped, err := ioutil.ReadFile("./testdata/hackatom.wasm.gzip")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _ = wasmRaw, wasmGzipped
|
||||
specs := map[string]struct {
|
||||
src []byte
|
||||
expError error
|
||||
|
@ -57,19 +59,23 @@ func TestUncompress(t *testing.T) {
|
|||
src: wasmGzipped[:len(wasmGzipped)-5],
|
||||
expError: io.ErrUnexpectedEOF,
|
||||
},
|
||||
"handle limit gzip output": {
|
||||
src: asGzip(bytes.Repeat([]byte{0x1}, maxSize)),
|
||||
expResult: bytes.Repeat([]byte{0x1}, maxSize),
|
||||
},
|
||||
"handle big gzip output": {
|
||||
src: asGzip(strings.Repeat("a", maxSize+1)),
|
||||
expError: io.ErrUnexpectedEOF,
|
||||
src: asGzip(bytes.Repeat([]byte{0x1}, maxSize+1)),
|
||||
expError: types.ErrLimit,
|
||||
},
|
||||
"handle other big gzip output": {
|
||||
src: asGzip(strings.Repeat("a", 2*maxSize)),
|
||||
expError: io.ErrUnexpectedEOF,
|
||||
src: asGzip(bytes.Repeat([]byte{0x1}, 2*maxSize)),
|
||||
expError: types.ErrLimit,
|
||||
},
|
||||
}
|
||||
for msg, spec := range specs {
|
||||
t.Run(msg, func(t *testing.T) {
|
||||
r, err := uncompress(spec.src)
|
||||
require.True(t, errors.Is(spec.expError, err), "exp %+v got %+v", spec.expError, err)
|
||||
require.True(t, errors.Is(spec.expError, err), "exp %v got %+v", spec.expError, err)
|
||||
if spec.expError != nil {
|
||||
return
|
||||
}
|
||||
|
@ -79,9 +85,13 @@ func TestUncompress(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func asGzip(src string) []byte {
|
||||
func asGzip(src []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
if _, err := io.Copy(gzip.NewWriter(&buf), strings.NewReader(src)); err != nil {
|
||||
zipper := gzip.NewWriter(&buf)
|
||||
if _, err := io.Copy(zipper, bytes.NewReader(src)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := zipper.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return buf.Bytes()
|
||||
|
|
Loading…
Reference in New Issue