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 all 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,distribution) [\#696](https://github.com/line/lbm-sdk/pull/696) x/wasm,distribution - add checking a file size before reading it
* (x/foundation) [\#698](https://github.com/line/lbm-sdk/pull/698) update x/group relevant logic in x/foundation

### Bug Fixes
Expand Down
58 changes: 58 additions & 0 deletions internal/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 internal/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)
}
})
}
}
8 changes: 5 additions & 3 deletions x/distribution/client/cli/utils.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package cli

import (
"os"

"github.com/line/lbm-sdk/codec"
"github.com/line/lbm-sdk/internal/os"
"github.com/line/lbm-sdk/x/distribution/types"
)

// ParseCommunityPoolSpendProposalWithDeposit reads and parses a CommunityPoolSpendProposalWithDeposit from a file.
func ParseCommunityPoolSpendProposalWithDeposit(cdc codec.JSONCodec, proposalFile string) (types.CommunityPoolSpendProposalWithDeposit, error) {
proposal := types.CommunityPoolSpendProposalWithDeposit{}

contents, err := os.ReadFile(proposalFile)
// 2M size limit is enough for a proposal.
// Check the proposals:
// https://hubble.figment.io/cosmos/chains/cosmoshub-4/governance
contents, err := os.ReadFileWithSizeLimit(proposalFile, 2*1024*1024)
if err != nil {
return proposal, err
}
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/internal/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