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: Rename the ``--julia`` option to ``--yul``.
|
||||
* 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.
|
||||
* 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.
|
||||
|
@ -58,22 +58,31 @@ using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void CompilerStack::setRemappings(vector<string> const& _remappings)
|
||||
boost::optional<CompilerStack::Remapping> CompilerStack::parseRemapping(string const& _remapping)
|
||||
{
|
||||
auto eq = find(_remapping.begin(), _remapping.end(), '=');
|
||||
if (eq == _remapping.end())
|
||||
return {};
|
||||
|
||||
auto colon = find(_remapping.begin(), eq, ':');
|
||||
|
||||
Remapping r;
|
||||
|
||||
r.context = colon == eq ? string() : string(_remapping.begin(), colon);
|
||||
r.prefix = colon == eq ? string(_remapping.begin(), eq) : string(colon + 1, eq);
|
||||
r.target = string(eq + 1, _remapping.end());
|
||||
|
||||
if (r.prefix.empty())
|
||||
return {};
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void CompilerStack::setRemappings(vector<Remapping> const& _remappings)
|
||||
{
|
||||
vector<Remapping> remappings;
|
||||
for (auto const& remapping: _remappings)
|
||||
{
|
||||
auto eq = find(remapping.begin(), remapping.end(), '=');
|
||||
if (eq == remapping.end())
|
||||
continue; // ignore
|
||||
auto colon = find(remapping.begin(), eq, ':');
|
||||
Remapping r;
|
||||
r.context = colon == eq ? string() : string(remapping.begin(), colon);
|
||||
r.prefix = colon == eq ? string(remapping.begin(), eq) : string(colon + 1, eq);
|
||||
r.target = string(eq + 1, remapping.end());
|
||||
remappings.push_back(r);
|
||||
}
|
||||
swap(m_remappings, remappings);
|
||||
solAssert(!remapping.prefix.empty(), "");
|
||||
m_remappings = _remappings;
|
||||
}
|
||||
|
||||
void CompilerStack::setEVMVersion(EVMVersion _version)
|
||||
|
@ -84,6 +84,13 @@ public:
|
||||
CompilationSuccessful
|
||||
};
|
||||
|
||||
struct Remapping
|
||||
{
|
||||
std::string context;
|
||||
std::string prefix;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
/// Creates a new compiler stack.
|
||||
/// @param _readFile callback to used to read files for import statements. Must return
|
||||
/// and must not emit exceptions.
|
||||
@ -103,8 +110,11 @@ public:
|
||||
/// All settings, with the exception of remappings, are reset.
|
||||
void reset(bool _keepSources = false);
|
||||
|
||||
/// Sets path remappings in the format "context:prefix=target"
|
||||
void setRemappings(std::vector<std::string> const& _remappings);
|
||||
// Parses a remapping of the format "context:prefix=target".
|
||||
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.
|
||||
/// Will not take effect before running compile.
|
||||
@ -319,13 +329,6 @@ private:
|
||||
FunctionDefinition const& _function
|
||||
) const;
|
||||
|
||||
struct Remapping
|
||||
{
|
||||
std::string context;
|
||||
std::string prefix;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
ReadCallback::Callback m_readFile;
|
||||
ReadCallback::Callback m_smtQuery;
|
||||
bool m_optimize = false;
|
||||
|
@ -326,9 +326,14 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
|
||||
m_compilerStack.setEVMVersion(*version);
|
||||
}
|
||||
|
||||
vector<string> remappings;
|
||||
vector<CompilerStack::Remapping> remappings;
|
||||
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);
|
||||
|
||||
Json::Value optimizerSettings = settings.get("optimizer", Json::Value());
|
||||
|
@ -392,7 +392,18 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
||||
{
|
||||
auto eq = find(path.begin(), path.end(), '=');
|
||||
if (eq != path.end())
|
||||
path = string(eq + 1, path.end());
|
||||
{
|
||||
if (auto r = CompilerStack::parseRemapping(path))
|
||||
{
|
||||
m_remappings.emplace_back(std::move(*r));
|
||||
path = string(eq + 1, path.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Invalid remapping: \"" << path << "\"." << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (path == "-")
|
||||
addStdin = true;
|
||||
else
|
||||
@ -808,7 +819,7 @@ bool CommandLineInterface::processInput()
|
||||
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>>());
|
||||
m_compiler->setRemappings(m_remappings);
|
||||
for (auto const& sourceCode: m_sourceCodes)
|
||||
m_compiler->addSource(sourceCode.first, sourceCode.second);
|
||||
if (m_args.count(g_argLibraries))
|
||||
|
@ -97,6 +97,8 @@ private:
|
||||
boost::program_options::variables_map m_args;
|
||||
/// map of input files to source code strings
|
||||
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
|
||||
std::vector<boost::filesystem::path> m_allowedDirectories;
|
||||
/// 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..."
|
||||
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..."
|
||||
(
|
||||
cd "$REPO_ROOT"/test/compilationTests/
|
||||
|
@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import)
|
||||
BOOST_AUTO_TEST_CASE(remappings)
|
||||
{
|
||||
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("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;");
|
||||
@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(remappings)
|
||||
BOOST_AUTO_TEST_CASE(context_dependent_remappings)
|
||||
{
|
||||
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("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;");
|
||||
@ -200,7 +200,11 @@ BOOST_AUTO_TEST_CASE(filename_with_period)
|
||||
BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved)
|
||||
{
|
||||
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("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;");
|
||||
@ -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)
|
||||
{
|
||||
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/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;");
|
||||
@ -220,7 +224,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
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/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;");
|
||||
|
Loading…
Reference in New Issue
Block a user