* Fix test failure on NFS when cleaning up gpg temp directory.
* Fix a build failure with ghc 9.2.2.
Thanks, gnezdo for the patch.
+ * rsync 3.2.4 broke backwards-compatability by preventing exposing
+ filenames to the shell. Made the rsync and gcrypt special remotes
+ detect this and disable shellescape. Closes: #1010397
-- Joey Hess <id@joeyh.name> Mon, 28 Mar 2022 14:46:10 -0400
withRsyncScratchDir,
rsyncRemoteConfigs,
genRsyncOpts,
- RsyncOpts
+ RsyncOpts,
+ probeRsyncProtectsArgs,
) where
import Annex.Common
import Crypto
import Utility.Rsync
import Utility.CopyFile
+import Utility.Process.Transcript
import Messages.Progress
import Utility.Metered
import Types.Transfer
cst <- remoteCost gc expensiveRemoteCost
(transport, url) <- rsyncTransport gc $
fromMaybe (giveup "missing rsyncurl") $ remoteAnnexRsyncUrl gc
- let o = genRsyncOpts c gc transport url
+ protectsargs <- liftIO probeRsyncProtectsArgs
+ let o = genRsyncOpts protectsargs c gc transport url
let islocal = rsyncUrlIsPath $ rsyncUrl o
return $ Just $ specialRemote c
(fileStorer $ store o)
, remoteStateHandle = rs
}
+-- | Since 3.2.4, rsync protects filenames from being exposed to the shell.
+newtype RsyncProtectsArgs = RsyncProtectsArgs Bool
+
+probeRsyncProtectsArgs :: IO RsyncProtectsArgs
+probeRsyncProtectsArgs = do
+ (helpoutput, _) <- processTranscript "rsync" ["--help"] Nothing
+ -- The --old-args option was added to disable the new arg
+ -- protection, so use it to detect when that feature is supported
+ -- by rsync, rather than parsing versions.
+ return (RsyncProtectsArgs $ "--old-args" `isInfixOf` helpoutput)
+
+
-- Things used by genRsyncOpts
rsyncRemoteConfigs :: [RemoteConfigFieldParser]
rsyncRemoteConfigs =
(FieldDesc "set to no to avoid usual shell escaping (not recommended)")
]
-genRsyncOpts :: ParsedRemoteConfig -> RemoteGitConfig -> Annex [CommandParam] -> RsyncUrl -> RsyncOpts
-genRsyncOpts c gc transport url = RsyncOpts
+genRsyncOpts :: RsyncProtectsArgs -> ParsedRemoteConfig -> RemoteGitConfig -> Annex [CommandParam] -> RsyncUrl -> RsyncOpts
+genRsyncOpts (RsyncProtectsArgs protectsargs) c gc transport url = RsyncOpts
{ rsyncUrl = url
, rsyncOptions = appendtransport $ opts []
, rsyncUploadOptions = appendtransport $
opts (remoteAnnexRsyncUploadOptions gc)
, rsyncDownloadOptions = appendtransport $
opts (remoteAnnexRsyncDownloadOptions gc)
- , rsyncShellEscape = fromMaybe True (getRemoteConfigValue shellEscapeField c)
+ , rsyncShellEscape = if protectsargs
+ then False
+ else fromMaybe True (getRemoteConfigValue shellEscapeField c)
}
where
appendtransport l = (++ l) <$> transport
by [[git-annex-export]]. It will not be usable as a general-purpose
special remote.
-* `shellescape` - Optional. Set to "no" to avoid shell escaping normally
- done when using rsync over ssh. That escaping is needed with typical
- setups, but not with some hosting providers that do not expose rsynced
- filenames to the shell. You'll know you need this option if `git annex get`
- from the special remote fails with an error message containing a single
- quote (`'`) character. If that happens, you can run enableremote
- setting shellescape=no.
+* `shellescape` - Optional. This has no effect when using rsync 3.2.4 or
+ newer. Set to "no" to avoid shell escaping
+ normally done when using older versions of rsync over ssh. That escaping
+ is needed with typical setups, but not with some hosting providers that do
+ not expose rsynced filenames to the shell. You'll know you need this
+ option if `git annex get` from the special remote fails with an error
+ message containing a single quote (`'`) character. If that happens, you
+ can run enableremote setting shellescape=no.
* `chunk` - Enables [[chunking]] when storing large files.
This is typically not a win for rsync, so no need to enable it.