make remoteKeyToRemoteName safer

If it's passed a ConfigKey such as annex.version, avoid returning
an empty remote name and return Nothing instead. Also, foo.bar.baz is
not treated as a remote named "bar".
This commit is contained in:
Joey Hess 2021-04-23 13:28:23 -04:00
parent 5cb05c43c9
commit 0e830b6bb5
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 20 additions and 14 deletions

View file

@ -449,8 +449,8 @@ completeRemotes = completer $ mkCompleter $ \input -> do
r <- maybe (pure Nothing) (Just <$$> Git.Config.read) r <- maybe (pure Nothing) (Just <$$> Git.Config.read)
=<< Git.Construct.fromCwd =<< Git.Construct.fromCwd
return $ filter (input `isPrefixOf`) $ return $ filter (input `isPrefixOf`) $
map remoteKeyToRemoteName $ mapMaybe remoteKeyToRemoteName $
filter isRemoteKey $ filter isRemoteUrlKey $
maybe [] (M.keys . config) r maybe [] (M.keys . config) r
completeBackends :: HasCompleter f => Mod f a completeBackends :: HasCompleter f => Mod f a

View file

@ -133,11 +133,11 @@ localToUrl reference r
{- Calculates a list of a repo's configured remotes, by parsing its config. -} {- Calculates a list of a repo's configured remotes, by parsing its config. -}
fromRemotes :: Repo -> IO [Repo] fromRemotes :: Repo -> IO [Repo]
fromRemotes repo = mapM construct remotepairs fromRemotes repo = catMaybes <$> mapM construct remotepairs
where where
filterconfig f = filter f $ M.toList $ config repo filterconfig f = filter f $ M.toList $ config repo
filterkeys f = filterconfig (\(k,_) -> f k) filterkeys f = filterconfig (\(k,_) -> f k)
remotepairs = filterkeys isRemoteKey remotepairs = filterkeys isRemoteUrlKey
construct (k,v) = remoteNamedFromKey k $ construct (k,v) = remoteNamedFromKey k $
fromRemoteLocation (fromConfigValue v) repo fromRemoteLocation (fromConfigValue v) repo
@ -149,8 +149,10 @@ remoteNamed n constructor = do
{- Sets the name of a remote based on the git config key, such as {- Sets the name of a remote based on the git config key, such as
- "remote.foo.url". -} - "remote.foo.url". -}
remoteNamedFromKey :: ConfigKey -> IO Repo -> IO Repo remoteNamedFromKey :: ConfigKey -> IO Repo -> IO (Maybe Repo)
remoteNamedFromKey = remoteNamed . remoteKeyToRemoteName remoteNamedFromKey k r = case remoteKeyToRemoteName k of
Nothing -> pure Nothing
Just n -> Just <$> remoteNamed n r
{- Constructs a new Repo for one of a Repo's remotes using a given {- Constructs a new Repo for one of a Repo's remotes using a given
- location (ie, an url). -} - location (ie, an url). -}

View file

@ -23,14 +23,18 @@ import Network.URI
import Git.FilePath import Git.FilePath
#endif #endif
{- Is a git config key one that specifies the location of a remote? -} {- Is a git config key one that specifies the url of a remote? -}
isRemoteKey :: ConfigKey -> Bool isRemoteUrlKey :: ConfigKey -> Bool
isRemoteKey (ConfigKey k) = "remote." `S.isPrefixOf` k && ".url" `S.isSuffixOf` k isRemoteUrlKey (ConfigKey k) = "remote." `S.isPrefixOf` k && ".url" `S.isSuffixOf` k
{- Get a remote's name from the config key that specifies its location. -} {- Get a remote's name from the a config key such as remote.name.url
remoteKeyToRemoteName :: ConfigKey -> RemoteName - or any other per-remote config key. -}
remoteKeyToRemoteName (ConfigKey k) = decodeBS' $ remoteKeyToRemoteName :: ConfigKey -> Maybe RemoteName
S.intercalate "." $ dropFromEnd 1 $ drop 1 $ S8.split '.' k remoteKeyToRemoteName (ConfigKey k)
| "remote." `S.isPrefixOf` k =
let n = S.intercalate "." $ dropFromEnd 1 $ drop 1 $ S8.split '.' k
in if S.null n then Nothing else Just (decodeBS' n)
| otherwise = Nothing
{- Construct a legal git remote name out of an arbitrary input string. {- Construct a legal git remote name out of an arbitrary input string.
- -

View file

@ -61,7 +61,7 @@ import qualified Data.Map as M
findSpecialRemotes :: String -> Annex [Git.Repo] findSpecialRemotes :: String -> Annex [Git.Repo]
findSpecialRemotes s = do findSpecialRemotes s = do
m <- fromRepo Git.config m <- fromRepo Git.config
liftIO $ mapM construct $ remotepairs m liftIO $ catMaybes <$> mapM construct (remotepairs m)
where where
remotepairs = M.toList . M.filterWithKey match remotepairs = M.toList . M.filterWithKey match
construct (k,_) = Git.Construct.remoteNamedFromKey k construct (k,_) = Git.Construct.remoteNamedFromKey k