mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Treat ambiguous imports as errors
This commit is contained in:
@@ -21,8 +21,10 @@
|
||||
|
||||
#include <libsolutil/CommonIO.h>
|
||||
#include <libsolutil/Exceptions.h>
|
||||
#include <libsolutil/StringUtils.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
|
||||
@@ -32,6 +34,7 @@ using solidity::frontend::ReadCallback;
|
||||
using solidity::langutil::InternalCompilerError;
|
||||
using solidity::util::errinfo_comment;
|
||||
using solidity::util::readFileAsString;
|
||||
using solidity::util::joinHumanReadable;
|
||||
using std::map;
|
||||
using std::reference_wrapper;
|
||||
using std::string;
|
||||
@@ -109,24 +112,38 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
if (strippedSourceUnitName.find("file://") == 0)
|
||||
strippedSourceUnitName.erase(0, 7);
|
||||
|
||||
vector<boost::filesystem::path> candidates;
|
||||
vector<reference_wrapper<boost::filesystem::path>> prefixes = {m_basePath};
|
||||
prefixes += (m_includePaths | ranges::to<vector<reference_wrapper<boost::filesystem::path>>>);
|
||||
|
||||
boost::filesystem::path canonicalPath;
|
||||
for (auto const& prefix: prefixes)
|
||||
{
|
||||
canonicalPath = normalizeCLIPathForVFS(prefix / strippedSourceUnitName, SymlinkResolution::Enabled);
|
||||
boost::filesystem::path canonicalPath = normalizeCLIPathForVFS(prefix / strippedSourceUnitName, SymlinkResolution::Enabled);
|
||||
|
||||
if (boost::filesystem::exists(canonicalPath))
|
||||
break;
|
||||
candidates.push_back(std::move(canonicalPath));
|
||||
}
|
||||
|
||||
auto pathToQuotedString = [](boost::filesystem::path const& _path){ return "\"" + _path.string() + "\""; };
|
||||
|
||||
if (candidates.empty())
|
||||
return ReadCallback::Result{false, "File not found."};
|
||||
|
||||
if (candidates.size() >= 2)
|
||||
return ReadCallback::Result{
|
||||
false,
|
||||
"Ambiguous import. "
|
||||
"Multiple matching files found inside base path and/or include paths: " +
|
||||
joinHumanReadable(candidates | ranges::views::transform(pathToQuotedString), ", ") +
|
||||
"."
|
||||
};
|
||||
|
||||
FileSystemPathSet extraAllowedPaths = {m_basePath.empty() ? "." : m_basePath};
|
||||
extraAllowedPaths += m_includePaths;
|
||||
|
||||
bool isAllowed = false;
|
||||
for (boost::filesystem::path const& allowedDir: m_allowedDirectories + extraAllowedPaths)
|
||||
if (isPathPrefix(normalizeCLIPathForVFS(allowedDir, SymlinkResolution::Enabled), canonicalPath))
|
||||
if (isPathPrefix(normalizeCLIPathForVFS(allowedDir, SymlinkResolution::Enabled), candidates[0]))
|
||||
{
|
||||
isAllowed = true;
|
||||
break;
|
||||
@@ -135,14 +152,12 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
if (!isAllowed)
|
||||
return ReadCallback::Result{false, "File outside of allowed directories."};
|
||||
|
||||
if (!boost::filesystem::exists(canonicalPath))
|
||||
return ReadCallback::Result{false, "File not found."};
|
||||
|
||||
if (!boost::filesystem::is_regular_file(canonicalPath))
|
||||
if (!boost::filesystem::is_regular_file(candidates[0]))
|
||||
return ReadCallback::Result{false, "Not a valid file."};
|
||||
|
||||
// NOTE: we ignore the FileNotFound exception as we manually check above
|
||||
auto contents = readFileAsString(canonicalPath);
|
||||
auto contents = readFileAsString(candidates[0]);
|
||||
solAssert(m_sourceCodes.count(_sourceUnitName) == 0, "");
|
||||
m_sourceCodes[_sourceUnitName] = contents;
|
||||
return ReadCallback::Result{true, contents};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user