[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