diff --git a/compiler.go b/compiler.go index cb1fab7..c697ee9 100644 --- a/compiler.go +++ b/compiler.go @@ -340,9 +340,10 @@ func (c *compiler) evalAccessIndex(left, index interface{}, node *ast.IndexExpre } case reflect.Array, reflect.Slice: if i, ok := index.(int); ok { - if i < 0 || i >= rv.Len() { + if rv.Len()-1 < i { err = fmt.Errorf("array index out of bounds, got index %d, while array size is %d", index, rv.Len()) } else { + if node.Callee != nil { returnValue, err = c.evalIndexCallee(rv.Index(i), node) } else { diff --git a/struct_test.go b/struct_test.go index a85ff1e..3fb8df1 100644 --- a/struct_test.go +++ b/struct_test.go @@ -556,3 +556,34 @@ func Test_Render_Function_on_Invalid_Function_Struct(t *testing.T) { _, err := plush.Render(input, ctx) r.Error(err) } + +func Test_Render_Struct_Nested_Slice_Access_Out_Of_Range(t *testing.T) { + r := require.New(t) + type d struct { + Final string + } + type c struct { + He []d + } + type b struct { + A []c + } + type mylist struct { + Name []b + } + + input := `<%= myarray[0].Name[0].A[1].He[2].Final %>` + + gg := make([]mylist, 3) + + var bc b + + gg[0].Name = []b{bc} + + ctx := plush.NewContext() + ctx.Set("myarray", gg) + res, err := plush.Render(input, ctx) + r.Error(err) + r.Empty(res) + r.Error(err, "line 1: array index out of bounds, got index 1, while array size is 0") +}