Support filenames that start with a dash; when such a file is passed to a utility it will be escaped to avoid it being interpreted as an option.

This commit is contained in:
Joey Hess 2011-02-25 01:13:01 -04:00
parent e61b47bc8a
commit 836e71297b
9 changed files with 29 additions and 10 deletions

View file

@ -20,6 +20,7 @@ import qualified Annex
import Locations
import Content
import Types
import Utility
backend :: Backend Annex
backend = Backend.File.backend {
@ -31,7 +32,7 @@ backend = Backend.File.backend {
sha1 :: FilePath -> Annex String
sha1 file = do
showNote "checksum..."
liftIO $ pOpen ReadFromPipe "sha1sum" [file] $ \h -> do
liftIO $ pOpen ReadFromPipe "sha1sum" [utilityEscape file] $ \h -> do
line <- hGetLine h
let bits = split " " line
if null bits

View file

@ -51,6 +51,6 @@ downloadUrl :: Key -> FilePath -> Annex Bool
downloadUrl key file = do
showNote "downloading"
showProgress -- make way for curl progress bar
liftIO $ boolSystem "curl" ["-#", "-o", file, url]
liftIO $ boolSystem "curl" ["-#", "-o", utilityEscape file, url]
where
url = join ":" $ drop 1 $ split ":" $ show key

View file

@ -35,7 +35,8 @@ perform file = do
-- rather than simply calling moveToObjectDir
ok <- getViaTmp key $ \dest -> do
if dest /= file
then liftIO $ boolSystem "mv" [file, dest]
then liftIO $
boolSystem "mv" [utilityEscape file, utilityEscape dest]
else return True
if ok
then return $ Just $ cleanup

View file

@ -23,9 +23,11 @@ copyFile src dest = do
boolSystem "cp" opts
where
opts = if SysConfig.cp_reflink_auto
then ["--reflink=auto", src, dest]
then ["--reflink=auto", src', dest']
else if SysConfig.cp_a
then ["-a", src, dest]
then ["-a", src', dest']
else if SysConfig.cp_p
then ["-p", src, dest]
else [src, dest]
then ["-p", src', dest']
else [src', dest']
src' = utilityEscape src
dest' = utilityEscape dest

View file

@ -282,7 +282,7 @@ rsyncParams r sending key file = do
-- inplace makes rsync resume partial files
options = ["-p", "--progress", "--inplace"]
-- the rsync shell parameter controls where rsync
-- does, so the source/dest parameter can be a dummy value,
-- goes, so the source/dest parameter can be a dummy value,
-- that just enables remote rsync mode.
dummy = ":"

View file

@ -24,11 +24,12 @@ rsyncShell command = ["-e", unwords $ map escape command]
{- Runs rsync in server mode to send a file, and exits. -}
rsyncServerSend :: FilePath -> IO ()
rsyncServerSend file = rsyncExec $ rsyncServerParams ++ ["--sender", file]
rsyncServerSend file = rsyncExec $
rsyncServerParams ++ ["--sender", utilityEscape file]
{- Runs rsync in server mode to receive a file. -}
rsyncServerReceive :: FilePath -> IO Bool
rsyncServerReceive file = rsync $ rsyncServerParams ++ [file]
rsyncServerReceive file = rsync $ rsyncServerParams ++ [utilityEscape file]
rsyncServerParams :: [String]
rsyncServerParams =

View file

@ -15,6 +15,7 @@ module Utility (
boolSystem,
shellEscape,
shellUnEscape,
utilityEscape,
unsetFileMode,
readMaybe,
safeWriteFile,
@ -179,6 +180,13 @@ shellUnEscape s = word:(shellUnEscape rest)
| c == q = findword w cs
| otherwise = inquote q (w++[c]) cs
{- Ensures that a filename is safe to pass to a utility program. In particular
- since utilities tend to interpret things starting with a dash as
- an option, relative filenames starting with a dash are escaped. -}
utilityEscape :: FilePath -> FilePath
utilityEscape ('-':s) = "./-" ++ s
utilityEscape s = s
{- For quickcheck. -}
prop_idempotent_shellEscape :: String -> Bool
prop_idempotent_shellEscape s = [s] == (shellUnEscape $ shellEscape s)

3
debian/changelog vendored
View file

@ -5,6 +5,9 @@ git-annex (0.22) UNRELEASED; urgency=low
for his help eliminating the infestation... for now.)
* Make test suite not rely on a working cp -pr.
(The Unix wars are still ON!)
* Support filenames that start with a dash; when such a file is passed
to a utility it will be escaped to avoid it being interpreted as an
option.
-- Joey Hess <joeyh@debian.org> Sun, 13 Feb 2011 00:48:02 -0400

View file

@ -10,3 +10,6 @@ add -wut-a-directory-name-/file1 (checksum...) sha1sum: invalid option -- 'u'
git-annex: <file descriptor: 15>: hGetLine: end of file
"""]]
> This is fixed in git, at least I think I've found all cases where
> filenames are passed to programs and escaped them. --[[Joey]] [[done]]