lib/fs: Be even more strict about Windows names (ref #7008) (#7012)

Things like nul.whatever.txt are also not allowed.
This commit is contained in:
Jakob Borg 2020-09-28 10:42:37 +02:00 committed by GitHub
parent 9e0b924d57
commit e6b1f67ecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 13 deletions

View File

@ -44,13 +44,19 @@ func getHomeDir() (string, error) {
return os.UserHomeDir() return os.UserHomeDir()
} }
var windowsDisallowedCharacters = string([]rune{ var (
windowsDisallowedCharacters = string([]rune{
'<', '>', ':', '"', '|', '?', '*', '<', '>', ':', '"', '|', '?', '*',
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 31,
}) })
windowsDisallowedNames = []string{"CON", "PRN", "AUX", "NUL",
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
}
)
func WindowsInvalidFilename(name string) error { func WindowsInvalidFilename(name string) error {
// None of the path components should end in space or period, or be a // None of the path components should end in space or period, or be a
@ -65,13 +71,16 @@ func WindowsInvalidFilename(name string) error {
// Names ending in space or period are not valid. // Names ending in space or period are not valid.
return errInvalidFilenameWindowsSpacePeriod return errInvalidFilenameWindowsSpacePeriod
} }
switch strings.ToUpper(part) { upperCased := strings.ToUpper(part)
case "CON", "PRN", "AUX", "NUL", for _, disallowed := range windowsDisallowedNames {
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", if upperCased == disallowed {
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9":
// These reserved names are not valid.
return errInvalidFilenameWindowsReservedName return errInvalidFilenameWindowsReservedName
} }
if strings.HasPrefix(upperCased, disallowed+".") {
// nul.txt.jpg is also disallowed
return errInvalidFilenameWindowsReservedName
}
}
} }
// The path must not contain any disallowed characters // The path must not contain any disallowed characters

View File

@ -44,3 +44,29 @@ func TestCommonPrefix(t *testing.T) {
test(`Audrius`, `Audrius`, `Audrius`) test(`Audrius`, `Audrius`, `Audrius`)
test(`.`, `.`, `.`) test(`.`, `.`, `.`)
} }
func TestWindowsInvalidFilename(t *testing.T) {
cases := []struct {
name string
err error
}{
{`asdf.txt`, nil},
{`nul`, errInvalidFilenameWindowsReservedName},
{`nul.txt`, errInvalidFilenameWindowsReservedName},
{`nul.jpg.txt`, errInvalidFilenameWindowsReservedName},
{`some.nul.jpg`, nil},
{`foo>bar.txt`, errInvalidFilenameWindowsReservedChar},
{`foo \bar.txt`, errInvalidFilenameWindowsSpacePeriod},
{`foo.\bar.txt`, errInvalidFilenameWindowsSpacePeriod},
{`foo.d\bar.txt`, nil},
{`foo.d\bar .txt`, nil},
{`foo.d\bar. txt`, nil},
}
for _, tc := range cases {
err := WindowsInvalidFilename(tc.name)
if err != tc.err {
t.Errorf("For %q, got %v, expected %v", tc.name, err, tc.err)
}
}
}