Skip to content

Commit

Permalink
CommandLineParser: Validate compiler output selection
Browse files Browse the repository at this point in the history
  • Loading branch information
cameel committed Sep 30, 2021
1 parent 22881a3 commit 71b3b0e
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 20 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Compiler Features:


Bugfixes:
* Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them.



Expand Down
53 changes: 51 additions & 2 deletions solc/CommandLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ static set<string> const g_metadataHashArgs
g_strNone
};

static map<InputMode, string> const g_inputModeName = {
{InputMode::Compiler, "compiler"},
{InputMode::CompilerWithASTImport, "compiler (AST import)"},
{InputMode::Assembler, "assembler"},
{InputMode::StandardJson, "standard JSON"},
{InputMode::Linker, "linker"},
};

void CommandLineParser::printVersionAndExit()
{
sout() <<
Expand Down Expand Up @@ -460,6 +468,47 @@ bool CommandLineParser::parseLibraryOption(string const& _input)
return true;
}

bool CommandLineParser::parseOutputSelection()
{
static auto outputSupported = [](InputMode _mode, string_view _outputName)
{
static set<string> const compilerModeOutputs =
CompilerOutputs::componentMap() |
ranges::views::keys |
ranges::to<set>();

switch (_mode)
{
case InputMode::Compiler:
case InputMode::CompilerWithASTImport:
return contains(compilerModeOutputs, _outputName);
case InputMode::Assembler:
case InputMode::StandardJson:
case InputMode::Linker:
return false;
}

solAssert(false, "");
};

for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);

vector<string> unsupportedOutputs;
for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
if (m_options.compiler.outputs.*outputComponent && !outputSupported(m_options.input.mode, optionName))
unsupportedOutputs.push_back(optionName);

if (!unsupportedOutputs.empty())
{
serr() << "The following outputs are not supported in " << g_inputModeName.at(m_options.input.mode) << " mode: ";
serr() << joinOptionNames(unsupportedOutputs) << ".";
return false;
}

return true;
}

po::options_description CommandLineParser::optionsDescription()
{
// Declare the supported options.
Expand Down Expand Up @@ -930,8 +979,8 @@ bool CommandLineParser::processArgs()
m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>();
}

for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);
if (!parseOutputSelection())
return false;

m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0);

Expand Down
2 changes: 2 additions & 0 deletions solc/CommandLineParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ class CommandLineParser
/// @return false if there are any validation errors, true otherwise.
bool parseLibraryOption(std::string const& _input);

bool parseOutputSelection();

bool checkMutuallyExclusive(std::vector<std::string> const& _optionNames);
[[noreturn]] void printVersionAndExit();
[[noreturn]] void printLicenseAndExit();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--link --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
1 change: 1 addition & 0 deletions test/cmdlineTests/linker_mode_output_selection_invalid/err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The following outputs are not supported in linker mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Empty file.
1 change: 1 addition & 0 deletions test/cmdlineTests/strict_asm_output_selection_invalid/args
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--strict-assembly --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout
1 change: 1 addition & 0 deletions test/cmdlineTests/strict_asm_output_selection_invalid/err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The following outputs are not supported in assembler mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.
1 change: 1 addition & 0 deletions test/cmdlineTests/strict_asm_output_selection_invalid/exit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Empty file.
18 changes: 0 additions & 18 deletions test/solc/CommandLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,6 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
"underflow,"
"divByZero",
"--model-checker-timeout=5", // Ignored in assembly mode

// Accepted but has no effect in assembly mode
"--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi",
"--ir", "--ir-optimized", "--ewasm", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout",
};
commandLine += assemblyOptions;
if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm)
Expand Down Expand Up @@ -328,11 +324,6 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
};
expectedOptions.formatting.coloredOutput = false;
expectedOptions.formatting.withErrorIds = true;
expectedOptions.compiler.outputs = {
true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
};
if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm)
{
expectedOptions.optimizer.enabled = true;
Expand Down Expand Up @@ -388,10 +379,6 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options)
"underflow,"
"divByZero",
"--model-checker-timeout=5", // Ignored in Standard JSON mode

// Accepted but has no effect in Standard JSON mode
"--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi",
"--ir", "--ir-optimized", "--ewasm", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout",
};

CommandLineOptions expectedOptions;
Expand All @@ -408,11 +395,6 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options)
expectedOptions.formatting.json = JsonFormat {JsonFormat::Pretty, 1};
expectedOptions.formatting.coloredOutput = false;
expectedOptions.formatting.withErrorIds = true;
expectedOptions.compiler.outputs = {
true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
};
expectedOptions.compiler.estimateGas = true;
expectedOptions.compiler.combinedJsonRequests = CombinedJsonRequests{};
expectedOptions.compiler.combinedJsonRequests->abi = true;
Expand Down

0 comments on commit 71b3b0e

Please sign in to comment.