Search: Improve input sanitation and filter queries #1994 #2079 #2181

This commit is contained in:
Michael Mayer 2022-03-25 18:01:34 +01:00
parent bd5c773232
commit e77a029f13
7 changed files with 28 additions and 15 deletions

View file

@ -143,7 +143,6 @@ func NewFolderAlbum(albumTitle, albumPath, albumFilter string) *Album {
result := &Album{
AlbumOrder: SortOrderAdded,
AlbumType: AlbumFolder,
AlbumTitle: txt.Clip(albumTitle, txt.ClipDefault),
AlbumSlug: txt.Clip(albumSlug, txt.ClipSlug),
AlbumPath: txt.Clip(albumPath, txt.ClipPath),
AlbumFilter: albumFilter,
@ -151,6 +150,8 @@ func NewFolderAlbum(albumTitle, albumPath, albumFilter string) *Album {
UpdatedAt: now,
}
result.SetTitle(albumTitle)
return result
}
@ -165,13 +166,14 @@ func NewMomentsAlbum(albumTitle, albumSlug, albumFilter string) *Album {
result := &Album{
AlbumOrder: SortOrderOldest,
AlbumType: AlbumMoment,
AlbumTitle: txt.Clip(albumTitle, txt.ClipDefault),
AlbumSlug: txt.Clip(albumSlug, txt.ClipSlug),
AlbumFilter: albumFilter,
CreatedAt: now,
UpdatedAt: now,
}
result.SetTitle(albumTitle)
return result
}
@ -189,13 +191,14 @@ func NewStateAlbum(albumTitle, albumSlug, albumFilter string) *Album {
result := &Album{
AlbumOrder: SortOrderNewest,
AlbumType: AlbumState,
AlbumTitle: txt.Clip(albumTitle, txt.ClipDefault),
AlbumSlug: txt.Clip(albumSlug, txt.ClipSlug),
AlbumFilter: albumFilter,
CreatedAt: now,
UpdatedAt: now,
}
result.SetTitle(albumTitle)
return result
}
@ -219,7 +222,6 @@ func NewMonthAlbum(albumTitle, albumSlug string, year, month int) *Album {
result := &Album{
AlbumOrder: SortOrderOldest,
AlbumType: AlbumMonth,
AlbumTitle: albumTitle,
AlbumSlug: albumSlug,
AlbumFilter: f.Serialize(),
AlbumYear: year,
@ -228,6 +230,8 @@ func NewMonthAlbum(albumTitle, albumSlug string, year, month int) *Album {
UpdatedAt: now,
}
result.SetTitle(albumTitle)
return result
}
@ -367,13 +371,15 @@ func (m *Album) IsDefault() bool {
// SetTitle changes the album name.
func (m *Album) SetTitle(title string) {
title = strings.TrimSpace(title)
title = strings.Trim(title, "_&|{}<>: \n\r\t\\")
title = strings.ReplaceAll(title, "\"", "'")
title = txt.Shorten(title, txt.ClipDefault, txt.Ellipsis)
if title == "" {
title = m.CreatedAt.Format("January 2006")
}
m.AlbumTitle = txt.Clip(title, txt.ClipDefault)
m.AlbumTitle = title
if m.AlbumType == AlbumDefault || m.AlbumSlug == "" {
if len(m.AlbumTitle) < txt.ClipSlug {
@ -408,7 +414,9 @@ func (m *Album) UpdateSlug(title, slug string) error {
return nil
}
m.AlbumTitle = title
if title != "" {
m.SetTitle(title)
}
return m.Updates(Values{"album_title": m.AlbumTitle, "album_slug": m.AlbumSlug})
}
@ -449,7 +457,9 @@ func (m *Album) UpdateState(title, slug, stateName, countryCode string) error {
return nil
}
m.AlbumTitle = title
if title != "" {
m.SetTitle(title)
}
return m.Updates(Values{"album_title": m.AlbumTitle, "album_slug": m.AlbumSlug, "album_location": m.AlbumLocation, "album_country": m.AlbumCountry, "album_state": m.AlbumState})
}

View file

@ -60,7 +60,7 @@ the further from the equator you get. The precision of the latitude part does no
more strictly however, a meridian arc length per 1 second depends on the latitude at the point in question.
The discrepancy of 1 second meridian arc length between equator and pole is about 0.3 metres because the earth
is an oblate spheroid.`
expected := txt.Clip(longName, txt.ClipDefault)
expected := txt.Shorten(longName, txt.ClipDefault, txt.Ellipsis)
slugExpected := txt.Clip(longName, txt.ClipSlug)
album := NewAlbum(longName, AlbumDefault)
assert.Equal(t, expected, album.AlbumTitle)

View file

@ -26,6 +26,8 @@ func (m *Photo) NoTitle() bool {
// SetTitle changes the photo title and clips it to 300 characters.
func (m *Photo) SetTitle(title, source string) {
title = strings.Trim(title, "_&|{}<>: \n\r\t\\")
title = strings.ReplaceAll(title, "\"", "'")
title = txt.Shorten(title, txt.ClipTitle, txt.Ellipsis)
if title == "" {

View file

@ -306,7 +306,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
s = s.Where("photos.camera_id = ?", txt.UInt(f.Camera))
} else if txt.NotEmpty(f.Camera) {
v := strings.Trim(f.Camera, "*%") + "%"
s = s.Where("cameras.camera_make LIKE ? OR cameras.camera_model LIKE ? OR cameras.camera_slug LIKE ?", v, v, v)
s = s.Where("cameras.camera_name LIKE ? OR cameras.camera_model LIKE ? OR cameras.camera_slug LIKE ?", v, v, v)
}
// Filter by lens id or name?
@ -314,7 +314,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
s = s.Where("photos.lens_id = ?", txt.UInt(f.Lens))
} else if txt.NotEmpty(f.Lens) {
v := strings.Trim(f.Lens, "*%") + "%"
s = s.Where("lenses.lens_make LIKE ? OR lenses.lens_model LIKE ? OR lenses.lens_slug LIKE ?", v, v, v)
s = s.Where("lenses.lens_name LIKE ? OR lenses.lens_model LIKE ? OR lenses.lens_slug LIKE ?", v, v, v)
}
// Filter by year?

View file

@ -27,7 +27,7 @@ func SearchString(s string) string {
s = strings.ReplaceAll(s, "**", "*")
// Trim.
return strings.Trim(s, "&|\\<>\n\r\t")
return strings.Trim(s, "|\\<>\n\r\t")
}
// SearchQuery replaces search operator with default symbols.
@ -49,5 +49,5 @@ func SearchQuery(s string) string {
s = strings.ReplaceAll(s, "**", "*")
// Trim.
return strings.Trim(s, "+&|-=$^(){}\\<>,;: \n\r\t")
return strings.Trim(s, "|${}\\<>: \n\r\t")
}

View file

@ -28,7 +28,7 @@ func TestSearchQuery(t *testing.T) {
})
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)
assert.Equal(t, "Jens&Mander&me|Kitty&", q)
})
t.Run("FlowersInThePark", func(t *testing.T) {
q := SearchQuery(" Flowers in the Park ")

View file

@ -5,7 +5,8 @@ import (
)
// sqlSpecialBytes contains special bytes to escape in SQL search queries.
var sqlSpecialBytes = []byte{34, 39, 92, 95}
// see https://mariadb.com/kb/en/string-literals/
var sqlSpecialBytes = []byte{34, 39, 92, 95} // ", ', \, _
// SqlString escapes a string for use in an SQL query.
func SqlString(s string) string {