Catch beyond index error in browse

This commit is contained in:
lash 2023-04-12 08:30:35 +01:00
parent 677dbf536f
commit 4da19b3047
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
8 changed files with 48 additions and 38 deletions

1
go/cache/cache.go vendored
View File

@ -136,7 +136,6 @@ func(ca *Cache) Reset() {
func (ca *Cache) Push() error { func (ca *Cache) Push() error {
m := make(map[string]string) m := make(map[string]string)
ca.Cache = append(ca.Cache, m) ca.Cache = append(ca.Cache, m)
//ca.resetCurrent()
return nil return nil
} }

View File

@ -118,8 +118,8 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
// - required data inputs to the template are not available. // - required data inputs to the template are not available.
// - the template for the given node point is note available for retrieval using the resource.Resource implementer. // - the template for the given node point is note available for retrieval using the resource.Resource implementer.
// - the supplied writer fails to process the writes. // - the supplied writer fails to process the writes.
func(en *Engine) WriteResult(w io.Writer) error { func(en *Engine) WriteResult(w io.Writer, ctx context.Context) error {
r, err := en.vm.Render() r, err := en.vm.Render(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -82,7 +82,7 @@ func TestEngineInit(t *testing.T) {
} }
w := bytes.NewBuffer(nil) w := bytes.NewBuffer(nil)
err = en.WriteResult(w) err = en.WriteResult(w, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -105,7 +105,7 @@ func TestEngineInit(t *testing.T) {
t.Fatalf("expected where-string 'foo', got %s", r) t.Fatalf("expected where-string 'foo', got %s", r)
} }
w = bytes.NewBuffer(nil) w = bytes.NewBuffer(nil)
err = en.WriteResult(w) err = en.WriteResult(w, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -17,7 +17,7 @@ func Loop(en *Engine, startSym string, ctx context.Context, reader io.Reader, wr
} }
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
en.WriteResult(b) en.WriteResult(b, ctx)
fmt.Println(b.String()) fmt.Println(b.String())
running := true running := true
@ -37,7 +37,7 @@ func Loop(en *Engine, startSym string, ctx context.Context, reader io.Reader, wr
return fmt.Errorf("unexpected termination: %v\n", err) return fmt.Errorf("unexpected termination: %v\n", err)
} }
//b := bytes.NewBuffer(nil) //b := bytes.NewBuffer(nil)
err = en.WriteResult(writer) err = en.WriteResult(writer, ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,6 +4,15 @@ import (
"fmt" "fmt"
) )
type BrowseError struct {
Idx uint16
PageCount uint16
}
func(err *BrowseError) Error() string {
return fmt.Sprintf("index is out of bounds: %v", err.Idx)
}
// BrowseConfig defines the availability and display parameters for page browsing. // BrowseConfig defines the availability and display parameters for page browsing.
type BrowseConfig struct { type BrowseConfig struct {
NextAvailable bool NextAvailable bool
@ -112,7 +121,8 @@ func(m *Menu) applyPage(idx uint16) error {
} }
return nil return nil
} else if idx >= m.pageCount { } else if idx >= m.pageCount {
return fmt.Errorf("index %v out of bounds (%v)", idx, m.pageCount) return &BrowseError{Idx: idx, PageCount: m.pageCount}
//return fmt.Errorf("index %v out of bounds (%v)", idx, m.pageCount)
} }
m.reset() m.reset()

View File

@ -307,20 +307,6 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
return "", fmt.Errorf("limit exceeded: %v", pg.sizer) return "", fmt.Errorf("limit exceeded: %v", pg.sizer)
} }
} }
// s, err = pg.menu.Render(idx)
// if err != nil {
// return "", err
// }
// log.Printf("rendered %v bytes for menu", len(s))
// if len(s) > 0 {
// r += "\n" + s
// }
// if pg.sizer != nil {
// _, ok = pg.sizer.Check(r)
// if !ok {
// return "", fmt.Errorf("limit exceeded: %v", pg.sizer)
// }
// }
return r, nil return r, nil
} }
@ -332,12 +318,11 @@ func(pg *Page) Render(sym string, idx uint16) (string, error) {
return "", err return "", err
} }
log.Printf("nosink %v", values)
return pg.render(sym, values, idx) return pg.render(sym, values, idx)
} }
func(pg *Page) Reset() { func(pg *Page) Reset() {
pg.sink = nil pg.sink = nil
pg.sinkSize = 0 pg.sinkSize = 0
//pg.cacheMap = make(map[string]string) pg.cacheMap = make(map[string]string)
} }

View File

@ -383,7 +383,7 @@ func(vm *Vm) RunMPrev(b []byte, ctx context.Context) ([]byte, error) {
return b, nil return b, nil
} }
func(vm *Vm) Render() (string, error) { func(vm *Vm) Render(ctx context.Context) (string, error) {
changed, err := vm.st.ResetFlag(state.FLAG_DIRTY) changed, err := vm.st.ResetFlag(state.FLAG_DIRTY)
if err != nil { if err != nil {
panic(err) panic(err)
@ -393,6 +393,15 @@ func(vm *Vm) Render() (string, error) {
} }
sym, idx := vm.st.Where() sym, idx := vm.st.Where()
r, err := vm.pg.Render(sym, idx) r, err := vm.pg.Render(sym, idx)
var ok bool
_, ok = err.(*render.BrowseError)
if ok {
vm.Reset()
b := NewLine(nil, MOVE, []string{"_catch"}, nil, nil)
vm.Run(b, ctx)
sym, idx := vm.st.Where()
r, err = vm.pg.Render(sym, idx)
}
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -112,16 +112,17 @@ func TestRunLoadRender(t *testing.T) {
st.Down("bar") st.Down("bar")
var err error var err error
ctx := context.TODO()
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil) b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"one"}, nil, nil) b = NewLine(b, MAP, []string{"one"}, nil, nil)
b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil) b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"two"}, nil, nil) b = NewLine(b, MAP, []string{"two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
b, err = vm.Run(b, context.TODO()) b, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
r, err := vm.Render() r, err := vm.Render(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -133,17 +134,17 @@ func TestRunLoadRender(t *testing.T) {
b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil) b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"two"}, nil, nil) b = NewLine(b, MAP, []string{"two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
b, err = vm.Run(b, context.TODO()) b, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
b = NewLine(nil, MAP, []string{"one"}, nil, nil) b = NewLine(nil, MAP, []string{"one"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
_, err = vm.Run(b, context.TODO()) _, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
r, err = vm.Render() r, err = vm.Render(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -159,11 +160,12 @@ func TestRunMultiple(t *testing.T) {
ca := cache.NewCache() ca := cache.NewCache()
vm := NewVm(&st, &rs, ca, nil) vm := NewVm(&st, &rs, ca, nil)
ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"test"}, nil, nil) b := NewLine(nil, MOVE, []string{"test"}, nil, nil)
b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil) b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil)
b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil) b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
b, err := vm.Run(b, context.TODO()) b, err := vm.Run(b, ctx)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -179,15 +181,16 @@ func TestRunReload(t *testing.T) {
szr := render.NewSizer(128) szr := render.NewSizer(128)
vm := NewVm(&st, &rs, ca, szr) vm := NewVm(&st, &rs, ca, szr)
ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"root"}, nil, nil) b := NewLine(nil, MOVE, []string{"root"}, nil, nil)
b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0}) b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0})
b = NewLine(b, MAP, []string{"dyn"}, nil, nil) b = NewLine(b, MAP, []string{"dyn"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
_, err := vm.Run(b, context.TODO()) _, err := vm.Run(b, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
r, err := vm.Render() r, err := vm.Render(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -197,7 +200,7 @@ func TestRunReload(t *testing.T) {
dynVal = "baz" dynVal = "baz"
b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil) b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
_, err = vm.Run(b, context.TODO()) _, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -310,12 +313,14 @@ func TestRunMenu(t *testing.T) {
var err error var err error
ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) b := NewLine(nil, MOVE, []string{"foo"}, nil, nil)
b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil) b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil)
b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
b, err = vm.Run(b, context.TODO()) b, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -324,7 +329,7 @@ func TestRunMenu(t *testing.T) {
t.Errorf("expected empty remainder, got length %v: %v", l, b) t.Errorf("expected empty remainder, got length %v: %v", l, b)
} }
r, err := vm.Render() r, err := vm.Render(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -343,12 +348,14 @@ func TestRunMenuBrowse(t *testing.T) {
var err error var err error
ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"foo"}, nil, nil) b := NewLine(nil, MOVE, []string{"foo"}, nil, nil)
b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil) b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil)
b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil) b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, HALT, nil, nil, nil)
b, err = vm.Run(b, context.TODO()) b, err = vm.Run(b, ctx)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -357,7 +364,7 @@ func TestRunMenuBrowse(t *testing.T) {
t.Errorf("expected empty remainder, got length %v: %v", l, b) t.Errorf("expected empty remainder, got length %v: %v", l, b)
} }
r, err := vm.Render() r, err := vm.Render(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }