diff options
-rw-r--r-- | Changelog.md | 2 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 16 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.h | 1 | ||||
-rw-r--r-- | libsolidity/interface/CompilerStack.cpp | 13 | ||||
-rw-r--r-- | libsolidity/interface/CompilerStack.h | 2 | ||||
-rw-r--r-- | solc/CommandLineInterface.cpp | 58 | ||||
-rw-r--r-- | solc/CommandLineInterface.h | 8 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 18 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 1 |
9 files changed, 84 insertions, 35 deletions
diff --git a/Changelog.md b/Changelog.md index a14e9ec8..71a1e096 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,10 +7,12 @@ Features: * Type system: Introduce type identifier strings. * Type checker: Warn about invalid checksum for addresses and deduce type from valid ones. * Metadata: Do not include platform in the version number. + * Metadata: Add option to store sources as literal content. * Code generator: Extract array utils into low-level functions. Bugfixes: * Code generator: Allow recursive structs. + * Inline assembly: Disallow variables named like opcodes. * Type checker: Allow multiple events of the same name (but with different arities or argument types) ### 0.4.8 (2017-01-13) diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index ef3da255..fcc92dbb 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -71,6 +71,8 @@ assembly::Statement Parser::parseStatement() expectToken(Token::Colon); assignment.variableName.location = location(); assignment.variableName.name = m_scanner->currentLiteral(); + if (instructions().count(assignment.variableName.name)) + fatalParserError("Identifier expected, got instruction name."); assignment.location.end = endPosition(); expectToken(Token::Identifier); return assignment; @@ -101,6 +103,8 @@ assembly::Statement Parser::parseStatement() { // functional assignment FunctionalAssignment funAss = createWithLocation<FunctionalAssignment>(identifier.location); + if (instructions().count(identifier.name)) + fatalParserError("Cannot use instruction names for identifier names."); m_scanner->next(); funAss.variableName = identifier; funAss.value.reset(new Statement(parseExpression())); @@ -130,7 +134,7 @@ assembly::Statement Parser::parseExpression() return operation; } -assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) +std::map<string, dev::solidity::Instruction> const& Parser::instructions() { // Allowed instructions, lowercase names. static map<string, dev::solidity::Instruction> s_instructions; @@ -151,7 +155,11 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) // add alias for selfdestruct s_instructions["selfdestruct"] = solidity::Instruction::SUICIDE; } + return s_instructions; +} +assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) +{ Statement ret; switch (m_scanner->currentToken()) { @@ -170,9 +178,9 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher) else literal = m_scanner->currentLiteral(); // first search the set of instructions. - if (s_instructions.count(literal)) + if (instructions().count(literal)) { - dev::solidity::Instruction const& instr = s_instructions[literal]; + dev::solidity::Instruction const& instr = instructions().at(literal); if (_onlySinglePusher) { InstructionInfo info = dev::solidity::instructionInfo(instr); @@ -207,6 +215,8 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration() VariableDeclaration varDecl = createWithLocation<VariableDeclaration>(); expectToken(Token::Let); varDecl.name = m_scanner->currentLiteral(); + if (instructions().count(varDecl.name)) + fatalParserError("Cannot use instruction names for identifier names."); expectToken(Token::Identifier); expectToken(Token::Colon); expectToken(Token::Assign); diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h index 8b56ab90..643548dd 100644 --- a/libsolidity/inlineasm/AsmParser.h +++ b/libsolidity/inlineasm/AsmParser.h @@ -64,6 +64,7 @@ protected: Statement parseStatement(); /// Parses a functional expression that has to push exactly one stack element Statement parseExpression(); + std::map<std::string, dev::solidity::Instruction> const& instructions(); Statement parseElementaryOperation(bool _onlySinglePusher = false); VariableDeclaration parseVariableDeclaration(); FunctionalInstruction parseFunctionalInstruction(Statement&& _instruction); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index b26bd501..3335c40e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -726,10 +726,15 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const solAssert(s.second.scanner, "Scanner not available"); meta["sources"][s.first]["keccak256"] = "0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes()); - meta["sources"][s.first]["urls"] = Json::arrayValue; - meta["sources"][s.first]["urls"].append( - "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()) - ); + if (m_metadataLiteralSources) + meta["sources"][s.first]["content"] = s.second.scanner->source(); + else + { + meta["sources"][s.first]["urls"] = Json::arrayValue; + meta["sources"][s.first]["urls"].append( + "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()) + ); + } } meta["settings"]["optimizer"]["enabled"] = m_optimize; meta["settings"]["optimizer"]["runs"] = m_optimizeRuns; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 61edc284..9ee70215 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -177,6 +177,7 @@ public: /// Can be one of 4 types defined at @c DocumentationType Json::Value const& metadata(std::string const& _contractName, DocumentationType _type) const; std::string const& onChainMetadata(std::string const& _contractName) const; + void useMetadataLiteralSources(bool _metadataLiteralSources) { m_metadataLiteralSources = _metadataLiteralSources; } /// @returns the previously used scanner, useful for counting lines during error reporting. Scanner const& scanner(std::string const& _sourceName = "") const; @@ -274,6 +275,7 @@ private: std::map<std::string const, Contract> m_contracts; std::string m_formalTranslation; ErrorList m_errors; + bool m_metadataLiteralSources = false; }; } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index b3ffa6bb..2c1f0644 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -22,28 +22,8 @@ */ #include "CommandLineInterface.h" -#ifdef _WIN32 // windows - #include <io.h> - #define isatty _isatty - #define fileno _fileno -#else // unix - #include <unistd.h> -#endif -#include <string> -#include <iostream> -#include <fstream> - -#include <boost/filesystem.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/algorithm/string.hpp> - #include "solidity/BuildInfo.h" -#include <libdevcore/Common.h> -#include <libdevcore/CommonData.h> -#include <libdevcore/CommonIO.h> -#include <libdevcore/JSON.h> -#include <libevmasm/Instruction.h> -#include <libevmasm/GasMeter.h> + #include <libsolidity/interface/Version.h> #include <libsolidity/parsing/Scanner.h> #include <libsolidity/parsing/Parser.h> @@ -54,9 +34,31 @@ #include <libsolidity/interface/CompilerStack.h> #include <libsolidity/interface/SourceReferenceFormatter.h> #include <libsolidity/interface/GasEstimator.h> -#include <libsolidity/inlineasm/AsmParser.h> #include <libsolidity/formal/Why3Translator.h> +#include <libevmasm/Instruction.h> +#include <libevmasm/GasMeter.h> + +#include <libdevcore/Common.h> +#include <libdevcore/CommonData.h> +#include <libdevcore/CommonIO.h> +#include <libdevcore/JSON.h> + +#include <boost/filesystem.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/algorithm/string.hpp> + +#ifdef _WIN32 // windows + #include <io.h> + #define isatty _isatty + #define fileno _fileno +#else // unix + #include <unistd.h> +#endif +#include <string> +#include <iostream> +#include <fstream> + using namespace std; namespace po = boost::program_options; @@ -98,6 +100,7 @@ static string const g_strSrcMap = "srcmap"; static string const g_strSrcMapRuntime = "srcmap-runtime"; static string const g_strVersion = "version"; static string const g_stdinFileNameStr = "<stdin>"; +static string const g_strMetadataLiteral = "metadata-literal"; static string const g_argAbi = g_strAbi; static string const g_argAddStandard = g_strAddStandard; @@ -126,6 +129,7 @@ static string const g_argOutputDir = g_strOutputDir; static string const g_argSignatureHashes = g_strSignatureHashes; static string const g_argVersion = g_strVersion; static string const g_stdinFileName = g_stdinFileNameStr; +static string const g_argMetadataLiteral = g_strMetadataLiteral; /// Possible arguments to for --combined-json static set<string> const g_combinedJsonArgs{ @@ -516,7 +520,8 @@ Allowed options)", g_argLink.c_str(), "Switch to linker mode, ignoring all options apart from --libraries " "and modify binaries in place." - ); + ) + (g_argMetadataLiteral.c_str(), "Store referenced sources are literal data in the metadata output."); po::options_description outputComponents("Output Components"); outputComponents.add_options() (g_argAst.c_str(), "AST of all source files.") @@ -639,6 +644,8 @@ bool CommandLineInterface::processInput() auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compiler->scanner(_sourceName); }; try { + if (m_args.count(g_argMetadataLiteral) > 0) + m_compiler->useMetadataLiteralSources(true); if (m_args.count(g_argInputFile)) m_compiler->setRemappings(m_args[g_argInputFile].as<vector<string>>()); for (auto const& sourceCode: m_sourceCodes) @@ -912,7 +919,6 @@ void CommandLineInterface::writeLinkedFiles() bool CommandLineInterface::assemble() { - //@TODO later, we will use the convenience interface and should also remove the include above bool successful = true; map<string, shared_ptr<Scanner>> scanners; for (auto const& src: m_sourceCodes) @@ -926,6 +932,7 @@ bool CommandLineInterface::assemble() m_assemblyStacks[src.first].assemble(); } for (auto const& stack: m_assemblyStacks) + { for (auto const& error: stack.second.errors()) SourceReferenceFormatter::printExceptionInformation( cerr, @@ -933,6 +940,9 @@ bool CommandLineInterface::assemble() (error->type() == Error::Type::Warning) ? "Warning" : "Error", [&](string const& _source) -> Scanner const& { return *scanners.at(_source); } ); + if (!Error::containsOnlyWarnings(stack.second.errors())) + successful = false; + } return successful; } diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index b8fc1823..bcfc43d7 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -21,12 +21,14 @@ */ #pragma once -#include <memory> -#include <boost/program_options.hpp> -#include <boost/filesystem/path.hpp> #include <libsolidity/interface/CompilerStack.h> #include <libsolidity/inlineasm/AsmStack.h> +#include <boost/program_options.hpp> +#include <boost/filesystem/path.hpp> + +#include <memory> + namespace dev { namespace solidity diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 64073edc..c051a982 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -182,6 +182,24 @@ BOOST_AUTO_TEST_CASE(error_tag) BOOST_CHECK(successAssemble("{ invalidJumpLabel }")); } +BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration) +{ + // Error message: "Cannot use instruction names for identifier names." + BOOST_CHECK(!successAssemble("{ let gas := 1 }")); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_assignment) +{ + // Error message: "Identifier expected, got instruction name." + BOOST_CHECK(!successAssemble("{ 2 =: gas }")); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_functional_assignment) +{ + // Error message: "Cannot use instruction names for identifier names." + BOOST_CHECK(!successAssemble("{ gas := 2 }")); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index a3bfab75..e5362e78 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -1479,7 +1479,6 @@ BOOST_AUTO_TEST_CASE(function_type_state_variable) BOOST_CHECK(successParse(text)); } - BOOST_AUTO_TEST_SUITE_END() } |