-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsanitize.go
More file actions
57 lines (51 loc) · 1.4 KB
/
Copy pathsanitize.go
File metadata and controls
57 lines (51 loc) · 1.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package storage
import (
"path/filepath"
"strings"
"unicode"
)
const defaultName = "default"
// SanitizeName validates strings for use as filename.
func SanitizeName(input string, maxLength int, extraChars string) string {
f := filepath.Base(input)
f = removeInvalidChars(f, extraChars)
ext := filepath.Ext(f)
base := strings.TrimSuffix(f, ext)
if base == "" {
base = defaultName
}
return truncateName(base, ext, maxLength)
}
// removeInvalidChars removes all invalid characters.
func removeInvalidChars(filename string, allowed string) string {
var result strings.Builder
for _, char := range filename {
if unicode.IsDigit(char) ||
unicode.IsLetter(char) ||
isAllowedChar(char, allowed) {
result.WriteRune(char)
}
}
return result.String()
}
// truncateName trims a filename string to max size,
// preserving reasonably-sized original file extensions.
func truncateName(base string, ext string, maxLength int) string {
const maxExtensionLength = 5
if len(ext) > maxExtensionLength {
ext = ext[:maxExtensionLength]
}
totalLength := len(base) + len(ext)
if totalLength <= maxLength {
return base + ext
}
allowedBaseLength := maxLength - len(ext)
if allowedBaseLength > 0 {
return base[:allowedBaseLength] + ext
}
return ext[:maxLength]
}
// isAllowedChar returns true if a character is allowed.
func isAllowedChar(r rune, allowed string) bool {
return strings.ContainsRune(allowed, r)
}