diff --git a/_fixtures/fncall.go b/_fixtures/fncall.go index 34063d64..f1839ca4 100644 --- a/_fixtures/fncall.go +++ b/_fixtures/fncall.go @@ -231,6 +231,9 @@ func main() { d := &Derived{3, Base{4}} + var ref strings.Builder + fmt.Fprintf(&ref, "blah") + runtime.Breakpoint() // breakpoint here call1(one, two) fn2clos(2) @@ -238,5 +241,5 @@ func main() { d.Method() d.Base.Method() x.CallMe() - fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), regabistacktest3, rast3, floatsum) + fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), regabistacktest3, rast3, floatsum, ref) } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index f01c4d2c..5433badc 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -2084,7 +2084,21 @@ func (v *Variable) sliceAccess(idx int) (*Variable, error) { return nil, fmt.Errorf("index out of bounds") } if v.loaded { - return &v.Children[idx], nil + if v.Kind == reflect.String { + s := constant.StringVal(v.Value) + if idx >= len(s) { + return nil, fmt.Errorf("index out of bounds") + } + r := v.newVariable("", v.Base+uint64(int64(idx)*v.stride), v.fieldType, v.mem) + r.loaded = true + r.Value = constant.MakeInt64(int64(s[idx])) + return r, nil + } else { + if idx >= len(v.Children) { + return nil, fmt.Errorf("index out of bounds") + } + return &v.Children[idx], nil + } } mem := v.mem if v.Kind != reflect.Array { diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 22cc223e..1c84f7eb 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -1206,6 +1206,10 @@ func TestCallFunction(t *testing.T) { // Issue 1577 {"1+2", []string{`::3`}, nil}, {`"de"+"mo"`, []string{`::"demo"`}, nil}, + + // Issue 3176 + {`ref.String()[0]`, []string{`:byte:98`}, nil}, + {`ref.String()[20]`, nil, errors.New("index out of bounds")}, } var testcases112 = []testCaseCallFunction{