aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-01-12 19:02:30 +0800
committerGitHub <noreply@github.com>2017-01-12 19:02:30 +0800
commit74d74fb00bc159076d8322c5780894b1c2d68791 (patch)
tree9405b030e69a9c03a20981e0f8953640af0c83db
parentb983c7492f7c22a441ef360809085ab2a00150c0 (diff)
parentb6508ca992531154a572320bf8bb117e3b9294b9 (diff)
downloaddexon-solidity-74d74fb00bc159076d8322c5780894b1c2d68791.tar.gz
dexon-solidity-74d74fb00bc159076d8322c5780894b1c2d68791.tar.zst
dexon-solidity-74d74fb00bc159076d8322c5780894b1c2d68791.zip
Merge pull request #1548 from VoR0220/remappingBugFix
Remapping bug fix
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/interface/CompilerStack.cpp25
-rw-r--r--libsolidity/interface/CompilerStack.h5
-rw-r--r--test/libsolidity/Imports.cpp29
4 files changed, 51 insertions, 9 deletions
diff --git a/Changelog.md b/Changelog.md
index 8a005eed..7676b5be 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -4,6 +4,7 @@ Features:
* Output: Print assembly in new standardized Solidity assembly format.
BugFixes:
+ * Remappings: Prefer longer context over longer prefix.
* Type checker, code generator: enable access to events of base contracts' names.
* Imports: ``import ".dir/a"`` is not a relative path. Relative paths begin with directory ``.`` or ``..``.
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index ee55f41a..a31df584 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -509,23 +509,32 @@ string CompilerStack::applyRemapping(string const& _path, string const& _context
};
size_t longestPrefix = 0;
- string longestPrefixTarget;
+ size_t longestContext = 0;
+ string bestMatchTarget;
+
for (auto const& redir: m_remappings)
{
- // Skip if we already have a closer match.
- if (longestPrefix > 0 && redir.prefix.length() <= longestPrefix)
+ string context = sanitizePath(redir.context);
+ string prefix = sanitizePath(redir.prefix);
+
+ // Skip if current context is closer
+ if (context.length() < longestContext)
continue;
// Skip if redir.context is not a prefix of _context
- if (!isPrefixOf(redir.context, _context))
+ if (!isPrefixOf(context, _context))
+ continue;
+ // Skip if we already have a closer prefix match.
+ if (prefix.length() < longestPrefix && context.length() == longestContext)
continue;
// Skip if the prefix does not match.
- if (!isPrefixOf(redir.prefix, _path))
+ if (!isPrefixOf(prefix, _path))
continue;
- longestPrefix = redir.prefix.length();
- longestPrefixTarget = redir.target;
+ longestContext = context.length();
+ longestPrefix = prefix.length();
+ bestMatchTarget = sanitizePath(redir.target);
}
- string path = longestPrefixTarget;
+ string path = bestMatchTarget;
path.append(_path.begin() + longestPrefix, _path.end());
return path;
}
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index f98a457a..d49a8df1 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -29,6 +29,7 @@
#include <vector>
#include <functional>
#include <boost/noncopyable.hpp>
+#include <boost/filesystem.hpp>
#include <json/json.h>
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
@@ -234,12 +235,14 @@ private:
bool checkLibraryNameClashes();
/// @returns the absolute path corresponding to @a _path relative to @a _reference.
std::string absolutePath(std::string const& _path, std::string const& _reference) const;
+ /// Helper function to return path converted strings.
+ std::string sanitizePath(std::string const& _path) const { return boost::filesystem::path(_path).generic_string(); }
+
/// Compile a single contract and put the result in @a _compiledContracts.
void compileContract(
ContractDefinition const& _contract,
std::map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
);
-
void link();
Contract const& contract(std::string const& _contractName = "") const;
diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp
index e3f0b281..56895fdc 100644
--- a/test/libsolidity/Imports.cpp
+++ b/test/libsolidity/Imports.cpp
@@ -172,6 +172,35 @@ BOOST_AUTO_TEST_CASE(filename_with_period)
BOOST_CHECK(!c.compile());
}
+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.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;");
+ c.addSource("vendor/foo_2.0.0/foo.sol", "contract Foo2 {} pragma solidity >=0.0;");
+ BOOST_CHECK(c.compile());
+}
+
+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.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;");
+ c.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;");
+ BOOST_CHECK(c.compile());
+ CompilerStack d;
+ d.setRemappings(vector<string>{"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;");
+ d.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;");
+ BOOST_CHECK(d.compile());
+}
+
BOOST_AUTO_TEST_SUITE_END()
}