Replace fs::absolute calls with AbsPathJoin calls

This adds better test coverage and will make it easier in #20744 to remove our dependency on the two-argument boost::filesystem::absolute() function which does not have a direct equivalent in C++17.
pull/826/head
Kiminuo 4 years ago
parent 66576c4fd5
commit da9caa1ced

@ -31,6 +31,12 @@ FILE *fopen(const fs::path& p, const char *mode)
#endif #endif
} }
fs::path AbsPathJoin(const fs::path& base, const fs::path& path)
{
assert(base.is_absolute());
return fs::absolute(path, base);
}
#ifndef WIN32 #ifndef WIN32
static std::string GetErrorReason() static std::string GetErrorReason()

@ -21,6 +21,17 @@ namespace fs = boost::filesystem;
namespace fsbridge { namespace fsbridge {
FILE *fopen(const fs::path& p, const char *mode); FILE *fopen(const fs::path& p, const char *mode);
/**
* Helper function for joining two paths
*
* @param[in] base Base path
* @param[in] path Path to combine with base
* @returns path unchanged if it is an absolute path, otherwise returns base joined with path. Returns base unchanged if path is empty.
* @pre Base path must be absolute
* @post Returned path will always be absolute
*/
fs::path AbsPathJoin(const fs::path& base, const fs::path& path);
class FileLock class FileLock
{ {
public: public:

@ -2399,10 +2399,10 @@ static RPCHelpMan dumptxoutset()
}, },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
fs::path path = fs::absolute(request.params[0].get_str(), GetDataDir()); const fs::path path = fsbridge::AbsPathJoin(GetDataDir(), request.params[0].get_str());
// Write to a temporary path and then move into `path` on completion // Write to a temporary path and then move into `path` on completion
// to avoid confusion due to an interruption. // to avoid confusion due to an interruption.
fs::path temppath = fs::absolute(request.params[0].get_str() + ".incomplete", GetDataDir()); const fs::path temppath = fsbridge::AbsPathJoin(GetDataDir(), request.params[0].get_str() + ".incomplete");
if (fs::exists(path)) { if (fs::exists(path)) {
throw JSONRPCError( throw JSONRPCError(

@ -52,6 +52,23 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
file >> input_buffer; file >> input_buffer;
BOOST_CHECK_EQUAL(input_buffer, "bitcoin"); BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
} }
{
// Join an absolute path and a relative path.
fs::path p = fsbridge::AbsPathJoin(tmpfolder, "fs_tests_₿_🏃");
BOOST_CHECK(p.is_absolute());
BOOST_CHECK_EQUAL(tmpfile1, p);
}
{
// Join two absolute paths.
fs::path p = fsbridge::AbsPathJoin(tmpfile1, tmpfile2);
BOOST_CHECK(p.is_absolute());
BOOST_CHECK_EQUAL(tmpfile2, p);
}
{
// Ensure joining with empty paths does not add trailing path components.
BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, ""));
BOOST_CHECK_EQUAL(tmpfile1, fsbridge::AbsPathJoin(tmpfile1, {}));
}
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

@ -398,7 +398,7 @@ bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp) const
} }
if (filepath) { if (filepath) {
std::string settings = GetArg("-settings", BITCOIN_SETTINGS_FILENAME); std::string settings = GetArg("-settings", BITCOIN_SETTINGS_FILENAME);
*filepath = fs::absolute(temp ? settings + ".tmp" : settings, GetDataDir(/* net_specific= */ true)); *filepath = fsbridge::AbsPathJoin(GetDataDir(/* net_specific= */ true), temp ? settings + ".tmp" : settings);
} }
return true; return true;
} }
@ -1311,7 +1311,7 @@ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific)
if (path.is_absolute()) { if (path.is_absolute()) {
return path; return path;
} }
return fs::absolute(path, GetDataDir(net_specific)); return fsbridge::AbsPathJoin(GetDataDir(net_specific), path);
} }
void ScheduleBatchPriority() void ScheduleBatchPriority()

@ -62,7 +62,7 @@ bool VerifyWallets(interfaces::Chain& chain)
std::set<fs::path> wallet_paths; std::set<fs::path> wallet_paths;
for (const auto& wallet_file : gArgs.GetArgs("-wallet")) { for (const auto& wallet_file : gArgs.GetArgs("-wallet")) {
const fs::path path = fs::absolute(wallet_file, GetWalletDir()); const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), wallet_file);
if (!wallet_paths.insert(path).second) { if (!wallet_paths.insert(path).second) {
chain.initWarning(strprintf(_("Ignoring duplicate -wallet %s."), wallet_file)); chain.initWarning(strprintf(_("Ignoring duplicate -wallet %s."), wallet_file));

@ -3780,7 +3780,7 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
// 2. Path to an existing directory. // 2. Path to an existing directory.
// 3. Path to a symlink to a directory. // 3. Path to a symlink to a directory.
// 4. For backwards compatibility, the name of a data file in -walletdir. // 4. For backwards compatibility, the name of a data file in -walletdir.
const fs::path& wallet_path = fs::absolute(name, GetWalletDir()); const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), name);
fs::file_type path_type = fs::symlink_status(wallet_path).type(); fs::file_type path_type = fs::symlink_status(wallet_path).type();
if (!(path_type == fs::file_not_found || path_type == fs::directory_file || if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
(path_type == fs::symlink_file && fs::is_directory(wallet_path)) || (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||

@ -105,7 +105,7 @@ static void WalletShowInfo(CWallet* wallet_instance)
bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command, const std::string& name) bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command, const std::string& name)
{ {
fs::path path = fs::absolute(name, GetWalletDir()); const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), name);
if (args.IsArgSet("-format") && command != "createfromdump") { if (args.IsArgSet("-format") && command != "createfromdump") {
tfm::format(std::cerr, "The -format option can only be used with the \"createfromdump\" command.\n"); tfm::format(std::cerr, "The -format option can only be used with the \"createfromdump\" command.\n");

Loading…
Cancel
Save