Catch missing input on empty bytecode buffer
This commit is contained in:
parent
f0bfff3a20
commit
6325ef4afd
@ -2,4 +2,5 @@ package state
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
FLAG_INMATCH = 1
|
FLAG_INMATCH = 1
|
||||||
|
FLAG_TERMINATE = 2
|
||||||
)
|
)
|
||||||
|
@ -57,6 +57,12 @@ func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
if len(b) == 0 {
|
||||||
|
b, err = RunDeadCheck(b, st, rs, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
@ -64,6 +70,36 @@ func Run(b []byte, st *state.State, rs resource.Resource, ctx context.Context) (
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunDeadCheck determines whether a state of empty bytecode should result in termination.
|
||||||
|
//
|
||||||
|
// If there is remaining bytecode, this method is a noop.
|
||||||
|
//
|
||||||
|
// If input has not been matched, a default invalid input page should be generated aswell as a possiblity of return to last screen (or exit).
|
||||||
|
//
|
||||||
|
// If the termination flag has been set but not yet handled, execution is allowed to terminate.
|
||||||
|
func RunDeadCheck(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
|
||||||
|
if len(b) > 0 {
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
log.Printf("no code remaining, let's check if we terminate")
|
||||||
|
r, err := matchFlag(st, state.FLAG_TERMINATE, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if r {
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
location := st.Where()
|
||||||
|
if location == "" {
|
||||||
|
return b, fmt.Errorf("dead runner with no current location")
|
||||||
|
}
|
||||||
|
b = NewLine(nil, MOVE, []string{"_catch"}, nil, nil)
|
||||||
|
b = NewLine(b, HALT, nil, nil, nil)
|
||||||
|
b = NewLine(b, MOVE, []string{location}, nil, nil)
|
||||||
|
log.Printf("code is now %x", b)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RunMap executes the MAP opcode
|
// RunMap executes the MAP opcode
|
||||||
func RunMap(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
|
func RunMap(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
|
||||||
sym, b, err := ParseMap(b)
|
sym, b, err := ParseMap(b)
|
||||||
@ -73,6 +109,7 @@ func RunMap(b []byte, st *state.State, rs resource.Resource, ctx context.Context
|
|||||||
|
|
||||||
// RunMap executes the CATCH opcode
|
// RunMap executes the CATCH opcode
|
||||||
func RunCatch(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
|
func RunCatch(b []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
|
||||||
|
log.Printf("zzz %x", b)
|
||||||
sym, sig, mode, b, err := ParseCatch(b)
|
sym, sig, mode, b, err := ParseCatch(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, err
|
return b, err
|
||||||
|
@ -104,6 +104,7 @@ func TestRunLoadRender(t *testing.T) {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil)
|
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil)
|
||||||
|
b = NewLine(b, HALT, nil, nil, nil)
|
||||||
b, err = Run(b, &st, &rs, context.TODO())
|
b, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -127,11 +128,13 @@ 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, HALT, nil, nil, nil)
|
||||||
b, err = Run(b, &st, &rs, context.TODO())
|
b, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
b = NewLine(nil, MAP, []string{"one"}, nil, nil)
|
b = NewLine(nil, MAP, []string{"one"}, nil, nil)
|
||||||
|
b = NewLine(b, HALT, nil, nil, nil)
|
||||||
_, err = Run(b, &st, &rs, context.TODO())
|
_, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -155,6 +158,7 @@ func TestRunMultiple(t *testing.T) {
|
|||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x00}, nil)
|
b := NewLine(nil, 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, err := Run(b, &st, &rs, context.TODO())
|
b, err := Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -167,33 +171,35 @@ func TestRunMultiple(t *testing.T) {
|
|||||||
func TestRunReload(t *testing.T) {
|
func TestRunReload(t *testing.T) {
|
||||||
st := state.NewState(5)
|
st := state.NewState(5)
|
||||||
rs := TestResource{}
|
rs := TestResource{}
|
||||||
b := NewLine(nil, LOAD, []string{"dyn"}, nil, []uint8{0})
|
b := NewLine(nil, MOVE, []string{"root"}, nil, nil)
|
||||||
|
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)
|
||||||
_, err := Run(b, &st, &rs, context.TODO())
|
_, err := Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
r, err := st.Val("dyn")
|
r, err := st.Val("dyn")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if r != "three" {
|
if r != "three" {
|
||||||
t.Errorf("expected result 'three', got %v", r)
|
t.Fatalf("expected result 'three', got %v", r)
|
||||||
}
|
}
|
||||||
dynVal = "baz"
|
dynVal = "baz"
|
||||||
b = []byte{}
|
b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil)
|
||||||
b = NewLine(b, RELOAD, []string{"dyn"}, nil, nil)
|
b = NewLine(b, HALT, nil, nil, nil)
|
||||||
_, err = Run(b, &st, &rs, context.TODO())
|
_, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
r, err = st.Val("dyn")
|
r, err = st.Val("dyn")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Printf("dun now %s", r)
|
log.Printf("dun now %s", r)
|
||||||
if r != "baz" {
|
if r != "baz" {
|
||||||
t.Errorf("expected result 'baz', got %v", r)
|
t.Fatalf("expected result 'baz', got %v", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -225,7 +231,8 @@ func TestRunArg(t *testing.T) {
|
|||||||
input := []byte("bar")
|
input := []byte("bar")
|
||||||
_ = st.SetInput(input)
|
_ = st.SetInput(input)
|
||||||
|
|
||||||
bi := NewLine([]byte{}, INCMP, []string{"bar", "baz"}, nil, nil)
|
bi := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil)
|
||||||
|
bi = NewLine(bi, HALT, nil, nil, nil)
|
||||||
b, err := Run(bi, &st, &rs, context.TODO())
|
b, err := Run(bi, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -252,6 +259,7 @@ func TestRunInputHandler(t *testing.T) {
|
|||||||
bi = NewLine(bi, LOAD, []string{"two"}, []byte{0x03}, nil)
|
bi = NewLine(bi, LOAD, []string{"two"}, []byte{0x03}, nil)
|
||||||
bi = NewLine(bi, MAP, []string{"one"}, nil, nil)
|
bi = NewLine(bi, MAP, []string{"one"}, nil, nil)
|
||||||
bi = NewLine(bi, MAP, []string{"two"}, nil, nil)
|
bi = NewLine(bi, MAP, []string{"two"}, nil, nil)
|
||||||
|
bi = NewLine(bi, HALT, nil, nil, nil)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
_, err = Run(bi, &st, &rs, context.TODO())
|
_, err = Run(bi, &st, &rs, context.TODO())
|
||||||
@ -271,21 +279,22 @@ func TestRunArgInvalid(t *testing.T) {
|
|||||||
_ = st.SetInput([]byte("foo"))
|
_ = st.SetInput([]byte("foo"))
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
b := NewLine([]byte{}, INCMP, []string{"bar", "baz"}, nil, nil)
|
st.Down("root")
|
||||||
b = NewLine(b, CATCH, []string{"_catch"}, []byte{state.FLAG_INMATCH}, []uint8{1})
|
b := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil)
|
||||||
|
//b = NewLine(b, CATCH, []string{"_catch"}, []byte{state.FLAG_INMATCH}, []uint8{1})
|
||||||
|
|
||||||
b, err = Run(b, &st, &rs, context.TODO())
|
b, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
l := len(b)
|
expect := NewLine(nil, MOVE, []string{"root"}, nil, nil)
|
||||||
if l != 0 {
|
if !bytes.Equal(b, expect) {
|
||||||
t.Errorf("expected empty remainder, got length %v: %v", l, b)
|
t.Fatalf("expected:\n\t%x\ngot:\b\t%x\n", expect, b)
|
||||||
}
|
}
|
||||||
r := st.Where()
|
r := st.Where()
|
||||||
if r != "_catch" {
|
if r != "_catch" {
|
||||||
t.Errorf("expected where-state _catch, got %v", r)
|
t.Fatalf("expected where-state _catch, got %v", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +307,7 @@ func TestRunMenu(t *testing.T) {
|
|||||||
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, err = Run(b, &st, &rs, context.TODO())
|
b, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -331,6 +341,7 @@ func TestRunMenuBrowse(t *testing.T) {
|
|||||||
b = NewLine(b, MPREV, []string{"22", "two"}, nil, nil)
|
b = NewLine(b, MPREV, []string{"22", "two"}, 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, err = Run(b, &st, &rs, context.TODO())
|
b, err = Run(b, &st, &rs, context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -350,3 +361,4 @@ func TestRunMenuBrowse(t *testing.T) {
|
|||||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r)
|
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user