From 697c61754fc912890f1eb6ca4353ad4456e9bfd5 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg <519948+ARR4N@users.noreply.github.com> Date: Sat, 3 Aug 2024 09:07:47 +0100 Subject: [PATCH] fix: `PUSH([]T{})` is noop for empty slice (#33) --- pushlabels_test.go | 28 ++++++++++++++++++++++++++++ specops.go | 5 +++++ 2 files changed, 33 insertions(+) diff --git a/pushlabels_test.go b/pushlabels_test.go index e8a4e6a..d8b9747 100644 --- a/pushlabels_test.go +++ b/pushlabels_test.go @@ -142,6 +142,34 @@ func TestPUSHLabels(t *testing.T) { // t.Logf("want: %d %#x", len(want), want) } +func TestPUSHNoLabels(t *testing.T) { + // Arbitrary boundaries to surround the empty push; MUST have no effect on + // the stack otherwise compilation will fail. + const ( + before = MSIZE + after = GAS + ) + + code := Code{ + before, + PUSH([]JUMPDEST{}), + PUSH([]Label{}), + PUSH([]string{}), + after, + } + want := asBytes(before, after) + + t.Logf("%T = {%s, PUSH([]JUMPDEST{}, []Label{}, []string), %s}", code, before, after) + + got, err := code.Compile() + if err != nil { + t.Fatalf("%T.Compile() error %v", code, err) + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("%T.Compile() diff (-want +got):\n%s", code, diff) + } +} + type opCode interface { vm.OpCode | types.OpCode } diff --git a/specops.go b/specops.go index 2873af9..1857596 100644 --- a/specops.go +++ b/specops.go @@ -13,6 +13,7 @@ import ( "encoding/binary" "fmt" "math/bits" + "reflect" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -87,6 +88,10 @@ func PUSH[P interface { ) types.Bytecoder { pToB := types.BytecoderFromStackPusher + if val := reflect.ValueOf(v); val.Kind() == reflect.Slice && val.Len() == 0 { + return Raw{} + } + switch v := any(v).(type) { case int: if v < 0 {