diff --git a/gno.land/pkg/sdk/vm/convert.go b/gno.land/pkg/sdk/vm/convert.go index f70f99403a8..cafb6cad67f 100644 --- a/gno.land/pkg/sdk/vm/convert.go +++ b/gno.land/pkg/sdk/vm/convert.go @@ -4,13 +4,14 @@ import ( "encoding/base64" "fmt" "strconv" + "strings" "github.com/cockroachdb/apd/v3" gno "github.com/gnolang/gno/gnovm/pkg/gnolang" ) -func assertCharNotPlus(b byte) { - if b == '+' { +func assertNoPlusPrefix(s string) { + if strings.HasPrefix(s, "+") { panic("numbers cannot start with +") } } @@ -41,7 +42,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetString(gno.StringValue(arg)) return case gno.IntType: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) i64, err := strconv.ParseInt(arg, 10, 64) if err != nil { panic(fmt.Sprintf( @@ -51,7 +52,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetInt(int(i64)) return case gno.Int8Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) i8, err := strconv.ParseInt(arg, 10, 8) if err != nil { panic(fmt.Sprintf( @@ -61,7 +62,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetInt8(int8(i8)) return case gno.Int16Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) i16, err := strconv.ParseInt(arg, 10, 16) if err != nil { panic(fmt.Sprintf( @@ -71,7 +72,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetInt16(int16(i16)) return case gno.Int32Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) i32, err := strconv.ParseInt(arg, 10, 32) if err != nil { panic(fmt.Sprintf( @@ -81,7 +82,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetInt32(int32(i32)) return case gno.Int64Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) i64, err := strconv.ParseInt(arg, 10, 64) if err != nil { panic(fmt.Sprintf( @@ -91,7 +92,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetInt64(i64) return case gno.UintType: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) u64, err := strconv.ParseUint(arg, 10, 64) if err != nil { panic(fmt.Sprintf( @@ -101,7 +102,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetUint(uint(u64)) return case gno.Uint8Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) u8, err := strconv.ParseUint(arg, 10, 8) if err != nil { panic(fmt.Sprintf( @@ -111,7 +112,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetUint8(uint8(u8)) return case gno.Uint16Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) u16, err := strconv.ParseUint(arg, 10, 16) if err != nil { panic(fmt.Sprintf( @@ -121,7 +122,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetUint16(uint16(u16)) return case gno.Uint32Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) u32, err := strconv.ParseUint(arg, 10, 32) if err != nil { panic(fmt.Sprintf( @@ -131,7 +132,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { tv.SetUint32(uint32(u32)) return case gno.Uint64Type: - assertCharNotPlus(arg[0]) + assertNoPlusPrefix(arg) u64, err := strconv.ParseUint(arg, 10, 64) if err != nil { panic(fmt.Sprintf( @@ -192,15 +193,15 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) { } func convertFloat(value string, precision int) float64 { - assertCharNotPlus(value[0]) + assertNoPlusPrefix(value) dec, _, err := apd.NewFromString(value) if err != nil { - panic(fmt.Sprintf("error parsing float%d %s: %v", precision, value, err)) + panic(fmt.Sprintf("error parsing float%d %q: %v", precision, value, err)) } f64, err := strconv.ParseFloat(dec.String(), precision) if err != nil { - panic(fmt.Sprintf("error value exceeds float%d precision %s: %v", precision, value, err)) + panic(fmt.Sprintf("error value exceeds float%d precision %q: %v", precision, value, err)) } return f64 diff --git a/gno.land/pkg/sdk/vm/convert_test.go b/gno.land/pkg/sdk/vm/convert_test.go new file mode 100644 index 00000000000..666ec1620fa --- /dev/null +++ b/gno.land/pkg/sdk/vm/convert_test.go @@ -0,0 +1,39 @@ +package vm + +import ( + "fmt" + "testing" + + "github.com/gnolang/gno/gnovm/pkg/gnolang" + "github.com/stretchr/testify/assert" +) + +func TestConvertEmptyNumbers(t *testing.T) { + tests := []struct { + argT gnolang.Type + expectedErr string + }{ + {gnolang.UintType, `error parsing uint "": strconv.ParseUint: parsing "": invalid syntax`}, + {gnolang.Uint64Type, `error parsing uint64 "": strconv.ParseUint: parsing "": invalid syntax`}, + {gnolang.Uint32Type, `error parsing uint32 "": strconv.ParseUint: parsing "": invalid syntax`}, + {gnolang.Uint16Type, `error parsing uint16 "": strconv.ParseUint: parsing "": invalid syntax`}, + {gnolang.Uint8Type, `error parsing uint8 "": strconv.ParseUint: parsing "": invalid syntax`}, + {gnolang.IntType, `error parsing int "": strconv.ParseInt: parsing "": invalid syntax`}, + {gnolang.Int64Type, `error parsing int64 "": strconv.ParseInt: parsing "": invalid syntax`}, + {gnolang.Int32Type, `error parsing int32 "": strconv.ParseInt: parsing "": invalid syntax`}, + {gnolang.Int16Type, `error parsing int16 "": strconv.ParseInt: parsing "": invalid syntax`}, + {gnolang.Int8Type, `error parsing int8 "": strconv.ParseInt: parsing "": invalid syntax`}, + {gnolang.Float64Type, `error parsing float64 "": parse mantissa: `}, + {gnolang.Float32Type, `error parsing float32 "": parse mantissa: `}, + } + + for _, tt := range tests { + testname := fmt.Sprintf("%v", tt.argT) + t.Run(testname, func(t *testing.T) { + run := func() { + _ = convertArgToGno("", tt.argT) + } + assert.PanicsWithValue(t, tt.expectedErr, run) + }) + } +}