Skip to content

Commit 6542b2f

Browse files
ag-eitilthasufell
authored andcommitted
Make Windows.isValid reject paths ending in a dot or space
1 parent 1d984dd commit 6542b2f

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

System/FilePath/Internal.hs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,10 @@ badElements =
927927
-- > Windows: isValid "\\\\\\foo" == False
928928
-- > Windows: isValid "\\\\?\\D:file" == False
929929
-- > Windows: isValid "foo\tbar" == False
930+
-- > Windows: isValid "foo." == False
931+
-- > Windows: isValid "foo " == False
932+
-- > Windows: isValid "foo.\\bar" == False
933+
-- > Windows: isValid "foo \\bar" == False
930934
-- > Windows: isValid "nul .txt" == False
931935
-- > Windows: isValid " nul.txt" == True
932936
isValid :: FilePath -> Bool
@@ -936,11 +940,15 @@ isValid _ | isPosix = True
936940
isValid path =
937941
not (any isBadCharacter x2) &&
938942
not (any f $ splitDirectories x2) &&
943+
not (any g $ splitDirectories x2) &&
939944
not (isJust (readDriveShare x1) && all isPathSeparator x1) &&
940945
not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))
941946
where
942947
(x1,x2) = splitDrive path
943948
f x = map toUpper (dropWhileEnd (== ' ') $ dropExtensions x) `elem` badElements
949+
g "." = False
950+
g ".." = False
951+
g x = head (reverse $ '@' : x) `elem` ". "
944952

945953

946954
-- | Take a FilePath and make it valid; does not change already valid FilePaths.
@@ -952,6 +960,8 @@ isValid path =
952960
-- > Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
953961
-- > Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
954962
-- > Windows: makeValid "test*" == "test_"
963+
-- > Windows: makeValid "test." == "test._"
964+
-- > Windows: makeValid "test " == "test _"
955965
-- > Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
956966
-- > Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
957967
-- > Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
@@ -974,10 +984,13 @@ makeValid path
974984
f x = if isBadCharacter x then '_' else x
975985

976986
validElements x = joinPath $ map g $ splitPath x
977-
g x = h a ++ b
987+
g x = i (h a) ++ b
978988
where (a,b) = break isPathSeparator x
979989
h x = if map toUpper (dropWhileEnd (== ' ') a) `elem` badElements then a ++ "_" <.> b else x
980990
where (a,b) = splitExtensions x
991+
i "." = "."
992+
i ".." = ".."
993+
i x = if head (reverse $ '@' : x) `elem` ". " then x ++ "_" else x
981994

982995

983996
-- | Is a path relative, or is it fixed to the root?

System/FilePath/Posix.hs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,10 @@ badElements =
927927
-- > Windows: isValid "\\\\\\foo" == False
928928
-- > Windows: isValid "\\\\?\\D:file" == False
929929
-- > Windows: isValid "foo\tbar" == False
930+
-- > Windows: isValid "foo." == False
931+
-- > Windows: isValid "foo " == False
932+
-- > Windows: isValid "foo.\\bar" == False
933+
-- > Windows: isValid "foo \\bar" == False
930934
-- > Windows: isValid "nul .txt" == False
931935
-- > Windows: isValid " nul.txt" == True
932936
isValid :: FilePath -> Bool
@@ -936,11 +940,15 @@ isValid _ | isPosix = True
936940
isValid path =
937941
not (any isBadCharacter x2) &&
938942
not (any f $ splitDirectories x2) &&
943+
not (any g $ splitDirectories x2) &&
939944
not (isJust (readDriveShare x1) && all isPathSeparator x1) &&
940945
not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))
941946
where
942947
(x1,x2) = splitDrive path
943948
f x = map toUpper (dropWhileEnd (== ' ') $ dropExtensions x) `elem` badElements
949+
g "." = False
950+
g ".." = False
951+
g x = head (reverse $ '@' : x) `elem` ". "
944952

945953

946954
-- | Take a FilePath and make it valid; does not change already valid FilePaths.
@@ -952,6 +960,8 @@ isValid path =
952960
-- > Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
953961
-- > Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
954962
-- > Windows: makeValid "test*" == "test_"
963+
-- > Windows: makeValid "test." == "test._"
964+
-- > Windows: makeValid "test " == "test _"
955965
-- > Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
956966
-- > Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
957967
-- > Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
@@ -974,10 +984,13 @@ makeValid path
974984
f x = if isBadCharacter x then '_' else x
975985

976986
validElements x = joinPath $ map g $ splitPath x
977-
g x = h a ++ b
987+
g x = i (h a) ++ b
978988
where (a,b) = break isPathSeparator x
979989
h x = if map toUpper (dropWhileEnd (== ' ') a) `elem` badElements then a ++ "_" <.> b else x
980990
where (a,b) = splitExtensions x
991+
i "." = "."
992+
i ".." = ".."
993+
i x = if head (reverse $ '@' : x) `elem` ". " then x ++ "_" else x
981994

982995

983996
-- | Is a path relative, or is it fixed to the root?

System/FilePath/Windows.hs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,10 @@ badElements =
927927
-- > Windows: isValid "\\\\\\foo" == False
928928
-- > Windows: isValid "\\\\?\\D:file" == False
929929
-- > Windows: isValid "foo\tbar" == False
930+
-- > Windows: isValid "foo." == False
931+
-- > Windows: isValid "foo " == False
932+
-- > Windows: isValid "foo.\\bar" == False
933+
-- > Windows: isValid "foo \\bar" == False
930934
-- > Windows: isValid "nul .txt" == False
931935
-- > Windows: isValid " nul.txt" == True
932936
isValid :: FilePath -> Bool
@@ -936,11 +940,15 @@ isValid _ | isPosix = True
936940
isValid path =
937941
not (any isBadCharacter x2) &&
938942
not (any f $ splitDirectories x2) &&
943+
not (any g $ splitDirectories x2) &&
939944
not (isJust (readDriveShare x1) && all isPathSeparator x1) &&
940945
not (isJust (readDriveUNC x1) && not (hasTrailingPathSeparator x1))
941946
where
942947
(x1,x2) = splitDrive path
943948
f x = map toUpper (dropWhileEnd (== ' ') $ dropExtensions x) `elem` badElements
949+
g "." = False
950+
g ".." = False
951+
g x = head (reverse $ '@' : x) `elem` ". "
944952

945953

946954
-- | Take a FilePath and make it valid; does not change already valid FilePaths.
@@ -952,6 +960,8 @@ isValid path =
952960
-- > Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
953961
-- > Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
954962
-- > Windows: makeValid "test*" == "test_"
963+
-- > Windows: makeValid "test." == "test._"
964+
-- > Windows: makeValid "test " == "test _"
955965
-- > Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
956966
-- > Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
957967
-- > Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
@@ -974,10 +984,13 @@ makeValid path
974984
f x = if isBadCharacter x then '_' else x
975985

976986
validElements x = joinPath $ map g $ splitPath x
977-
g x = h a ++ b
987+
g x = i (h a) ++ b
978988
where (a,b) = break isPathSeparator x
979989
h x = if map toUpper (dropWhileEnd (== ' ') a) `elem` badElements then a ++ "_" <.> b else x
980990
where (a,b) = splitExtensions x
991+
i "." = "."
992+
i ".." = ".."
993+
i x = if head (reverse $ '@' : x) `elem` ". " then x ++ "_" else x
981994

982995

983996
-- | Is a path relative, or is it fixed to the root?

tests/TestGen.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ tests =
427427
,("W.isValid \"\\\\\\\\\\\\foo\" == False", property $ W.isValid "\\\\\\foo" == False)
428428
,("W.isValid \"\\\\\\\\?\\\\D:file\" == False", property $ W.isValid "\\\\?\\D:file" == False)
429429
,("W.isValid \"foo\\tbar\" == False", property $ W.isValid "foo\tbar" == False)
430+
,("W.isValid \"foo.\" == False", property $ W.isValid "foo." == False)
431+
,("W.isValid \"foo \" == False", property $ W.isValid "foo " == False)
432+
,("W.isValid \"foo.\\\\bar\" == False", property $ W.isValid "foo.\\bar" == False)
433+
,("W.isValid \"foo \\\\bar\" == False", property $ W.isValid "foo \\bar" == False)
430434
,("W.isValid \"nul .txt\" == False", property $ W.isValid "nul .txt" == False)
431435
,("W.isValid \" nul.txt\" == True", property $ W.isValid " nul.txt" == True)
432436
,("P.isValid (P.makeValid x)", property $ \(QFilePath x) -> P.isValid (P.makeValid x))
@@ -440,6 +444,8 @@ tests =
440444
,("W.makeValid \"c:\\\\already\\\\/valid\" == \"c:\\\\already\\\\/valid\"", property $ W.makeValid "c:\\already\\/valid" == "c:\\already\\/valid")
441445
,("W.makeValid \"c:\\\\test:of_test\" == \"c:\\\\test_of_test\"", property $ W.makeValid "c:\\test:of_test" == "c:\\test_of_test")
442446
,("W.makeValid \"test*\" == \"test_\"", property $ W.makeValid "test*" == "test_")
447+
,("W.makeValid \"test.\" == \"test._\"", property $ W.makeValid "test." == "test._")
448+
,("W.makeValid \"test \" == \"test _\"", property $ W.makeValid "test " == "test _")
443449
,("W.makeValid \"c:\\\\test\\\\nul\" == \"c:\\\\test\\\\nul_\"", property $ W.makeValid "c:\\test\\nul" == "c:\\test\\nul_")
444450
,("W.makeValid \"c:\\\\test\\\\prn.txt\" == \"c:\\\\test\\\\prn_.txt\"", property $ W.makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt")
445451
,("W.makeValid \"c:\\\\test/prn.txt\" == \"c:\\\\test/prn_.txt\"", property $ W.makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt")

0 commit comments

Comments
 (0)