Skip to content

Commit

Permalink
add safe casting to memory file
Browse files Browse the repository at this point in the history
  • Loading branch information
jimjbrettj committed Mar 27, 2023
1 parent fadb99a commit a807601
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
23 changes: 19 additions & 4 deletions lib/runtime/newWasmer/memory.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
// Copyright 2023 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package newWasmer
package wasmer

import (
"errors"
"fmt"
"math"

wasmgo "github.com/wasmerio/wasmer-go/wasmer"
)

var errGrowMemory = errors.New("failed to grow memory")
var (
errCantGrowMemory = errors.New("failed to grow memory")
errMemoryValueOutOfBounds = errors.New("memory value is out of bounds")
)

// Memory is a thin wrapper around Wasmer memory to support
// Gossamer runtime.Memory interface
type Memory struct {
memory *wasmgo.Memory
}

func checkBounds(value uint64) (uint32, error) {
if value > math.MaxUint32 {
return 0, fmt.Errorf("%w", errMemoryValueOutOfBounds)
}
return uint32(value), nil
}

// Data returns the memory's data
func (m Memory) Data() []byte {
return m.memory.Data()
}

// Length returns the memory's length
func (m Memory) Length() uint32 {
return uint32(m.memory.DataSize())
value, err := checkBounds(uint64(m.memory.DataSize()))
if err != nil {
panic(err)
}
return value
}

// Grow grows the memory by the given number of pages
func (m Memory) Grow(numPages uint32) error {
ok := m.memory.Grow(wasmgo.Pages(numPages))
if !ok {
return fmt.Errorf("%w", errGrowMemory)
return fmt.Errorf("%w", errCantGrowMemory)
}
return nil
}
47 changes: 46 additions & 1 deletion lib/runtime/newWasmer/memory_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright 2023 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package newWasmer
package wasmer

import (
"github.com/stretchr/testify/assert"
"math"
"testing"
"unsafe"

Expand Down Expand Up @@ -47,6 +49,7 @@ func createInstance(t *testing.T) (*wasmer.Instance, error) {
}

func TestMemory_Length(t *testing.T) {
t.Parallel()
const pageLength uint32 = 65536
instance, err := createInstance(t)
require.NoError(t, err)
Expand All @@ -63,6 +66,7 @@ func TestMemory_Length(t *testing.T) {
}

func TestMemory_Grow(t *testing.T) {
t.Parallel()
const pageLength uint32 = 65536
instance, err := createInstance(t)
require.NoError(t, err)
Expand All @@ -85,6 +89,7 @@ func TestMemory_Grow(t *testing.T) {
}

func TestMemory_Data(t *testing.T) {
t.Parallel()
instance, err := createInstance(t)
require.NoError(t, err)

Expand Down Expand Up @@ -126,5 +131,45 @@ func TestMemory_Data(t *testing.T) {
result, err = getAt(memAddr)
require.NoError(t, err)
require.Equal(t, val2, result)
}

func TestMemory_CheckBounds(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
value uint64
exp uint32
expErr error
expErrMsg string
}{
{
name: "valid cast",
value: uint64(0),
exp: uint32(0),
},
{
name: "max uint32",
value: uint64(math.MaxUint32),
exp: math.MaxUint32,
},
{
name: "out of bounds",
value: uint64(math.MaxUint32 + 1),
expErr: errMemoryValueOutOfBounds,
expErrMsg: errMemoryValueOutOfBounds.Error(),
},
}
for _, test := range testCases {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

res, err := checkBounds(test.value)
assert.ErrorIs(t, err, test.expErr)
if test.expErr != nil {
assert.EqualError(t, err, test.expErrMsg)
}
assert.Equal(t, test.exp, res)
})
}
}

0 comments on commit a807601

Please sign in to comment.