mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow remappings with empty prefix.
This commit is contained in:
parent
43db88b836
commit
954d7433bd
@ -16,6 +16,7 @@ Breaking Changes:
|
|||||||
* Commandline interface: Remove obsolete ``--formal`` option.
|
* Commandline interface: Remove obsolete ``--formal`` option.
|
||||||
* Commandline interface: Rename the ``--julia`` option to ``--yul``.
|
* Commandline interface: Rename the ``--julia`` option to ``--yul``.
|
||||||
* Commandline interface: Require ``-`` if standard input is used as source.
|
* Commandline interface: Require ``-`` if standard input is used as source.
|
||||||
|
* Compiler interface: Disallow remappings with empty prefix.
|
||||||
* Control Flow Analyzer: Turn warning about returning uninitialized storage pointers into an error.
|
* Control Flow Analyzer: Turn warning about returning uninitialized storage pointers into an error.
|
||||||
* General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code.
|
* General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code.
|
||||||
* General: Disallow declaring empty structs.
|
* General: Disallow declaring empty structs.
|
||||||
|
@ -58,22 +58,31 @@ using namespace std;
|
|||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
|
|
||||||
void CompilerStack::setRemappings(vector<string> const& _remappings)
|
boost::optional<CompilerStack::Remapping> CompilerStack::parseRemapping(string const& _remapping)
|
||||||
{
|
{
|
||||||
vector<Remapping> remappings;
|
auto eq = find(_remapping.begin(), _remapping.end(), '=');
|
||||||
for (auto const& remapping: _remappings)
|
if (eq == _remapping.end())
|
||||||
{
|
return {};
|
||||||
auto eq = find(remapping.begin(), remapping.end(), '=');
|
|
||||||
if (eq == remapping.end())
|
auto colon = find(_remapping.begin(), eq, ':');
|
||||||
continue; // ignore
|
|
||||||
auto colon = find(remapping.begin(), eq, ':');
|
|
||||||
Remapping r;
|
Remapping r;
|
||||||
r.context = colon == eq ? string() : string(remapping.begin(), colon);
|
|
||||||
r.prefix = colon == eq ? string(remapping.begin(), eq) : string(colon + 1, eq);
|
r.context = colon == eq ? string() : string(_remapping.begin(), colon);
|
||||||
r.target = string(eq + 1, remapping.end());
|
r.prefix = colon == eq ? string(_remapping.begin(), eq) : string(colon + 1, eq);
|
||||||
remappings.push_back(r);
|
r.target = string(eq + 1, _remapping.end());
|
||||||
|
|
||||||
|
if (r.prefix.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
swap(m_remappings, remappings);
|
|
||||||
|
void CompilerStack::setRemappings(vector<Remapping> const& _remappings)
|
||||||
|
{
|
||||||
|
for (auto const& remapping: _remappings)
|
||||||
|
solAssert(!remapping.prefix.empty(), "");
|
||||||
|
m_remappings = _remappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerStack::setEVMVersion(EVMVersion _version)
|
void CompilerStack::setEVMVersion(EVMVersion _version)
|
||||||
|
@ -84,6 +84,13 @@ public:
|
|||||||
CompilationSuccessful
|
CompilationSuccessful
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Remapping
|
||||||
|
{
|
||||||
|
std::string context;
|
||||||
|
std::string prefix;
|
||||||
|
std::string target;
|
||||||
|
};
|
||||||
|
|
||||||
/// Creates a new compiler stack.
|
/// Creates a new compiler stack.
|
||||||
/// @param _readFile callback to used to read files for import statements. Must return
|
/// @param _readFile callback to used to read files for import statements. Must return
|
||||||
/// and must not emit exceptions.
|
/// and must not emit exceptions.
|
||||||
@ -103,8 +110,11 @@ public:
|
|||||||
/// All settings, with the exception of remappings, are reset.
|
/// All settings, with the exception of remappings, are reset.
|
||||||
void reset(bool _keepSources = false);
|
void reset(bool _keepSources = false);
|
||||||
|
|
||||||
/// Sets path remappings in the format "context:prefix=target"
|
// Parses a remapping of the format "context:prefix=target".
|
||||||
void setRemappings(std::vector<std::string> const& _remappings);
|
static boost::optional<Remapping> parseRemapping(std::string const& _remapping);
|
||||||
|
|
||||||
|
/// Sets path remappings.
|
||||||
|
void setRemappings(std::vector<Remapping> const& _remappings);
|
||||||
|
|
||||||
/// Sets library addresses. Addresses are cleared iff @a _libraries is missing.
|
/// Sets library addresses. Addresses are cleared iff @a _libraries is missing.
|
||||||
/// Will not take effect before running compile.
|
/// Will not take effect before running compile.
|
||||||
@ -319,13 +329,6 @@ private:
|
|||||||
FunctionDefinition const& _function
|
FunctionDefinition const& _function
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
struct Remapping
|
|
||||||
{
|
|
||||||
std::string context;
|
|
||||||
std::string prefix;
|
|
||||||
std::string target;
|
|
||||||
};
|
|
||||||
|
|
||||||
ReadCallback::Callback m_readFile;
|
ReadCallback::Callback m_readFile;
|
||||||
ReadCallback::Callback m_smtQuery;
|
ReadCallback::Callback m_smtQuery;
|
||||||
bool m_optimize = false;
|
bool m_optimize = false;
|
||||||
|
@ -326,9 +326,14 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
|||||||
m_compilerStack.setEVMVersion(*version);
|
m_compilerStack.setEVMVersion(*version);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> remappings;
|
vector<CompilerStack::Remapping> remappings;
|
||||||
for (auto const& remapping: settings.get("remappings", Json::Value()))
|
for (auto const& remapping: settings.get("remappings", Json::Value()))
|
||||||
remappings.push_back(remapping.asString());
|
{
|
||||||
|
if (auto r = CompilerStack::parseRemapping(remapping.asString()))
|
||||||
|
remappings.emplace_back(std::move(*r));
|
||||||
|
else
|
||||||
|
return formatFatalError("JSONError", "Invalid remapping: \"" + remapping.asString() + "\"");
|
||||||
|
}
|
||||||
m_compilerStack.setRemappings(remappings);
|
m_compilerStack.setRemappings(remappings);
|
||||||
|
|
||||||
Json::Value optimizerSettings = settings.get("optimizer", Json::Value());
|
Json::Value optimizerSettings = settings.get("optimizer", Json::Value());
|
||||||
|
@ -392,7 +392,18 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
|||||||
{
|
{
|
||||||
auto eq = find(path.begin(), path.end(), '=');
|
auto eq = find(path.begin(), path.end(), '=');
|
||||||
if (eq != path.end())
|
if (eq != path.end())
|
||||||
|
{
|
||||||
|
if (auto r = CompilerStack::parseRemapping(path))
|
||||||
|
{
|
||||||
|
m_remappings.emplace_back(std::move(*r));
|
||||||
path = string(eq + 1, path.end());
|
path = string(eq + 1, path.end());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "Invalid remapping: \"" << path << "\"." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (path == "-")
|
else if (path == "-")
|
||||||
addStdin = true;
|
addStdin = true;
|
||||||
else
|
else
|
||||||
@ -808,7 +819,7 @@ bool CommandLineInterface::processInput()
|
|||||||
if (m_args.count(g_argMetadataLiteral) > 0)
|
if (m_args.count(g_argMetadataLiteral) > 0)
|
||||||
m_compiler->useMetadataLiteralSources(true);
|
m_compiler->useMetadataLiteralSources(true);
|
||||||
if (m_args.count(g_argInputFile))
|
if (m_args.count(g_argInputFile))
|
||||||
m_compiler->setRemappings(m_args[g_argInputFile].as<vector<string>>());
|
m_compiler->setRemappings(m_remappings);
|
||||||
for (auto const& sourceCode: m_sourceCodes)
|
for (auto const& sourceCode: m_sourceCodes)
|
||||||
m_compiler->addSource(sourceCode.first, sourceCode.second);
|
m_compiler->addSource(sourceCode.first, sourceCode.second);
|
||||||
if (m_args.count(g_argLibraries))
|
if (m_args.count(g_argLibraries))
|
||||||
|
@ -97,6 +97,8 @@ private:
|
|||||||
boost::program_options::variables_map m_args;
|
boost::program_options::variables_map m_args;
|
||||||
/// map of input files to source code strings
|
/// map of input files to source code strings
|
||||||
std::map<std::string, std::string> m_sourceCodes;
|
std::map<std::string, std::string> m_sourceCodes;
|
||||||
|
/// list of remappings
|
||||||
|
std::vector<dev::solidity::CompilerStack::Remapping> m_remappings;
|
||||||
/// list of allowed directories to read files from
|
/// list of allowed directories to read files from
|
||||||
std::vector<boost::filesystem::path> m_allowedDirectories;
|
std::vector<boost::filesystem::path> m_allowedDirectories;
|
||||||
/// map of library names to addresses
|
/// map of library names to addresses
|
||||||
|
@ -144,6 +144,10 @@ test_solc_file_input_failures "file_not_found.sol" "" "" "\"file_not_found.sol\"
|
|||||||
printTask "Testing passing files that are not files..."
|
printTask "Testing passing files that are not files..."
|
||||||
test_solc_file_input_failures "." "" "" "\".\" is not a valid file."
|
test_solc_file_input_failures "." "" "" "\".\" is not a valid file."
|
||||||
|
|
||||||
|
printTask "Testing passing empty remappings..."
|
||||||
|
test_solc_file_input_failures "${0}" "=/some/remapping/target" "" "Invalid remapping: \"=/some/remapping/target\"."
|
||||||
|
test_solc_file_input_failures "${0}" "ctx:=/some/remapping/target" "" "Invalid remapping: \"ctx:=/some/remapping/target\"."
|
||||||
|
|
||||||
printTask "Compiling various other contracts and libraries..."
|
printTask "Compiling various other contracts and libraries..."
|
||||||
(
|
(
|
||||||
cd "$REPO_ROOT"/test/compilationTests/
|
cd "$REPO_ROOT"/test/compilationTests/
|
||||||
|
@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import)
|
|||||||
BOOST_AUTO_TEST_CASE(remappings)
|
BOOST_AUTO_TEST_CASE(remappings)
|
||||||
{
|
{
|
||||||
CompilerStack c;
|
CompilerStack c;
|
||||||
c.setRemappings(vector<string>{"s=s_1.4.6", "t=Tee"});
|
c.setRemappings(vector<CompilerStack::Remapping>{{"", "s", "s_1.4.6"},{"", "t", "Tee"}});
|
||||||
c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;");
|
c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;");
|
||||||
c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;");
|
c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;");
|
||||||
c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;");
|
c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;");
|
||||||
@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(remappings)
|
|||||||
BOOST_AUTO_TEST_CASE(context_dependent_remappings)
|
BOOST_AUTO_TEST_CASE(context_dependent_remappings)
|
||||||
{
|
{
|
||||||
CompilerStack c;
|
CompilerStack c;
|
||||||
c.setRemappings(vector<string>{"a:s=s_1.4.6", "b:s=s_1.4.7"});
|
c.setRemappings(vector<CompilerStack::Remapping>{{"a", "s", "s_1.4.6"}, {"b", "s", "s_1.4.7"}});
|
||||||
c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;");
|
c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;");
|
||||||
c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;");
|
c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;");
|
||||||
c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;");
|
c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;");
|
||||||
@ -200,7 +200,11 @@ BOOST_AUTO_TEST_CASE(filename_with_period)
|
|||||||
BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved)
|
BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved)
|
||||||
{
|
{
|
||||||
CompilerStack c;
|
CompilerStack c;
|
||||||
c.setRemappings(vector<string>{"foo=vendor/foo_2.0.0", "vendor/bar:foo=vendor/foo_1.0.0", "bar=vendor/bar"});
|
c.setRemappings(vector<CompilerStack::Remapping>{
|
||||||
|
{"", "foo", "vendor/foo_2.0.0"},
|
||||||
|
{"vendor/bar", "foo", "vendor/foo_1.0.0"},
|
||||||
|
{"", "bar", "vendor/bar"}
|
||||||
|
});
|
||||||
c.addSource("main.sol", "import \"foo/foo.sol\"; import {Bar} from \"bar/bar.sol\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;");
|
c.addSource("main.sol", "import \"foo/foo.sol\"; import {Bar} from \"bar/bar.sol\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;");
|
||||||
c.addSource("vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;");
|
c.addSource("vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;");
|
||||||
c.addSource("vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;");
|
c.addSource("vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;");
|
||||||
@ -212,7 +216,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_pres
|
|||||||
BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
||||||
{
|
{
|
||||||
CompilerStack c;
|
CompilerStack c;
|
||||||
c.setRemappings(vector<string>{"a:x/y/z=d", "a/b:x=e"});
|
c.setRemappings(vector<CompilerStack::Remapping>{{"a", "x/y/z", "d"}, {"a/b", "x", "e"}});
|
||||||
c.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;");
|
c.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;");
|
||||||
c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
||||||
c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
||||||
@ -220,7 +224,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
|||||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||||
BOOST_CHECK(c.compile());
|
BOOST_CHECK(c.compile());
|
||||||
CompilerStack d;
|
CompilerStack d;
|
||||||
d.setRemappings(vector<string>{"a/b:x=e", "a:x/y/z=d"});
|
d.setRemappings(vector<CompilerStack::Remapping>{{"a/b", "x", "e"}, {"a", "x/y/z", "d"}});
|
||||||
d.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;");
|
d.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;");
|
||||||
d.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
d.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
||||||
d.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
d.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
||||||
|
Loading…
Reference in New Issue
Block a user