Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ReadFileWithSizeLimit and use it on x/wasm #696

Merged
merged 8 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (refactor) [\#685](https://github.com/line/lbm-sdk/pull/685) remove x/foundation UpdateValidatorAuthsProposal
* (x/foundation) [\#686](https://github.com/line/lbm-sdk/pull/686) remove `Minthreshold` and `MinPercentage` from x/foundation config
* (x/foundation) [\#693](https://github.com/line/lbm-sdk/pull/693) add pool to the state of x/foundation
* (x/wasm) [\#696](https://github.com/line/lbm-sdk/pull/696) x/wasm - add checking a wasm file size before reading it

### Bug Fixes
* (x/wasm) [\#453](https://github.com/line/lbm-sdk/pull/453) modify wasm grpc query api path
Expand Down
7 changes: 4 additions & 3 deletions x/wasm/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package cli
import (
"errors"
"fmt"
"os"
"strconv"

"github.com/line/lbm-sdk/x/wasm/os"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

Expand Down Expand Up @@ -82,7 +83,7 @@ func StoreCodeCmd() *cobra.Command {
}

func parseStoreCodeArgs(file string, sender sdk.AccAddress, flags *flag.FlagSet) (types.MsgStoreCode, error) {
wasm, err := os.ReadFile(file)
wasm, err := os.ReadFileWithSizeLimit(file, int64(types.MaxWasmSize))
if err != nil {
return types.MsgStoreCode{}, err
}
Expand Down Expand Up @@ -264,7 +265,7 @@ func StoreCodeAndInstantiateContractCmd() *cobra.Command {
}

func parseStoreCodeAndInstantiateContractArgs(file string, initMsg string, sender sdk.AccAddress, flags *flag.FlagSet) (lbmtypes.MsgStoreCodeAndInstantiateContract, error) {
wasm, err := os.ReadFile(file)
wasm, err := os.ReadFileWithSizeLimit(file, int64(types.MaxWasmSize))
if err != nil {
return lbmtypes.MsgStoreCodeAndInstantiateContract{}, err
}
Expand Down
58 changes: 58 additions & 0 deletions x/wasm/os/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package os

import (
"fmt"
"io"
"os"
)

// ReadFileWithSizeLimit expanded os.ReadFile for checking the file size before reading it
func ReadFileWithSizeLimit(name string, sizeLimit int64) ([]byte, error) {
f, err := os.Open(name)
if err != nil {
return nil, err
}
defer func() {
err := f.Close()
if err != nil {
fmt.Printf("Cannot close the file: %s\n", name)
}
}()

var size int
if info, err := f.Stat(); err == nil {
size64 := info.Size()
// Check the file size
if size64 > sizeLimit {
return nil, fmt.Errorf("the file is too large: %s, size limit over > %d", name, sizeLimit)
}
if int64(int(size64)) == size64 {
size = int(size64)
}
}
size++ // one byte for final read at EOF

// If a file claims a small size, read at least 512 bytes.
// In particular, files in Linux's /proc claim size 0 but
// then do not work right if read in small pieces,
// so an initial read of 1 byte would not work correctly.
if size < 512 {
size = 512
}

data := make([]byte, 0, size)
for {
if len(data) >= cap(data) {
d := append(data[:cap(data)], 0)
data = d[:len(data)]
}
n, err := f.Read(data[len(data):cap(data)])
data = data[:len(data)+n]
if err != nil {
if err == io.EOF {
err = nil
}
return data, err
}
}
}
42 changes: 42 additions & 0 deletions x/wasm/os/file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package os

import (
"os"
"reflect"
"testing"

"github.com/stretchr/testify/require"
)

func TestReadFileWithSizeLimit(t *testing.T) {
filename := "file.go"
file, err := os.ReadFile(filename)
require.NoError(t, err)

type args struct {
name string
sizeLimit int64
}
tests := []struct {
name string
args args
want []byte
wantErr bool
}{
{"cannot open error", args{"", 0}, nil, true},
{"size limit over error", args{filename, 0}, nil, true},
{"simple reading file success", args{filename, 100000}, file, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ReadFileWithSizeLimit(tt.args.name, tt.args.sizeLimit)
if (err != nil) != tt.wantErr {
t.Errorf("ReadFileWithSizeLimit() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ReadFileWithSizeLimit() got = %v, want %v", got, tt.want)
}
})
}
}