go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit 4e32e2197bbd6c26334b81a55e9dabf039bccffe
parent 577f56f43bea524dd55cc3f89016b4c0164d3a67
Author: lash <dev@holbrook.no>
Date:   Fri, 13 Sep 2024 17:19:41 +0100

Enable alternate valid input parsers passed by to vm

Diffstat:
Mengine/db.go | 2+-
Mvm/input.go | 30++++++++++++++++++++++++++----
Mvm/input_test.go | 38++++++++++++++++++++++++++++++++------
3 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/engine/db.go b/engine/db.go @@ -439,7 +439,7 @@ func (en *DefaultEngine) Exec(ctx context.Context, input []byte) (bool, error) { ctx = context.WithValue(ctx, "Language", *en.st.Language) } - err = vm.ValidInput(input) + _, err = vm.ValidInput(input) if err != nil { return true, err } diff --git a/vm/input.go b/vm/input.go @@ -17,7 +17,10 @@ var ( ctrlRegex = regexp.MustCompile(ctrlRegexStr) symRegexStr = "^[a-zA-Z0-9][a-zA-Z0-9_]+$" symRegex = regexp.MustCompile(symRegexStr) +) +var ( + preInputRegexStr = make(map[int]*regexp.Regexp) ) // InvalidInputError indicates client input that was unhandled by the bytecode (INCMP fallthrough) @@ -35,12 +38,31 @@ func(e InvalidInputError) Error() string { return fmt.Sprintf("invalid input: '%s'", e.input) } +func RegisterInputValidator(k int, v string) error { + var ok bool + var err error + + _, ok = preInputRegexStr[k] + if ok { + return fmt.Errorf("input checker with key '%d' already registered", k) + } + preInputRegexStr[k], err = regexp.Compile(v) + return err +} + // CheckInput validates the given byte string as client input. -func ValidInput(input []byte) error { - if !inputRegex.Match(input) { - return fmt.Errorf("Input '%s' does not match input format /%s/", input, inputRegexStr) +func ValidInput(input []byte) (int, error) { + if inputRegex.Match(input) { + return -1, nil } - return nil + for k, v := range preInputRegexStr { + logg.Tracef("custom check input", "i", k, "regex", v) + if v.Match(input) { + logg.Debugf("match custom check input", "i", k, "regex", v, "input", input) + return k, nil + } + } + return -2, fmt.Errorf("Input '%s' does not match any input format (default: /%s/)", input, inputRegexStr) } // control characters for relative navigation. diff --git a/vm/input_test.go b/vm/input_test.go @@ -9,36 +9,40 @@ import ( ) func TestPhoneInput(t *testing.T) { - err := ValidInput([]byte("+12345")) + v, err := ValidInput([]byte("+12345")) if err != nil { t.Fatal(err) } + if v != -1 { + t.Fatalf("expected -1, got %d", v) + } } func TestMenuInputs(t *testing.T) { - err := ValidInput([]byte("0")) + var err error + _, err = ValidInput([]byte("0")) if err != nil { t.Fatal(err) } - err = ValidInput([]byte("99")) + _, err = ValidInput([]byte("99")) if err != nil { t.Fatal(err) } - err = ValidInput([]byte("foo")) + _, err = ValidInput([]byte("foo")) if err != nil { t.Fatal(err) } - err = ValidInput([]byte("foo Bar")) + _, err = ValidInput([]byte("foo Bar")) if err != nil { t.Fatal(err) } } func TestFalseInput(t *testing.T) { - err := ValidInput([]byte{0x0a}) + _, err := ValidInput([]byte{0x0a}) if err == nil { t.Fatal("expected error") } @@ -150,3 +154,25 @@ func TestApplyTarget(t *testing.T) { t.Fatal(err) } } + +func TestVmCustomInputValid(t *testing.T) { + var err error + s := []byte{0x07, 0x6a, 0x6f, 0x6f} + _, err = ValidInput(s) + if err == nil { + t.Fatal("expected error") + } + + err = RegisterInputValidator(42, "^\x07[a-z]+") + if err != nil { + t.Fatal(err) + } + + v, err := ValidInput(s) + if err != nil { + t.Fatal(err) + } + if v != 42 { + t.Fatalf("expected 42, got %d", v) + } +}