diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-01-08 13:55:35 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-01-08 13:55:35 -0400 |
commit | 8df4e37f0dda20be0a13487f71bacf483aedaf58 (patch) | |
tree | fc628244c59aaa1e04658847c0a3ee8d4fbc45bd /Annex/View.hs | |
parent | 6b4fc5e985ed96e14ebc89e67b373dd66c857bc5 (diff) |
better fix for slash in view metadata
The homomorphs are back, just encoded such that it doesn't crash in LANG=C
However, I noticed a bug in the old escaping; [pseudoSlash] was escaped the
same as ['/','/']. Fixed by using '%' to escape pseudoSlash. Which requires
doubling '%' to escape it, but that's already done in the escaping of
worktree filenames in a view, so is probably ok.
Diffstat (limited to 'Annex/View.hs')
-rw-r--r-- | Annex/View.hs | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/Annex/View.hs b/Annex/View.hs index 92a7ffc48..060301fd5 100644 --- a/Annex/View.hs +++ b/Annex/View.hs @@ -222,23 +222,37 @@ viewComponentMatcher viewcomponent = \metadata -> | S.null s = Nothing | otherwise = Just (S.toList s) +-- This is '∕', a unicode character that displays the same as '/' but is +-- not it. It is encoded using the filesystem encoding, which allows it +-- to be used even when not in a unicode capable locale. +pseudoSlash :: String +pseudoSlash = "\56546\56456\56469" + +-- And this is '╲' similarly. +pseudoBackslash :: String +pseudoBackslash = "\56546\56469\56498" + toViewPath :: MetaValue -> FilePath -toViewPath = concatMap escapeslash . fromMetaValue +toViewPath = escapeslash [] . fromMetaValue where - escapeslash c - | c == '/' = "%_" - | c == '\\' = "%." - | c == '%' = "%%" - | otherwise = [c] + escapeslash s ('/':cs) = escapeslash (pseudoSlash:s) cs + escapeslash s ('\\':cs) = escapeslash (pseudoBackslash:s) cs + escapeslash s ('%':cs) = escapeslash ("%%":s) cs + escapeslash s (c1:c2:c3:cs) + | [c1,c2,c3] == pseudoSlash = escapeslash ("%":pseudoSlash:s) cs + | [c1,c2,c3] == pseudoBackslash = escapeslash ("%":pseudoBackslash:s) cs + | otherwise = escapeslash ([c1]:s) (c2:c3:cs) + escapeslash s cs = concat (reverse (cs:s)) fromViewPath :: FilePath -> MetaValue fromViewPath = toMetaValue . deescapeslash [] where - deescapeslash s [] = reverse s - deescapeslash s ('%':'_':cs) = deescapeslash ('/':s) cs - deescapeslash s ('%':'.':cs) = deescapeslash ('\\':s) cs - deescapeslash s ('%':'%':cs) = deescapeslash ('%':s) cs - deescapeslash s (c:cs) = deescapeslash (c:s) cs + deescapeslash s ('%':escapedc:cs) = deescapeslash ([escapedc]:s) cs + deescapeslash s (c1:c2:c3:cs) + | [c1,c2,c3] == pseudoSlash = deescapeslash ("/":s) cs + | [c1,c2,c3] == pseudoBackslash = deescapeslash ("\\":s) cs + | otherwise = deescapeslash ([c1]:s) (c2:c3:cs) + deescapeslash s cs = concat (reverse (cs:s)) prop_viewPath_roundtrips :: MetaValue -> Bool prop_viewPath_roundtrips v = fromViewPath (toViewPath v) == v |