lib/fs: Clarify errors for Windows filenames (fixes #8968) (#8969)

With this change, error messages include the offending characters or
name parts. Examples:

    nul.txt: name is invalid, contains Windows reserved name: "nul"
    foo>bar.txt: name is invalid, contains Windows reserved character: ">"
    foo \bar.txt: name is invalid, must not end in space or period on Windows
This commit is contained in:
Jakob Borg
2023-07-07 11:00:40 +00:00
committed by GitHub
parent 6ff5ed6d23
commit c44de2cd58
3 changed files with 16 additions and 12 deletions
+9 -9
View File
@@ -54,8 +54,8 @@ const windowsDisallowedCharacters = (`<>:"|?*` +
func WindowsInvalidFilename(name string) error {
// The path must not contain any disallowed characters.
if strings.ContainsAny(name, windowsDisallowedCharacters) {
return errInvalidFilenameWindowsReservedChar
if idx := strings.IndexAny(name, windowsDisallowedCharacters); idx != -1 {
return fmt.Errorf("%w: %q", errInvalidFilenameWindowsReservedChar, name[idx:idx+1])
}
// None of the path components should end in space or period, or be a
@@ -72,8 +72,8 @@ func WindowsInvalidFilename(name string) error {
// Names ending in space or period are not valid.
return errInvalidFilenameWindowsSpacePeriod
}
if windowsIsReserved(part) {
return errInvalidFilenameWindowsReservedName
if reserved := windowsReservedNamePart(part); reserved != "" {
return fmt.Errorf("%w: %q", errInvalidFilenameWindowsReservedName, reserved)
}
}
@@ -117,13 +117,13 @@ func SanitizePath(path string) string {
}
path = strings.TrimSpace(b.String())
if windowsIsReserved(path) {
if reserved := windowsReservedNamePart(path); reserved != "" {
path = "-" + path
}
return path
}
func windowsIsReserved(part string) bool {
func windowsReservedNamePart(part string) string {
// nul.txt.jpg is also disallowed.
dot := strings.IndexByte(part, '.')
if dot != -1 {
@@ -132,7 +132,7 @@ func windowsIsReserved(part string) bool {
// Check length to skip allocating ToUpper.
if len(part) != 3 && len(part) != 4 {
return false
return ""
}
// COM0 and LPT0 are missing from the Microsoft docs,
@@ -144,9 +144,9 @@ func windowsIsReserved(part string) bool {
"COM5", "COM6", "COM7", "COM8", "COM9",
"LPT0", "LPT1", "LPT2", "LPT3", "LPT4",
"LPT5", "LPT6", "LPT7", "LPT8", "LPT9":
return true
return part
}
return false
return ""
}
// IsParent compares paths purely lexicographically, meaning it returns false