Drop support for the Elixir config format - #1230
Merged
Merged
Conversation
hex.config has been written as Erlang terms since v0.5.0 in 2014, and update/1 is read-modify-write, so every config change since then has rewritten the file in the new format. A config still in the Elixir format is one no hex has written in about ten years. Reading it went through Code.eval_string, which evaluates whatever the file contains, so a term decode failure was a code execution path into the file that holds the API key and the OAuth tokens. That branch caught a truncated or corrupt config too, not only an old-format one. An unreadable config now raises and names the way out.
:io.read/2 answers a bare :error atom, not {:error, reason}, when a term
decodes structurally but holds a binary that is not valid UTF-8. consult/3
matched neither, so read/0 raised CaseClauseError from Hex.State.start_link/1
and every later mix invocation failed until the file was deleted by hand.
A server-supplied value reaches the config this way: hex stores the
organization names from sso_reauth_required, and hex_core admits any binary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hex.Config.do_read/0fell back toCode.eval_string/1whenhex.configfailed Erlang term decoding, so an unreadable config was evaluated as Elixir source. That file holds the API key and the OAuth tokens.The fallback dates to v0.5.0 (2014-09-19), which switched the write format to Erlang terms and kept an Elixir reader for existing files. v0.13.0 removed the reader and v0.13.1 reverted that, so the fallback has been in place continuously since 2014. It never converted anything on read, but
update/1is read-modify-write against the term writer, so any config change (mix hex.user auth, adding an organization, anything touching$repos) has rewritten the file in the term format for the last ten years. A config still in the Elixir format is one no hex has written in that time.The branch was also reached by any term decode failure, not only old-format files, so a truncated or corrupt config took the eval path too. It now raises and names the recovery step:
The second commit closes the other half of the same read path.
:io.read/2answers a bare:erroratom rather than an{:error, reason}tuple when a term is syntactically valid but cannot be read back, andconsult/3had no clause for it, so the whole ofmixraisedCaseClauseErroron every invocation until the file was deleted by hand.Hex.State.start_link/1callsHex.Config.read/0, so there was no way to run the command that would have fixed it.A non-UTF-8 organization name in
sso_reauth_requiredgets there, which needs a hostileHEX_API_URLsince hexpm validates organization names, but the same exposure already applied toaccess_tokenandrefresh_token. It now raises the sameMix.raiseas any other unreadable config.