|
@@ -47,25 +47,13 @@ func getHomeDir() (string, error) {
|
|
|
return os.UserHomeDir()
|
|
|
}
|
|
|
|
|
|
-var (
|
|
|
- windowsDisallowedCharacters = string([]rune{
|
|
|
- '<', '>', ':', '"', '|', '?', '*',
|
|
|
- 0, 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,
|
|
|
- })
|
|
|
- windowsDisallowedNames = []string{"CON", "PRN", "AUX", "NUL",
|
|
|
- "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
|
|
|
- "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
|
|
|
- }
|
|
|
-)
|
|
|
+const windowsDisallowedCharacters = (`<>:"|?*` +
|
|
|
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" +
|
|
|
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f")
|
|
|
|
|
|
func WindowsInvalidFilename(name string) error {
|
|
|
// None of the path components should end in space or period, or be a
|
|
|
- // reserved name. COM0 and LPT0 are missing from the Microsoft docs,
|
|
|
- // but Windows Explorer treats them as invalid too.
|
|
|
- // (https://docs.microsoft.com/windows/win32/fileio/naming-a-file)
|
|
|
+ // reserved name.
|
|
|
for _, part := range strings.Split(name, `\`) {
|
|
|
if len(part) == 0 {
|
|
|
continue
|
|
@@ -110,7 +98,7 @@ func WindowsInvalidFilename(name string) error {
|
|
|
func SanitizePath(path string) string {
|
|
|
var b strings.Builder
|
|
|
|
|
|
- disallowed := `<>:"'/\|?*[]{};:!@$%&^#` + windowsDisallowedCharacters
|
|
|
+ const disallowed = `'/\[]{};:!@$%&^#` + windowsDisallowedCharacters
|
|
|
prev := ' '
|
|
|
for _, c := range path {
|
|
|
if !unicode.IsPrint(c) || c == unicode.ReplacementChar ||
|
|
@@ -132,15 +120,27 @@ func SanitizePath(path string) string {
|
|
|
}
|
|
|
|
|
|
func windowsIsReserved(part string) bool {
|
|
|
- upperCased := strings.ToUpper(part)
|
|
|
- for _, disallowed := range windowsDisallowedNames {
|
|
|
- if upperCased == disallowed {
|
|
|
- return true
|
|
|
- }
|
|
|
- if strings.HasPrefix(upperCased, disallowed+".") {
|
|
|
- // nul.txt.jpg is also disallowed
|
|
|
- return true
|
|
|
- }
|
|
|
+ // nul.txt.jpg is also disallowed.
|
|
|
+ dot := strings.IndexByte(part, '.')
|
|
|
+ if dot != -1 {
|
|
|
+ part = part[:dot]
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check length to skip allocating ToUpper.
|
|
|
+ if len(part) != 3 && len(part) != 4 {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // COM0 and LPT0 are missing from the Microsoft docs,
|
|
|
+ // but Windows Explorer treats them as invalid too.
|
|
|
+ // (https://docs.microsoft.com/windows/win32/fileio/naming-a-file)
|
|
|
+ switch strings.ToUpper(part) {
|
|
|
+ case "CON", "PRN", "AUX", "NUL",
|
|
|
+ "COM0", "COM1", "COM2", "COM3", "COM4",
|
|
|
+ "COM5", "COM6", "COM7", "COM8", "COM9",
|
|
|
+ "LPT0", "LPT1", "LPT2", "LPT3", "LPT4",
|
|
|
+ "LPT5", "LPT6", "LPT7", "LPT8", "LPT9":
|
|
|
+ return true
|
|
|
}
|
|
|
return false
|
|
|
}
|