normalise should not alter paths that start with \\?\
From https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath :
They indicate that the path should be passed to the system with minimal modification, which means that you cannot use forward slashes to represent path separators, or a period to represent the current directory, or double dots to represent the parent directory.
My take from this is that whenever \\?\ is at the beginning of a path, then everything afterward must interpreted literally. Specifically:
-
/should be understood as a normal character, not a path separator -
.and..should be understood as normal path segments, not special directories
This means whenever normalise sees a path that starts with \\?\, it should basically do nothing at all.
As of filepath-1.4.1.0, normalise "\\\\?\\C:\\.\\Windows/" == "\\\\?\\C:\\Windows\\", which is incorrect according to MSDN. Instead, it should remain as is.
If we do that, can things like takeExtension work? Since they are implicitly playing around with knowledge of the structure of \\?\ paths.
I am inclined to agree that treating \\?\ specially for normalise sounds like a good idea.
If we do that, can things like
takeExtensionwork? Since they are implicitly playing around with knowledge of the structure of\\?\paths.
I guess the problem runs deeper than just normalise. For example, the various split functions likely have the same problem.
Yep. I think we have to do what is pragmatic, rather than necessarily semantically precise. My inclination is normalise does nothing, everything else works as is.
Another oddity I discovered:
*System.FilePath W> W.normalise "D:file"
"D:file"
*System.FilePath W> W.normalise "\\\\?\\D:file"
"\\\\?\\D:\\file"
In the second case it actually changes semantics.
As I got into the details of normalise I found out it was hilariously slow and had about a million really crazy corner cases. I rewrote it for Shake as normaliseEx - https://hackage.haskell.org/package/shake-0.19.6/docs/Development-Shake-FilePath.html#v:normaliseEx. My intention was to replace this one wholesale with that, including the test suite for normaliseEx which is in Shake.