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

@ -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"