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:
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)
+ }
+}