mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
normalizeCLIPathForVFS(): Add an option for resolving symlinks
This commit is contained in:
parent
f0dceffe1d
commit
a436abfb25
@ -111,7 +111,10 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
}
|
||||
}
|
||||
|
||||
boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::path const& _path)
|
||||
boost::filesystem::path FileReader::normalizeCLIPathForVFS(
|
||||
boost::filesystem::path const& _path,
|
||||
SymlinkResolution _symlinkResolution
|
||||
)
|
||||
{
|
||||
// Detailed normalization rules:
|
||||
// - Makes the path either be absolute or have slash as root (note that on Windows paths with
|
||||
@ -125,7 +128,8 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::pa
|
||||
// path to the current working directory.
|
||||
//
|
||||
// Also note that this function:
|
||||
// - Does NOT resolve symlinks (except for symlinks in the path to the current working directory).
|
||||
// - Does NOT resolve symlinks (except for symlinks in the path to the current working directory)
|
||||
// unless explicitly requested.
|
||||
// - Does NOT check if the path refers to a file or a directory. If the path ends with a slash,
|
||||
// the slash is preserved even if it's a file.
|
||||
// - The only exception are paths where the file name is a dot (e.g. '.' or 'a/b/.'). These
|
||||
@ -139,9 +143,27 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::pa
|
||||
// Windows it does not. To get consistent results we resolve them on all platforms.
|
||||
boost::filesystem::path absolutePath = boost::filesystem::absolute(_path, canonicalWorkDir);
|
||||
|
||||
// NOTE: boost path preserves certain differences that are ignored by its operator ==.
|
||||
// E.g. "a//b" vs "a/b" or "a/b/" vs "a/b/.". lexically_normal() does remove these differences.
|
||||
boost::filesystem::path normalizedPath = absolutePath.lexically_normal();
|
||||
boost::filesystem::path normalizedPath;
|
||||
if (_symlinkResolution == SymlinkResolution::Enabled)
|
||||
{
|
||||
// NOTE: weakly_canonical() will not convert a relative path into an absolute one if no
|
||||
// directory included in the path actually exists.
|
||||
normalizedPath = boost::filesystem::weakly_canonical(absolutePath);
|
||||
|
||||
// The three corner cases in which lexically_normal() includes a trailing slash in the
|
||||
// normalized path but weakly_canonical() does not. Note that the trailing slash is not
|
||||
// ignored when comparing paths with ==.
|
||||
if ((_path == "." || _path == "./" || _path == "../") && !boost::ends_with(normalizedPath.generic_string(), "/"))
|
||||
normalizedPath = normalizedPath.parent_path() / (normalizedPath.filename().string() + "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(_symlinkResolution == SymlinkResolution::Disabled, "");
|
||||
|
||||
// NOTE: boost path preserves certain differences that are ignored by its operator ==.
|
||||
// E.g. "a//b" vs "a/b" or "a/b/" vs "a/b/.". lexically_normal() does remove these differences.
|
||||
normalizedPath = absolutePath.lexically_normal();
|
||||
}
|
||||
solAssert(normalizedPath.is_absolute() || normalizedPath.root_path() == "/", "");
|
||||
|
||||
// If the path is on the same drive as the working dir, for portability we prefer not to
|
||||
|
@ -39,6 +39,11 @@ public:
|
||||
using PathMap = std::map<SourceUnitName, boost::filesystem::path>;
|
||||
using FileSystemPathSet = std::set<boost::filesystem::path>;
|
||||
|
||||
enum SymlinkResolution {
|
||||
Disabled, ///< Do not resolve symbolic links in the path.
|
||||
Enabled, ///< Follow symbolic links. The path should contain no symlinks.
|
||||
};
|
||||
|
||||
/// Constructs a FileReader with a base path and a set of allowed directories that
|
||||
/// will be used when requesting files from this file reader instance.
|
||||
explicit FileReader(
|
||||
@ -90,11 +95,16 @@ public:
|
||||
|
||||
/// Normalizes a filesystem path to make it include all components up to the filesystem root,
|
||||
/// remove small, inconsequential differences that do not affect the meaning and make it look
|
||||
/// the same on all platforms (if possible). Symlinks in the path are not resolved.
|
||||
/// the same on all platforms (if possible).
|
||||
/// The resulting path uses forward slashes as path separators, has no redundant separators,
|
||||
/// has no redundant . or .. segments and has no root name if removing it does not change the meaning.
|
||||
/// The path does not have to actually exist.
|
||||
static boost::filesystem::path normalizeCLIPathForVFS(boost::filesystem::path const& _path);
|
||||
/// @param _path Path to normalize.
|
||||
/// @param _symlinkResolution If @a Disabled, any symlinks present in @a _path are preserved.
|
||||
static boost::filesystem::path normalizeCLIPathForVFS(
|
||||
boost::filesystem::path const& _path,
|
||||
SymlinkResolution _symlinkResolution = SymlinkResolution::Disabled
|
||||
);
|
||||
|
||||
/// @returns true if all the path components of @a _prefix are present at the beginning of @a _path.
|
||||
/// Both paths must be absolute (or have slash as root) and normalized (no . or .. segments, no
|
||||
|
@ -36,31 +36,36 @@ using namespace solidity::test;
|
||||
namespace solidity::frontend::test
|
||||
{
|
||||
|
||||
using SymlinkResolution = FileReader::SymlinkResolution;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(FileReaderTest)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_absolute_path)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./."), "/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/.", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./.", resolveSymlinks), "/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/"), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/."), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a/"), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a/."), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b"), "/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/", resolveSymlinks), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/.", resolveSymlinks), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a/", resolveSymlinks), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/./a/.", resolveSymlinks), "/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b", resolveSymlinks), "/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/", resolveSymlinks), "/a/b/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/./b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../a/b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/.."), "/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/./b/", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../a/b/", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/..", resolveSymlinks), "/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../", resolveSymlinks), "/a/b/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../../../"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b/c/../../../", resolveSymlinks), "/");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_relative_path)
|
||||
@ -75,54 +80,60 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_relative_path)
|
||||
expectedPrefix = "/" / expectedPrefix.relative_path();
|
||||
soltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == "/", "");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("."), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./"), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(".//"), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(".."), expectedPrefix / "x/y");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../"), expectedPrefix / "x/y/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("..//"), expectedPrefix / "x/y/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(".", resolveSymlinks), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./", resolveSymlinks), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(".//", resolveSymlinks), expectedPrefix / "x/y/z/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("..", resolveSymlinks), expectedPrefix / "x/y");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../", resolveSymlinks), expectedPrefix / "x/y/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("..//", resolveSymlinks), expectedPrefix / "x/y/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a"), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/."), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a"), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/."), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/./"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/.//"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/./."), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/././"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/././/"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b"), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/"), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a", resolveSymlinks), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/.", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a", resolveSymlinks), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/.", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/./", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/.//", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/./.", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/././", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/././/", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b", resolveSymlinks), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/", resolveSymlinks), expectedPrefix / "x/y/z/a/b/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/b"), expectedPrefix / "x/y/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/b"), expectedPrefix / "x/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/b"), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("././a/b"), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/b", resolveSymlinks), expectedPrefix / "x/y/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/b", resolveSymlinks), expectedPrefix / "x/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("./a/b", resolveSymlinks), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("././a/b", resolveSymlinks), expectedPrefix / "x/y/z/a/b");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/./b/"), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../a/b/"), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/.."), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../"), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/..//"), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../.."), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../../"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../..//"), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/./b/", resolveSymlinks), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../a/b/", resolveSymlinks), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/..", resolveSymlinks), expectedPrefix / "x/y/z/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../", resolveSymlinks), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/..//", resolveSymlinks), expectedPrefix / "x/y/z/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../..", resolveSymlinks), expectedPrefix / "x/y/z/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../../", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/b/c/../..//", resolveSymlinks), expectedPrefix / "x/y/z/a/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/.././../p/../q/../a/b"), expectedPrefix / "a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/.././../p/../q/../a/b", resolveSymlinks), expectedPrefix / "a/b");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_redundant_slashes)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("///"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("////"), "/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("///", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("////", resolveSymlinks), "/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("////a/b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a//b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a////b/"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b//"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b////"), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("////a/b/", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a//b/", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a////b/", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b//", resolveSymlinks), "/a/b/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/b////", resolveSymlinks), "/a/b/");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path)
|
||||
@ -134,23 +145,26 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path)
|
||||
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
|
||||
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
|
||||
|
||||
// UNC paths start with // or \\ followed by a name. They are used for network shares on Windows.
|
||||
// On UNIX systems they are not supported but still treated in a special way.
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/"), "//host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b"), "//host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b/"), "//host/a/b/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
// UNC paths start with // or \\ followed by a name. They are used for network shares on Windows.
|
||||
// On UNIX systems they are not supported but still treated in a special way.
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/", resolveSymlinks), "//host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b", resolveSymlinks), "//host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host/a/b/", resolveSymlinks), "//host/a/b/");
|
||||
|
||||
#if defined(_WIN32)
|
||||
// On Windows an UNC path can also start with \\ instead of //
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/"), "//host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b"), "//host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b/"), "//host/a/b/");
|
||||
// On Windows an UNC path can also start with \\ instead of //
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/", resolveSymlinks), "//host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b", resolveSymlinks), "//host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b/", resolveSymlinks), "//host/a/b/");
|
||||
#else
|
||||
// On UNIX systems it's just a fancy relative path instead
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/"), expectedWorkDir / "\\\\host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b"), expectedWorkDir / "\\\\host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b/"), expectedWorkDir / "\\\\host/a/b/");
|
||||
// On UNIX systems it's just a fancy relative path instead
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/", resolveSymlinks), expectedWorkDir / "\\\\host/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b", resolveSymlinks), expectedWorkDir / "\\\\host/a/b");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("\\\\host/a/b/", resolveSymlinks), expectedWorkDir / "\\\\host/a/b/");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only)
|
||||
@ -167,20 +181,23 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only)
|
||||
// C:\ represents the root directory of drive C: but C: on its own refers to the current working
|
||||
// directory.
|
||||
|
||||
// UNC paths
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//"), "//" / expectedWorkDir);
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host"), "//host" / expectedWorkDir);
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
// UNC paths
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//", resolveSymlinks), "//" / expectedWorkDir);
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("//host", resolveSymlinks), "//host" / expectedWorkDir);
|
||||
|
||||
// On UNIX systems root name is empty.
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(""), expectedWorkDir);
|
||||
// On UNIX systems root name is empty.
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("", resolveSymlinks), expectedWorkDir);
|
||||
|
||||
#if defined(_WIN32)
|
||||
boost::filesystem::path driveLetter = boost::filesystem::current_path().root_name();
|
||||
solAssert(!driveLetter.empty(), "");
|
||||
solAssert(driveLetter.is_relative(), "");
|
||||
boost::filesystem::path driveLetter = boost::filesystem::current_path().root_name();
|
||||
solAssert(!driveLetter.empty(), "");
|
||||
solAssert(driveLetter.is_relative(), "");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(driveLetter), expectedWorkDir);
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(driveLetter, resolveSymlinks), expectedWorkDir);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_stripping_root_name)
|
||||
@ -193,41 +210,50 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_stripping_root_name)
|
||||
soltestAssert(!boost::filesystem::current_path().root_name().empty(), "");
|
||||
#endif
|
||||
|
||||
boost::filesystem::path normalizedPath = FileReader::normalizeCLIPathForVFS(boost::filesystem::current_path());
|
||||
BOOST_CHECK_EQUAL(normalizedPath, "/" / boost::filesystem::current_path().relative_path());
|
||||
BOOST_TEST(normalizedPath.root_name().empty());
|
||||
BOOST_CHECK_EQUAL(normalizedPath.root_directory(), "/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
boost::filesystem::path normalizedPath = FileReader::normalizeCLIPathForVFS(
|
||||
boost::filesystem::current_path(),
|
||||
resolveSymlinks
|
||||
);
|
||||
BOOST_CHECK_EQUAL(normalizedPath, "/" / boost::filesystem::current_path().relative_path());
|
||||
BOOST_TEST(normalizedPath.root_name().empty());
|
||||
BOOST_CHECK_EQUAL(normalizedPath.root_directory(), "/");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_beyond_root)
|
||||
{
|
||||
TemporaryWorkingDirectory tempWorkDir("/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a/.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a/.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../../b/../.."), "/");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../.", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a/..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a/..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/../../a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("/a/../../b/../..", resolveSymlinks), "/");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(".."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../"), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a"), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../../b/../.."), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../.", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a", resolveSymlinks), "/a");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("../../a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../..", resolveSymlinks), "/");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("a/../../b/../..", resolveSymlinks), "/");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_case_sensitivity)
|
||||
@ -235,22 +261,31 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_case_sensitivity)
|
||||
TemporaryDirectory tempDir(TEST_CASE_NAME);
|
||||
TemporaryWorkingDirectory tempWorkDir(tempDir);
|
||||
|
||||
boost::filesystem::path expectedPrefix = "/" / tempDir.path().relative_path();
|
||||
soltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == "/", "");
|
||||
boost::filesystem::path workDirNoSymlinks = boost::filesystem::weakly_canonical(tempDir);
|
||||
boost::filesystem::path expectedPrefix = "/" / workDirNoSymlinks.relative_path();
|
||||
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc") == expectedPrefix / "abc");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc") != expectedPrefix / "ABC");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(tempDir.path() / "ABC") != expectedPrefix / "abc");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(tempDir.path() / "ABC") == expectedPrefix / "ABC");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / "abc", resolveSymlinks) == expectedPrefix / "abc");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / "abc", resolveSymlinks) != expectedPrefix / "ABC");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / "ABC", resolveSymlinks) != expectedPrefix / "abc");
|
||||
BOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / "ABC", resolveSymlinks) == expectedPrefix / "ABC");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_separators)
|
||||
{
|
||||
// Even on Windows we want / as a separator.
|
||||
BOOST_TEST((FileReader::normalizeCLIPathForVFS("/a/b/c").native() == boost::filesystem::path("/a/b/c").native()));
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
// Even on Windows we want / as a separator.
|
||||
BOOST_TEST((
|
||||
FileReader::normalizeCLIPathForVFS("/a/b/c", resolveSymlinks).native() ==
|
||||
boost::filesystem::path("/a/b/c").native()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks)
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks_unless_requested)
|
||||
{
|
||||
TemporaryDirectory tempDir({"abc/"}, TEST_CASE_NAME);
|
||||
soltestAssert(tempDir.path().is_absolute(), "");
|
||||
@ -258,11 +293,26 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks)
|
||||
if (!createSymlinkIfSupportedByFilesystem(tempDir.path() / "abc", tempDir.path() / "sym", true))
|
||||
return;
|
||||
|
||||
boost::filesystem::path expectedPrefix = "/" / tempDir.path().relative_path();
|
||||
soltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == "/", "");
|
||||
boost::filesystem::path expectedPrefixWithSymlinks = "/" / tempDir.path().relative_path();
|
||||
boost::filesystem::path expectedPrefixWithoutSymlinks = "/" / boost::filesystem::weakly_canonical(tempDir).relative_path();
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol"), expectedPrefix / "sym/contract.sol");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol"), expectedPrefix / "abc/contract.sol");
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol", SymlinkResolution::Disabled),
|
||||
expectedPrefixWithSymlinks / "sym/contract.sol"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol", SymlinkResolution::Disabled),
|
||||
expectedPrefixWithSymlinks / "abc/contract.sol"
|
||||
);
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol", SymlinkResolution::Enabled),
|
||||
expectedPrefixWithoutSymlinks / "abc/contract.sol"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol", SymlinkResolution::Enabled),
|
||||
expectedPrefixWithoutSymlinks / "abc/contract.sol"
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_resolve_symlinks_in_workdir_when_path_is_relative)
|
||||
@ -280,9 +330,31 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_resolve_symlinks_in_workdir_w
|
||||
boost::filesystem::path expectedPrefix = "/" / tempDir.path().relative_path();
|
||||
soltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == "/", "");
|
||||
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS("contract.sol"), expectedWorkDir / "contract.sol");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol"), expectedPrefix / "sym/contract.sol");
|
||||
BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol"), expectedPrefix / "abc/contract.sol");
|
||||
for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})
|
||||
{
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS("contract.sol", resolveSymlinks),
|
||||
expectedWorkDir / "contract.sol"
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol", SymlinkResolution::Disabled),
|
||||
expectedPrefix / "sym/contract.sol"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol", SymlinkResolution::Disabled),
|
||||
expectedPrefix / "abc/contract.sol"
|
||||
);
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "sym/contract.sol", SymlinkResolution::Enabled),
|
||||
expectedWorkDir / "contract.sol"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(
|
||||
FileReader::normalizeCLIPathForVFS(tempDir.path() / "abc/contract.sol", SymlinkResolution::Enabled),
|
||||
expectedWorkDir / "contract.sol"
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(isPathPrefix_file_prefix)
|
||||
|
Loading…
Reference in New Issue
Block a user