From 4cf5d70b15ef0e2ce959d4bda528a236ee394149 Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Sun, 21 Jan 2024 20:28:36 +0000 Subject: [PATCH] Fix regression of splitFileName on '//?/A:' --- System/FilePath/Internal.hs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/System/FilePath/Internal.hs b/System/FilePath/Internal.hs index 786eb3a3..2dce4c64 100644 --- a/System/FilePath/Internal.hs +++ b/System/FilePath/Internal.hs @@ -644,15 +644,26 @@ splitFileName_ fp -- or UNC location "\\?\UNC\foo", where path separator is a part of the drive name. -- We can test this by trying dropDrive and falling back to splitDrive. | isWindows - , Just (s1, _s2, bs') <- uncons2 dirSlash - , isPathSeparator s1 - -- If bs' is empty, then s2 as the last character of dirSlash must be a path separator, - -- so we are in the middle of shared drive. - -- Otherwise, since s1 is a path separator, we might be in the middle of UNC path. - , null bs' || maybe False isIncompleteUNC (readDriveUNC dirSlash) - = (fp, mempty) + = case uncons2 dirSlash of + Just (s1, s2, bs') + | isPathSeparator s1 + -- If bs' is empty, then s2 as the last character of dirSlash must be a path separator, + -- so we are in the middle of shared drive. + -- Otherwise, since s1 is a path separator, we might be in the middle of UNC path. + , null bs' || maybe False isIncompleteUNC (readDriveUNC dirSlash) + -> (fp, mempty) + -- This handles inputs like "//?/A:" and "//?/A:foo" + | isPathSeparator s1 + , isPathSeparator s2 + , Just (s3, s4, bs'') <- uncons2 bs' + , s3 == _question + , isPathSeparator s4 + , null bs'' + , Just (drive, rest) <- readDriveLetter file + -> (dirSlash <> drive, rest) + _ -> (dirSlash, file) | otherwise - = (dirSlash, file) + = (dirSlash, file) where (dirSlash, file) = breakEnd isPathSeparator fp