From 0a8d93cb8ae0701d15bb40a149af5a540eeec314 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 14 Jan 2019 14:02:47 -0400 Subject: [PATCH] convert to ByteString --- Annex/Locations.hs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Annex/Locations.hs b/Annex/Locations.hs index 053be6e3b4..a45fa02c21 100644 --- a/Annex/Locations.hs +++ b/Annex/Locations.hs @@ -1,13 +1,17 @@ {- git-annex file locations - - - Copyright 2010-2017 Joey Hess + - Copyright 2010-2019 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} +{-# LANGUAGE OverloadedStrings #-} + module Annex.Locations ( keyFile, + keyFile', fileKey, + fileKey', keyPaths, keyPath, annexDir, @@ -80,6 +84,8 @@ module Annex.Locations ( import Data.Char import Data.Default +import qualified Data.ByteString.Lazy as L +import qualified Data.ByteString.Char8 as S8 import Common import Key @@ -476,8 +482,8 @@ preSanitizeKeyName' resanitize = concatMap escape where escape c | isAsciiUpper c || isAsciiLower c || isDigit c = [c] - | c `elem` ".-_" = [c] -- common, assumed safe - | c `elem` "/%:" = [c] -- handled by keyFile + | c `elem` ['.', '-', '_'] = [c] -- common, assumed safe + | c `elem` ['/', '%', ':'] = [c] -- handled by keyFile -- , is safe and uncommon, so will be used to escape -- other characters. By itself, it is escaped to -- doubled form. @@ -506,25 +512,33 @@ reSanitizeKeyName = preSanitizeKeyName' True - can cause existing objects to get lost. -} keyFile :: Key -> FilePath -keyFile = concatMap esc . serializeKey +keyFile = fromRawFilePath . keyFile' + +keyFile' :: Key -> RawFilePath +keyFile' = S8.concatMap esc . L.toStrict . serializeKey' where esc '&' = "&a" esc '%' = "&s" esc ':' = "&c" esc '/' = "%" - esc c = [c] + esc c = S8.singleton c {- Reverses keyFile, converting a filename fragment (ie, the basename of - the symlink target) into a key. -} fileKey :: FilePath -> Maybe Key -fileKey = deserializeKey . unesc [] +fileKey = fileKey' . toRawFilePath + +fileKey' :: RawFilePath -> Maybe Key +fileKey' = deserializeKey' . S8.intercalate "/" . map go . S8.split '%' where - unesc r [] = reverse r - unesc r ('%':cs) = unesc ('/':r) cs - unesc r ('&':'c':cs) = unesc (':':r) cs - unesc r ('&':'s':cs) = unesc ('%':r) cs - unesc r ('&':'a':cs) = unesc ('&':r) cs - unesc r (c:cs) = unesc (c:r) cs + go :: S8.ByteString -> S8.ByteString + go = S8.concat . map (unesc . S8.uncons) . S8.split '&' + unesc :: Maybe (Char, S8.ByteString) -> S8.ByteString + unesc Nothing = mempty + unesc (Just ('c', b)) = S8.cons ':' b + unesc (Just ('s', b)) = S8.cons '%' b + unesc (Just ('a', b)) = S8.cons '&' b + unesc (Just (c, b)) = S8.cons c b {- A location to store a key on a special remote that uses a filesystem. - A directory hash is used, to protect against filesystems that dislike