Skip to content

Commit

Permalink
Fix parsing of password-command option (#6268)
Browse files Browse the repository at this point in the history
The password-command option does not parse its value correctly.
Quotes are ignored, making many kinds of commands impossible to
express (e.g.  `sh -c "foo | bar"`).  Also, `cabal user-config`
treats the argument list as a *list of option values*, rather than a
*value that is a list*.  As a consequence, `cabal user-config
update` corrupts the value in the config file.

Fix these issues by parsing the command as a space separated list of
tokens, and changing the getter to `unwords` the value and return a
*singleton* list.  Also update the argument placeholder from
`PASSWORD` to `COMMAND`.

Fixes: #6268
  • Loading branch information
frasertweedale committed Jun 6, 2023
1 parent a191f0a commit b78c95a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
11 changes: 10 additions & 1 deletion cabal-install/src/Distribution/Client/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ import Distribution.Client.Targets
( UserConstraint
, readUserConstraint
)
import Distribution.Deprecated.ParseUtils (parseSpaceList, parseTokenQ)
import Distribution.Deprecated.ReadP (readP_to_E)
import Distribution.Utils.NubList
( NubList
, fromNubList
Expand Down Expand Up @@ -2706,7 +2708,14 @@ uploadCommand =
"Command to get Hackage password."
uploadPasswordCmd
(\v flags -> flags{uploadPasswordCmd = v})
(reqArg' "PASSWORD" (Flag . words) (fromMaybe [] . flagToMaybe))
( reqArg
"COMMAND"
( readP_to_E
("Cannot parse command: " ++)
(Flag <$> parseSpaceList parseTokenQ)
)
(flagElim [] (pure . unwords . fmap show))
)
]
}

Expand Down
1 change: 1 addition & 0 deletions cabal-install/src/Distribution/Deprecated/ParseUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module Distribution.Deprecated.ParseUtils
, readFields
, parseHaskellString
, parseTokenQ
, parseSpaceList
, parseOptCommaList
, showFilePath
, showToken
Expand Down
3 changes: 3 additions & 0 deletions cabal-testsuite/PackageTests/UserConfig/cabal.out
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Writing merged config to <ROOT>/cabal.dist/cabal-config.
# cabal user-config
Renaming <ROOT>/cabal.dist/cabal-config to <ROOT>/cabal.dist/cabal-config.backup.
Writing merged config to <ROOT>/cabal.dist/cabal-config.
# cabal user-config
Renaming <ROOT>/cabal.dist/cabal-config to <ROOT>/cabal.dist/cabal-config.backup.
Writing merged config to <ROOT>/cabal.dist/cabal-config.
6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/UserConfig/cabal.test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ main = cabalTest $ do
assertFileDoesContain conf "foo,bar"
cabalG ["--config-file", conf] "user-config" ["update", "-f", "-a", "extra-prog-path: foo, bar"]
assertFileDoesContain conf "foo,bar"

-- regression test for #6268 (password-command parsing)
cabalG ["--config-file", conf]
"user-config" ["update", "-f", "-a", "password-command: sh -c \"echo secret\""]
-- non-quoted tokens do get quoted when writing, but this is expected
assertFileDoesContain conf "password-command: \"sh\" \"-c\" \"echo secret\""
14 changes: 13 additions & 1 deletion doc/cabal-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,19 @@ to Hackage.

.. option:: -P, --password-command

Command to get your Hackage password.
Command to get your Hackage password. Arguments with whitespace
must be quoted (double-quotes only). For example:

::

--password-command 'sh -c "grep hackage ~/secrets | cut -d : -f 2"'

Or in the config file:

::

password-command: sh -c "grep hackage ~/secrets | cut -d : -f 2"


cabal report
^^^^^^^^^^^^
Expand Down

0 comments on commit b78c95a

Please sign in to comment.