Search: Fix query string substitutions and sanitation #1930

This commit is contained in:
Michael Mayer 2022-01-17 16:07:31 +01:00
parent 2ee89e733b
commit ff41a94051
8 changed files with 65 additions and 29 deletions

View file

@ -126,7 +126,7 @@ func Unserialize(f SearchForm, q string) (result error) {
field.SetUint(uint64(intValue))
}
case string:
field.SetString(sanitize.Query(stringValue))
field.SetString(sanitize.SearchString(stringValue))
case bool:
field.SetBool(txt.Bool(stringValue))
default:
@ -155,7 +155,7 @@ func Unserialize(f SearchForm, q string) (result error) {
}
if len(queryStrings) > 0 {
f.SetQuery(sanitize.Query(strings.Join(queryStrings, " ")))
f.SetQuery(sanitize.SearchQuery(strings.Join(queryStrings, " ")))
}
if result != nil {

View file

@ -783,7 +783,7 @@ func TestGeo(t *testing.T) {
assert.NotEmpty(t, r.ID)
}
})
t.Run("f.Query = p", func(t *testing.T) {
t.Run("QueryP", func(t *testing.T) {
var frm form.SearchGeo
frm.Query = "p"
frm.Title = ""

View file

@ -18,7 +18,7 @@ func LikeAny(col, s string, keywords, exact bool) (wheres []string) {
return wheres
}
s = txt.StripOr(sanitize.Query(s))
s = txt.StripOr(sanitize.SearchQuery(s))
var wildcardThreshold int
@ -244,7 +244,7 @@ func OrLike(col, s string) (where string, values []interface{}) {
values = make([]interface{}, len(terms))
for i := range terms {
values[i] = strings.TrimSpace(terms[i])
values[i] = terms[i]
}
like := fmt.Sprintf("%s LIKE ?", col)

View file

@ -207,7 +207,7 @@ func TestLikeAllNames(t *testing.T) {
}
})
t.Run("Plus", func(t *testing.T) {
if w := LikeAllNames(Cols{"name"}, sanitize.Query("Paul + Paula")); len(w) == 2 {
if w := LikeAllNames(Cols{"name"}, sanitize.SearchQuery("Paul + Paula")); len(w) == 2 {
assert.Equal(t, "name LIKE '%Paul%'", w[0])
assert.Equal(t, "name LIKE '%Paula%'", w[1])
} else {
@ -215,7 +215,7 @@ func TestLikeAllNames(t *testing.T) {
}
})
t.Run("And", func(t *testing.T) {
if w := LikeAllNames(Cols{"name"}, sanitize.Query("P and Paula")); len(w) == 2 {
if w := LikeAllNames(Cols{"name"}, sanitize.SearchQuery("P and Paula")); len(w) == 2 {
assert.Equal(t, "name LIKE '%P%'", w[0])
assert.Equal(t, "name LIKE '%Paula%'", w[1])
} else {
@ -223,7 +223,7 @@ func TestLikeAllNames(t *testing.T) {
}
})
t.Run("Or", func(t *testing.T) {
if w := LikeAllNames(Cols{"name"}, sanitize.Query("Paul or Paula")); len(w) == 1 {
if w := LikeAllNames(Cols{"name"}, sanitize.SearchQuery("Paul or Paula")); len(w) == 1 {
assert.Equal(t, "name LIKE '%Paul%' OR name LIKE '%Paula%'", w[0])
} else {
t.Fatalf("unexpected result: %#v", w)

View file

@ -162,5 +162,5 @@ func SubjectUIDs(s string) (result []string, names []string, remaining string) {
result = append(result, strings.Join(subj, txt.Or))
}
return result, names, sanitize.Query(remaining)
return result, names, sanitize.SearchQuery(remaining)
}

View file

@ -1,18 +0,0 @@
package sanitize
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestQuery(t *testing.T) {
t.Run("Replace", func(t *testing.T) {
q := Query("table spoon & usa | img% json OR BILL!\n")
assert.Equal(t, "table spoon & usa | img* json|BILL!", q)
})
t.Run("AndOr", func(t *testing.T) {
q := Query("Jens AND Mander and me Or Kitty AND ")
assert.Equal(t, "Jens&Mander&me|Kitty", q)
})
}

View file

@ -15,8 +15,23 @@ func replace(subject string, search string, replace string) string {
return regexp.MustCompile("(?i)"+search).ReplaceAllString(subject, replace)
}
// Query replaces search operator with default symbols.
func Query(s string) string {
// SearchString replaces search operator with default symbols.
func SearchString(s string) string {
if s == "" || reject(s, MaxLength) {
return Empty
}
// Normalize.
s = strings.ReplaceAll(s, "%%", "%")
s = strings.ReplaceAll(s, "%", "*")
s = strings.ReplaceAll(s, "**", "*")
// Trim.
return strings.Trim(s, "&|\\<>\n\r\t")
}
// SearchQuery replaces search operator with default symbols.
func SearchQuery(s string) string {
if s == "" || reject(s, MaxLength) {
return Empty
}
@ -29,7 +44,9 @@ func Query(s string) string {
s = replace(s, spaced(EnIn), And)
s = replace(s, spaced(EnAt), And)
s = strings.ReplaceAll(s, SpacedPlus, And)
s = strings.ReplaceAll(s, "%%", "%")
s = strings.ReplaceAll(s, "%", "*")
s = strings.ReplaceAll(s, "**", "*")
// Trim.
return strings.Trim(s, "+&|-=$^(){}\\<>,;: \n\r\t")

View file

@ -0,0 +1,37 @@
package sanitize
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSearchString(t *testing.T) {
t.Run("Replace", func(t *testing.T) {
q := SearchString("table spoon & usa | img% json OR BILL!\n")
assert.Equal(t, "table spoon & usa | img* json OR BILL!", q)
})
t.Run("AndOr", func(t *testing.T) {
q := SearchString("Jens AND Mander and me Or Kitty AND ")
assert.Equal(t, "Jens AND Mander and me Or Kitty AND ", q)
})
t.Run("FlowersInThePark", func(t *testing.T) {
q := SearchString(" Flowers in the Park ")
assert.Equal(t, " Flowers in the Park ", q)
})
}
func TestSearchQuery(t *testing.T) {
t.Run("Replace", func(t *testing.T) {
q := SearchQuery("table spoon & usa | img% json OR BILL!\n")
assert.Equal(t, "table spoon & usa | img* json|BILL!", q)
})
t.Run("AndOr", func(t *testing.T) {
q := SearchQuery("Jens AND Mander and me Or Kitty AND ")
assert.Equal(t, "Jens&Mander&me|Kitty", q)
})
t.Run("FlowersInThePark", func(t *testing.T) {
q := SearchQuery(" Flowers in the Park ")
assert.Equal(t, "Flowers&the Park", q)
})
}