Fix support for local gcrypt repositories with a space in their URI

Git.Remote.parseRemoteLocation had a hack to handle URIs that contained
characters like spaces, which is something git unfortunately allows
despite not being a valid URI. However, that hack looked for "//" to
guess something was an URI, and these gcrypt URIs, being to a local
path, don't contain that. So instead escape all illegal characters and
check if the resulting thing is an URI.

And that was already done by Git.Construct.fromUrl, so
internally the gcrypt URI with a space looks like "gcrypt::foo%20bar"
and that needs to be de-escaped when converting back from URI to local
repo path.

This change might also allow a few other almost-valid URIs to be handled
as URIs by git-annex. None that contain "//" will change, and any
behavior change should result in git-annex doing closer to a right thing
than it did before, probably.

This commit was sponsored by Noam Kremen on Patreon.
This commit is contained in:
Joey Hess 2021-03-09 12:30:13 -04:00
parent d3578f3b66
commit e07eabbf7f
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 13 additions and 2 deletions

View file

@ -15,6 +15,7 @@ git-annex (8.20210224) UNRELEASED; urgency=medium
(Such a conversion will still happen when importing from a remote
an old git-annex exported such a tree to before; export the tree
with the new git-annex before importing to avoid that.)
* Fix support for local gcrypt repositories with a space in their URI.
-- Joey Hess <id@joeyh.name> Wed, 24 Feb 2021 13:18:38 -0400

View file

@ -19,6 +19,7 @@ import qualified Git.Command as Command
import Utility.Gpg
import qualified Data.ByteString as S
import qualified Network.URI
urlScheme :: String
urlScheme = "gcrypt:"
@ -48,7 +49,13 @@ encryptedRemote baserepo = go
go' u
| urlPrefix `isPrefixOf` u =
fromRemoteLocation (drop plen u) baserepo
let l = drop plen u
-- Git.Construct.fromUrl escapes characters
-- that are not allowed in URIs (though git
-- allows them); need to de-escape any such
-- to get back the path to the repository.
l' = Network.URI.unEscapeString l
in fromRemoteLocation l' baserepo
| otherwise = notencrypted
notencrypted = giveup "not a gcrypt encrypted repository"

View file

@ -99,7 +99,9 @@ parseRemoteLocation s repo = ret $ calcloc s
concatMap splitconfigs $ M.toList $ fullconfig repo
splitconfigs (k, vs) = map (\v -> (k, v)) vs
(prefix, suffix) = ("url." , ".insteadof")
urlstyle v = isURI v || ":" `isInfixOf` v && "//" `isInfixOf` v
-- git supports URIs that contain unescaped characters such as
-- spaces. So to test if it's a (git) URI, escape those.
urlstyle v = isURI (escapeURIString isUnescapedInURI v)
-- git remotes can be written scp style -- [user@]host:dir
-- but foo::bar is a git-remote-helper location instead
scpstyle v = ":" `isInfixOf` v

View file

@ -22,4 +22,5 @@ copy file.mkv (unable to check encryptedbackup) failed
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
> [[fixed|done]] --[[Joey]]