From b9b2c69d246235525fee6a97a6c49ff993b3cead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 4 Oct 2021 16:35:59 +0200 Subject: [PATCH] CommandLineParser: Validate compiler output selection --- Changelog.md | 1 + solc/CommandLineParser.cpp | 53 ++++++++++++++++++- solc/CommandLineParser.h | 2 + .../linker_mode_output_selection_invalid/args | 1 + .../linker_mode_output_selection_invalid/err | 1 + .../linker_mode_output_selection_invalid/exit | 1 + .../input.bin | 0 .../args | 1 + .../standard_cli_output_selection_invalid/err | 1 + .../exit | 1 + .../input.json | 0 .../strict_asm_output_selection_invalid/args | 1 + .../strict_asm_output_selection_invalid/err | 1 + .../strict_asm_output_selection_invalid/exit | 1 + .../input.yul | 0 test/cmdlineTests/yul_optimize_runs/args | 2 +- test/solc/CommandLineParser.cpp | 18 ------- 17 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 test/cmdlineTests/linker_mode_output_selection_invalid/args create mode 100644 test/cmdlineTests/linker_mode_output_selection_invalid/err create mode 100644 test/cmdlineTests/linker_mode_output_selection_invalid/exit create mode 100644 test/cmdlineTests/linker_mode_output_selection_invalid/input.bin create mode 100644 test/cmdlineTests/standard_cli_output_selection_invalid/args create mode 100644 test/cmdlineTests/standard_cli_output_selection_invalid/err create mode 100644 test/cmdlineTests/standard_cli_output_selection_invalid/exit create mode 100644 test/cmdlineTests/standard_cli_output_selection_invalid/input.json create mode 100644 test/cmdlineTests/strict_asm_output_selection_invalid/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_invalid/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_invalid/exit create mode 100644 test/cmdlineTests/strict_asm_output_selection_invalid/input.yul diff --git a/Changelog.md b/Changelog.md index 74e20d4b8..173751636 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: * Commandline Interface: Fix extra newline character being appended to sources passed through standard input, affecting their hashes. + * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * TypeChecker: Fix internal error when using user defined value types in public library functions. diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 26b8dd255..6c673c311 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -137,6 +137,14 @@ static set const g_metadataHashArgs g_strNone }; +static map 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() << @@ -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 const compilerModeOutputs = + CompilerOutputs::componentMap() | + ranges::views::keys | + ranges::to(); + + 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 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. @@ -930,8 +979,8 @@ bool CommandLineParser::processArgs() m_options.formatting.json.indent = m_args[g_strJsonIndent].as(); } - 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); diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 7e1266653..1f09ea993 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -286,6 +286,8 @@ private: /// @return false if there are any validation errors, true otherwise. bool parseLibraryOption(std::string const& _input); + bool parseOutputSelection(); + bool checkMutuallyExclusive(std::vector const& _optionNames); [[noreturn]] void printVersionAndExit(); [[noreturn]] void printLicenseAndExit(); diff --git a/test/cmdlineTests/linker_mode_output_selection_invalid/args b/test/cmdlineTests/linker_mode_output_selection_invalid/args new file mode 100644 index 000000000..ded0d6efc --- /dev/null +++ b/test/cmdlineTests/linker_mode_output_selection_invalid/args @@ -0,0 +1 @@ +--link --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout diff --git a/test/cmdlineTests/linker_mode_output_selection_invalid/err b/test/cmdlineTests/linker_mode_output_selection_invalid/err new file mode 100644 index 000000000..c84a12d97 --- /dev/null +++ b/test/cmdlineTests/linker_mode_output_selection_invalid/err @@ -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. diff --git a/test/cmdlineTests/linker_mode_output_selection_invalid/exit b/test/cmdlineTests/linker_mode_output_selection_invalid/exit new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/test/cmdlineTests/linker_mode_output_selection_invalid/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/linker_mode_output_selection_invalid/input.bin b/test/cmdlineTests/linker_mode_output_selection_invalid/input.bin new file mode 100644 index 000000000..e69de29bb diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/args b/test/cmdlineTests/standard_cli_output_selection_invalid/args new file mode 100644 index 000000000..f2deb3847 --- /dev/null +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/args @@ -0,0 +1 @@ +--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/err b/test/cmdlineTests/standard_cli_output_selection_invalid/err new file mode 100644 index 000000000..d6ed4d572 --- /dev/null +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/err @@ -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. diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/exit b/test/cmdlineTests/standard_cli_output_selection_invalid/exit new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/input.json b/test/cmdlineTests/standard_cli_output_selection_invalid/input.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/args b/test/cmdlineTests/strict_asm_output_selection_invalid/args new file mode 100644 index 000000000..85814eb29 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/args @@ -0,0 +1 @@ +--strict-assembly --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/err b/test/cmdlineTests/strict_asm_output_selection_invalid/err new file mode 100644 index 000000000..736eb2c8a --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/err @@ -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. diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/exit b/test/cmdlineTests/strict_asm_output_selection_invalid/exit new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/input.yul b/test/cmdlineTests/strict_asm_output_selection_invalid/input.yul new file mode 100644 index 000000000..e69de29bb diff --git a/test/cmdlineTests/yul_optimize_runs/args b/test/cmdlineTests/yul_optimize_runs/args index b48e7aeed..033abe3bb 100644 --- a/test/cmdlineTests/yul_optimize_runs/args +++ b/test/cmdlineTests/yul_optimize_runs/args @@ -1 +1 @@ ---yul --yul-dialect evm --optimize --ir-optimized --optimize-runs 10000 +--yul --yul-dialect evm --optimize --optimize-runs 10000 diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 7b1dd375b..939850304 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -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) @@ -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; @@ -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; @@ -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;