From 15d372ac55266e4e15ffc0aa28505b6f792156d2 Mon Sep 17 00:00:00 2001 From: ston1th Date: Sun, 12 Nov 2017 03:09:32 +0100 Subject: [PATCH] fixed issues found by go-fuzz --- .gitignore | 3 +++ filter.go | 18 ++++++++++++++---- helper.go | 25 ++++++++++++++++++++----- 3 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe681e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +fuzz +fuzz.go +filter-fuzz.zip diff --git a/filter.go b/filter.go index cddc35b..ea4a54d 100644 --- a/filter.go +++ b/filter.go @@ -102,6 +102,9 @@ func NewQuery(s string, l Logic) (q *Query, err error) { switch s[2] { case asc, desc: q.s.fields = strings.Split(s[1], ".") + if err = checkFields(q.s.fields, v); err != nil { + return + } if len(q.s.fields) > 0 { if s[2] == desc { q.s.desc = true @@ -129,8 +132,12 @@ func NewQuery(s string, l Logic) (q *Query, err error) { } qm[m[0]] = struct{}{} } + mf := strings.Split(m[0], ".") + if err = checkFields(mf, m[0]); err != nil { + return + } q.m = append(q.m, match{ - strings.Split(m[0], "."), + mf, matchFunc(m[1]), boolFunc(m[1]), }) @@ -191,9 +198,9 @@ func (q *Query) match(v reflect.Value) (ok bool) { if fl == 0 { continue } - val := v.FieldByName(qv.fields[0]) - for j := 1; j < fl; j++ { - val = val.FieldByName(qv.fields[j]) + val := walkFields(v.FieldByName(qv.fields[0]), qv.fields[1:]) + if val.Kind() == reflect.Invalid { + continue } s, b, err := getValue(val) if err != nil { @@ -239,6 +246,9 @@ func (q Query) sort(f Filter) { return } l := makeLess(f, q.s.fields) + if l == nil { + return + } if q.s.desc { l = reverse(l) } diff --git a/helper.go b/helper.go index 7b8786f..c64908e 100644 --- a/helper.go +++ b/helper.go @@ -12,6 +12,15 @@ const ( anys = string(any) ) +func checkFields(s []string, val string) error { + for _, v := range s { + if v == "" { + return errors.New("invalid subfield: " + val) + } + } + return nil +} + type less func(i, j int) bool func reverse(f less) less { @@ -20,12 +29,18 @@ func reverse(f less) less { } } -func index(f Filter, i int, fields []string) (val reflect.Value) { - val = reflect.ValueOf(f.Index(i)).FieldByName(fields[0]) - for j := 1; j < len(fields); j++ { - val = val.FieldByName(fields[j]) +func walkFields(v reflect.Value, fields []string) reflect.Value { + for i := 0; i < len(fields); i++ { + if v.Kind() != reflect.Struct { + return reflect.ValueOf(nil) + } + v = v.FieldByName(fields[i]) } - return + return v +} + +func index(f Filter, i int, fields []string) (val reflect.Value) { + return walkFields(reflect.ValueOf(f.Index(i)).FieldByName(fields[0]), fields[1:]) } func makeLess(f Filter, fields []string) less {