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.
This commit is contained in:
Joey Hess 2016-01-08 13:55:35 -04:00
parent 42619e2231
commit 51bc32e21e
Failed to extract signature
3 changed files with 30 additions and 14 deletions

View file

@ -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

5
debian/changelog vendored
View file

@ -48,9 +48,8 @@ git-annex (6.20151219) UNRELEASED; urgency=medium
* rekey: No longer copies over urls from the old to the new key.
It makes sense for migrate to do that, but not for this low-level
(and little used) plumbing command to.
* view: Avoid using cute unicode homomorphs for '/' and '\' and instead
use ugly escaping, as the unicode method doesn't work on non-unicode
supporting systems.
* view: Fix crash in non-unicode capable locale when entering a view
of metadata containing a slash or backslash.
-- Joey Hess <id@joeyh.name> Sat, 19 Dec 2015 13:31:17 -0400

View file

@ -21,4 +21,7 @@ unicode support.
Sigh, 2016 and still can't have nice things.. Suppose it'll have to use an
ugly encoding for them instead.
Update: Can have nice things, just have to encode the characters using the
FileSystemEncoding!
"""]]