Skip to content

Commit

Permalink
merge bitcoin#24265: Drop StripRedundantLastElementsOfPath() function
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Oct 28, 2024
1 parent 2d299f1 commit 9a8d6e1
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);

// Warn about relative -datadir path.
if (args.IsArgSet("-datadir") && !fs::PathFromString(args.GetArg("-datadir", "")).is_absolute()) {
if (args.IsArgSet("-datadir") && !args.GetPathArg("-datadir").is_absolute()) {
LogPrintf("Warning: relative datadir option '%s' specified, which will be interpreted relative to the " /* Continued */
"current working directory '%s'. This is fragile, because if Dash Core is started in the future "
"from a different location, it will be unable to locate the current data files. There could "
Expand Down
92 changes: 92 additions & 0 deletions src/test/getarg_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,98 @@ BOOST_AUTO_TEST_CASE(intarg)
BOOST_CHECK_EQUAL(m_local_args.GetArg("-bar", 11), 0);
}

BOOST_AUTO_TEST_CASE(patharg)
{
const auto dir = std::make_pair("-dir", ArgsManager::ALLOW_ANY);
SetupArgs({dir});
ResetArgs("");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), fs::path{});

const fs::path root_path{"/"};
ResetArgs("-dir=/");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), root_path);

ResetArgs("-dir=/.");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), root_path);

ResetArgs("-dir=/./");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), root_path);

ResetArgs("-dir=/.//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), root_path);

#ifdef WIN32
const fs::path win_root_path{"C:\\"};
ResetArgs("-dir=C:\\");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);

ResetArgs("-dir=C:/");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);

ResetArgs("-dir=C:\\\\");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);

ResetArgs("-dir=C:\\.");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);

ResetArgs("-dir=C:\\.\\");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);

ResetArgs("-dir=C:\\.\\\\");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), win_root_path);
#endif

const fs::path absolute_path{"/home/user/.bitcoin"};
ResetArgs("-dir=/home/user/.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/root/../home/user/.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/./user/.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/user/.bitcoin/");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/user/.bitcoin//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/user/.bitcoin/.");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/user/.bitcoin/./");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

ResetArgs("-dir=/home/user/.bitcoin/.//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), absolute_path);

const fs::path relative_path{"user/.bitcoin"};
ResetArgs("-dir=user/.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=somewhere/../user/.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/./.bitcoin");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/.bitcoin/");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/.bitcoin//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/.bitcoin/.");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/.bitcoin/./");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);

ResetArgs("-dir=user/.bitcoin/.//");
BOOST_CHECK_EQUAL(m_local_args.GetPathArg("-dir"), relative_path);
}

BOOST_AUTO_TEST_CASE(doubledash)
{
const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);
Expand Down
31 changes: 12 additions & 19 deletions src/util/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,19 +261,6 @@ static bool CheckValid(const std::string& key, const util::SettingsValue& val, u
return true;
}

namespace {
fs::path StripRedundantLastElementsOfPath(const fs::path& path)
{
auto result = path;
while (result.filename().empty() || fs::PathToString(result.filename()) == ".") {
result = result.parent_path();
}

assert(fs::equivalent(result, path.lexically_normal()));
return result;
}
} // namespace

// Define default constructor and destructor that are not inline, so code instantiating this class doesn't need to
// #include class definitions for all members.
// For example, m_settings has an internal dependency on univalue.
Expand Down Expand Up @@ -420,6 +407,13 @@ std::optional<unsigned int> ArgsManager::GetArgFlags(const std::string& name) co
return std::nullopt;
}

fs::path ArgsManager::GetPathArg(std::string pathlike_arg) const
{
auto result = fs::PathFromString(GetArg(pathlike_arg, "")).lexically_normal();
// Remove trailing slash, if present.
return result.has_filename() ? result : result.parent_path();
}

const fs::path ArgsManager::GetBlocksDirPath() const
{
LOCK(cs_args);
Expand All @@ -430,7 +424,7 @@ const fs::path ArgsManager::GetBlocksDirPath() const
if (!path.empty()) return path;

if (IsArgSet("-blocksdir")) {
path = fs::absolute(fs::PathFromString(GetArg("-blocksdir", "")));
path = fs::absolute(GetPathArg("-blocksdir"));
if (!fs::is_directory(path)) {
path = "";
return path;
Expand All @@ -454,9 +448,9 @@ const fs::path ArgsManager::GetDataDir(bool net_specific) const
// this function
if (!path.empty()) return path;

std::string datadir = GetArg("-datadir", "");
const fs::path datadir{GetPathArg("-datadir")};
if (!datadir.empty()) {
path = fs::absolute(StripRedundantLastElementsOfPath(fs::PathFromString(datadir)));
path = fs::absolute(datadir);
if (!fs::is_directory(path)) {
path = "";
return path;
Expand All @@ -476,7 +470,6 @@ const fs::path ArgsManager::GetDataDir(bool net_specific) const
}
}

path = StripRedundantLastElementsOfPath(path);
return path;
}

Expand Down Expand Up @@ -871,8 +864,8 @@ fs::path GetBackupsDir()

bool CheckDataDirOption()
{
std::string datadir = gArgs.GetArg("-datadir", "");
return datadir.empty() || fs::is_directory(fs::absolute(fs::PathFromString(datadir)));
const fs::path datadir{gArgs.GetPathArg("-datadir")};
return datadir.empty() || fs::is_directory(fs::absolute(datadir));
}

fs::path GetConfigFile(const std::string& confPath)
Expand Down
10 changes: 10 additions & 0 deletions src/util/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,16 @@ class ArgsManager
*/
const std::map<std::string, std::vector<util::SettingsValue>> GetCommandLineArgs() const;

/**
* Get a normalized path from a specified pathlike argument
*
* It is guaranteed that the returned path has no trailing slashes.
*
* @param pathlike_arg Pathlike argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
* @return Normalized path which is get from a specified pathlike argument
*/
fs::path GetPathArg(std::string pathlike_arg) const;

/**
* Get blocks directory path
*
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
bool VerifyWallets(interfaces::Chain& chain)
{
if (gArgs.IsArgSet("-walletdir")) {
fs::path wallet_dir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
const fs::path wallet_dir{gArgs.GetPathArg("-walletdir")};
std::error_code error;
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
// It also lets the fs::exists and fs::is_directory checks below pass on windows, since they return false
Expand Down
8 changes: 4 additions & 4 deletions src/wallet/test/init_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_default)
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
}
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path walletdir = gArgs.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
Expand All @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_custom)
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
}
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path walletdir = gArgs.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["custom"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
Expand Down Expand Up @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
}
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path walletdir = gArgs.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
Expand All @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
}
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path walletdir = gArgs.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/walletutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fs::path GetWalletDir()
fs::path path;

if (gArgs.IsArgSet("-walletdir")) {
path = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
path = gArgs.GetPathArg("-walletdir");
if (!fs::is_directory(path)) {
// If the path specified doesn't exist, we return the deliberately
// invalid empty string.
Expand Down

0 comments on commit 9a8d6e1

Please sign in to comment.