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 | S.null s = Nothing
| otherwise = Just (S.toList s) | 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 :: MetaValue -> FilePath
toViewPath = concatMap escapeslash . fromMetaValue toViewPath = escapeslash [] . fromMetaValue
where where
escapeslash c escapeslash s ('/':cs) = escapeslash (pseudoSlash:s) cs
| c == '/' = "%_" escapeslash s ('\\':cs) = escapeslash (pseudoBackslash:s) cs
| c == '\\' = "%." escapeslash s ('%':cs) = escapeslash ("%%":s) cs
| c == '%' = "%%" escapeslash s (c1:c2:c3:cs)
| otherwise = [c] | [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 :: FilePath -> MetaValue
fromViewPath = toMetaValue . deescapeslash [] fromViewPath = toMetaValue . deescapeslash []
where where
deescapeslash s [] = reverse s deescapeslash s ('%':escapedc:cs) = deescapeslash ([escapedc]:s) cs
deescapeslash s ('%':'_':cs) = deescapeslash ('/':s) cs deescapeslash s (c1:c2:c3:cs)
deescapeslash s ('%':'.':cs) = deescapeslash ('\\':s) cs | [c1,c2,c3] == pseudoSlash = deescapeslash ("/":s) cs
deescapeslash s ('%':'%':cs) = deescapeslash ('%':s) cs | [c1,c2,c3] == pseudoBackslash = deescapeslash ("\\":s) cs
deescapeslash s (c:cs) = deescapeslash (c:s) cs | otherwise = deescapeslash ([c1]:s) (c2:c3:cs)
deescapeslash s cs = concat (reverse (cs:s))
prop_viewPath_roundtrips :: MetaValue -> Bool prop_viewPath_roundtrips :: MetaValue -> Bool
prop_viewPath_roundtrips v = fromViewPath (toViewPath v) == v 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. * 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 It makes sense for migrate to do that, but not for this low-level
(and little used) plumbing command to. (and little used) plumbing command to.
* view: Avoid using cute unicode homomorphs for '/' and '\' and instead * view: Fix crash in non-unicode capable locale when entering a view
use ugly escaping, as the unicode method doesn't work on non-unicode of metadata containing a slash or backslash.
supporting systems.
-- Joey Hess <id@joeyh.name> Sat, 19 Dec 2015 13:31:17 -0400 -- 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 Sigh, 2016 and still can't have nice things.. Suppose it'll have to use an
ugly encoding for them instead. ugly encoding for them instead.
Update: Can have nice things, just have to encode the characters using the
FileSystemEncoding!
"""]] """]]