mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Settings: Use PHOTOPRISM_DISABLE_FEATURES to initialize default features
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
35
pkg/clean/fieldname.go
Normal file
35
pkg/clean/fieldname.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FieldName normalizes a struct field identifier so it can be compared safely.
|
||||
// It strips all characters outside [A-Za-z0-9], rejects empty strings, and
|
||||
// returns an empty string for inputs longer than 255 bytes to avoid abuse.
|
||||
func FieldName(s string) string {
|
||||
if s == "" || len(s) > 255 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Remove all invalid characters.
|
||||
s = strings.Map(func(r rune) rune {
|
||||
if (r < '0' || r > '9') && (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') {
|
||||
return -1
|
||||
}
|
||||
|
||||
return r
|
||||
}, s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// FieldNameLower normalizes a struct field identifier and lowercases it first.
|
||||
// Useful when callers want case-insensitive comparisons against normalized data.
|
||||
func FieldNameLower(s string) string {
|
||||
if s == "" || len(s) > 255 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return FieldName(strings.ToLower(s))
|
||||
}
|
||||
49
pkg/clean/fieldname_test.go
Normal file
49
pkg/clean/fieldname_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFieldName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{name: "Path", in: "/go/src/github.com/photoprism/photoprism", want: "gosrcgithubcomphotoprismphotoprism"},
|
||||
{name: "DotsAndUpper", in: "filename.TXT", want: "filenameTXT"},
|
||||
{name: "SpacesAndPunctuation", in: "The quick brown fox.", want: "Thequickbrownfox"},
|
||||
{name: "QuestionAndDot", in: "file?name.jpg", want: "filenamejpg"},
|
||||
{name: "ControlCharacter", in: "filename." + string(rune(127)), want: "filename"},
|
||||
{name: "Empty", in: "", want: ""},
|
||||
{name: "TooLong", in: strings.Repeat("a", 256), want: ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, FieldName(tt.in))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldNameLower(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{name: "LowerCase", in: "file?name.JPG", want: "filenamejpg"},
|
||||
{name: "UpperOnly", in: "ABC", want: "abc"},
|
||||
{name: "MixedSeparators", in: "Album-Photos_123", want: "albumphotos123"},
|
||||
{name: "TooLong", in: strings.Repeat("B", 300), want: ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, FieldNameLower(tt.in))
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user