[GHC] #8752: System.FilePath.Windows.combine does not really check isAbsolute
GHC
ghc-devs at haskell.org
Mon Sep 15 17:25:30 UTC 2014
#8752: System.FilePath.Windows.combine does not really check isAbsolute
-------------------------------------+-------------------------------------
Reporter: joeyhess | Owner: thomie
Type: bug | Status: new
Priority: normal | Milestone:
Component: libraries | Version: 7.9
(other) | Keywords: filepath
Resolution: | Architecture: Unknown/Multiple
Operating System: Windows | Difficulty: Unknown
Type of failure: | Blocked By:
None/Unknown | Related Tickets:
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by thomie):
Can you explain why the docstring I posed is confusing? It is valid for
both Posix as Windows, so it's not really a caveat.
Correct me if I'm wrong, but the way I understand it is that on
[http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx
Windows], if a filepath starts with a single slash, it is considered to be
relative to the root of the current drive. The system keeps track of the
current drive along with the current directory of that drive.
Currently, if the second argument starts with a slash, `combine` returns
it as is. The implementation is essentially:
{{{
combine a b | hasDrive b || hasLeadingPathSeparator b = b
| otherwise = combineAlways a b
}}}
I am guessing you are looking for the following behavior:
{{{
combine "C:\\" "\\foo\\bar" == "C:\\foo\\bar"
combine "C:\\STUFF" "\\foo\\bar" == "C:\\foo\\bar"
combine ""\\\\shared" "\\foo\\bar" == "\\\\shared\\foo\\bar"
combine ""\\\\shared\\stuff" "\\foo\\bar" == "\\\\shared\\foo\\bar"
}}}
But, since anything else doesn't make any sense:
{{{
combine "home" "/bob" == "/bob"
}}}
So just changing the check to `isAbsolute` (or `hasDrive`, since combining
with "C:foo", which isRelative, is not implemented at the moment, but that
is another issue) doesn't work.
An implementation that has this behavior would be:
{{{
combine a b | hasDrive b || hasLeadingPathSeparator b && not (hasDrive a)
= b
| hasLeadingPathSeparator b = combineAlways (takeDrive a)
(dropLeadingPathSeparator b)
| otherwise = combineAlways a b
}}}
Or, an option with the same behavior as above, except:
{{{
combine "C:\\STUFF" "\\foo\\bar" == "\\foo\\bar"
combine ""\\\\shared\\stuff" "\\foo\\bar" == "\\foo\\bar"
}}}
, would be:
{{{
combine a b | hasDrive b || hasLeadingPathSeparator b && not (isDrive a) =
b
| hasLeadingPathSeparator b = combineAlways a
(dropLeadingPathSeparator b)
| otherwise = combineAlways a b
}}}
I'm not sure which of the three is better. We have to change the docstring
either way.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8752#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list