Add validation for the JSON input; replace outputSelection

pull/5025/head
Viktor Baranov 3 years ago
parent 55f23069dd
commit 8e5b61b98f
  1. 1
      CHANGELOG.md
  2. 49
      apps/explorer/lib/explorer/smart_contract/solidity/code_compiler.ex

@ -3,6 +3,7 @@
### Features
### Fixes
- [#5025](https://github.com/blockscout/blockscout/pull/5025) - Add standard input JSON files validation
### Chore

@ -9,6 +9,10 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
@new_contract_name "New.sol"
@required_standard_input_fields ~w(language sources settings)
@default_output_selection %{"*" => %{"*" => ["*"]}}
@doc """
Compiles a code in the solidity command line.
@ -132,24 +136,24 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
path = SolcDownloader.ensure_exists(compiler_version)
if path do
{response, _status} =
System.cmd(
"node",
[
Application.app_dir(:explorer, "priv/compile_solc_standard_json_input.js"),
create_source_file(json_input),
path
]
)
with {:ok, decoded} <- Jason.decode(response),
with {:ok, valid_json} <- tune_json(json_input),
{response, _status} <-
System.cmd(
"node",
[
Application.app_dir(:explorer, "priv/compile_solc_standard_json_input.js"),
create_source_file(valid_json),
path
]
),
{:ok, decoded} <- Jason.decode(response),
{:ok, contracts} <- get_contracts_standard_input_verification(decoded) do
fetch_candidates(contracts, name)
else
{:error, %Jason.DecodeError{}} ->
{:error, :compilation}
{:error, reason} when reason in [:name, :compilation] ->
{:error, reason} when reason in [:name, :compilation, :json] ->
{:error, reason}
error ->
@ -164,6 +168,27 @@ defmodule Explorer.SmartContract.Solidity.CodeCompiler do
end
end
defp tune_json(json_input) when is_binary(json_input) do
case Jason.decode(json_input) do
{:ok, map_input} ->
map_set_input_keys = map_input |> Map.keys() |> MapSet.new()
map_set_required_keys = MapSet.new(@required_standard_input_fields)
if MapSet.subset?(map_set_required_keys, map_set_input_keys) do
settings = Map.fetch!(map_input, "settings")
new_settings = Map.put(settings, "outputSelection", @default_output_selection)
map_input |> Map.replace("settings", new_settings) |> Jason.encode()
else
{:error, :json}
end
_ ->
{:error, :json}
end
end
defp tune_json(_json_input), do: {:error, :json}
defp fetch_candidates(contracts, "") when is_map(contracts) do
candidates =
for {file, content} <- contracts,

Loading…
Cancel
Save