Simplify fs::path by dropping filename() and make_preferred() overloads
What changed, and why it matters
This is a routine code cleanup in Bitcoin Core. It removes helper functions that let custom filesystem path objects be passed directly to C++ file streams, because the project no longer uses them that way and the C++ standard now discourages it. The commit updates a handful of file-opening calls to use the underlying standard path object instead. There is no security bug being fixed here.
No security action required. Treat as normal maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit drops make_preferred() and filename() overloads on the custom fs::path wrapper and updates callers to invoke .std_path() before std::fstream::open(). It also removes an unnecessary explicit fs::path construction in src/bitcoin.cpp. The change is purely a simplification/refactoring to align with C++ standard direction (LWG3430) and remove dead compatibility code.
Changed components
src/util/fs.hsrc/common/settings.cppsrc/rpc/request.cppsrc/wallet/dump.cppsrc/bitcoin.cppsrc/test/settings_tests.cppInspect captured patch +8 / −13
diff --git a/src/bitcoin.cpp b/src/bitcoin.cpp
index c1a5fce3..7e4d243a 100644
--- a/src/bitcoin.cpp
+++ b/src/bitcoin.cpp
@@ -209,7 +209,7 @@ static void ExecCommand(const std::vector<const char*>& args, std::string_view w
// Try to resolve any symlinks and figure out the directory containing the wrapper executable.
std::error_code ec;
- fs::path wrapper_dir{fs::weakly_canonical(wrapper_path, ec)};
+ auto wrapper_dir{fs::weakly_canonical(wrapper_path, ec)};
if (wrapper_dir.empty()) wrapper_dir = wrapper_path; // Restore previous path if weakly_canonical failed.
wrapper_dir = wrapper_dir.parent_path();
@@ -225,7 +225,7 @@ static void ExecCommand(const std::vector<const char*>& args, std::string_view w
// If wrapper is installed in a bin/ directory, look for target executable
// in libexec/
- (wrapper_dir.filename() == "bin" && try_exec(fs::path{wrapper_dir.parent_path()} / "libexec" / arg0.filename())) ||
+ (wrapper_dir.filename() == "bin" && try_exec(wrapper_dir.parent_path() / "libexec" / arg0.filename())) ||
#ifdef WIN32
// Otherwise check the "daemon" subdirectory in a windows install.
(!wrapper_dir.empty() && try_exec(wrapper_dir / "daemon" / arg0.filename())) ||
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 046afca1..fbe531c7 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -78,7 +78,7 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
if (!fs::exists(path)) return true;
std::ifstream file;
- file.open(path);
+ file.open(path.std_path());
if (!file.is_open()) {
errors.emplace_back(strprintf("%s. Please check permissions.", fs::PathToString(path)));
return false;
@@ -133,7 +133,7 @@ bool WriteSettings(const fs::path& path,
out.pushKVEnd(value.first, value.second);
}
std::ofstream file;
- file.open(path);
+ file.open(path.std_path());
if (file.fail()) {
errors.emplace_back(strprintf("Error: Unable to open settings file %s for writing", fs::PathToString(path)));
return false;
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index e07072fd..df28e4ea 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -114,7 +114,7 @@ GenerateAuthCookieResult GenerateAuthCookie(const std::optional<fs::perms>& cook
if (filepath_tmp.empty()) {
return GenerateAuthCookieResult::DISABLED; // -norpccookiefile
}
- file.open(filepath_tmp);
+ file.open(filepath_tmp.std_path());
if (!file.is_open()) {
LogWarning("Unable to open cookie authentication file %s for writing", fs::PathToString(filepath_tmp));
return GenerateAuthCookieResult::ERR;
@@ -153,7 +153,7 @@ bool GetAuthCookie(std::string *cookie_out)
if (filepath.empty()) {
return true; // -norpccookiefile
}
- file.open(filepath);
+ file.open(filepath.std_path());
if (!file.is_open())
return false;
std::getline(file, cookie);
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index 95f38fc0..00a566d7 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -45,7 +45,7 @@ inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, c
inline void WriteText(const fs::path& path, const std::string& text)
{
std::ofstream file;
- file.open(path);
+ file.open(path.std_path());
file << text;
}
diff --git a/src/util/fs.h b/src/util/fs.h
index 8ff30482..22b53a0c 100644
--- a/src/util/fs.h
+++ b/src/util/fs.h
@@ -75,11 +75,6 @@ public:
const std::u8string& utf8_str{std::filesystem::path::u8string()};
return std::string{utf8_str.begin(), utf8_str.end()};
}
-
- // Required for path overloads in <fstream>.
- // See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=96e0367ead5d8dcac3bec2865582e76e2fbab190
- path& make_preferred() { std::filesystem::path::make_preferred(); return *this; }
- path filename() const { return std::filesystem::path::filename(); }
};
static inline path u8path(const std::string& utf8_str)
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 312753dd..c63b95b5 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -37,7 +37,7 @@ bool DumpWallet(const ArgsManager& args, WalletDatabase& db, bilingual_str& erro
return false;
}
std::ofstream dump_file;
- dump_file.open(path);
+ dump_file.open(path.std_path());
if (dump_file.fail()) {
error = strprintf(_("Unable to open %s for writing"), fs::PathToString(path));
return false;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.