mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
refactor: Block unsafe fs::path std::string conversion calls
There is no change in behavior. This just helps prepare for the transition from boost::filesystem to std::filesystem by avoiding calls to methods which will be unsafe after the transaction to std::filesystem to due lack of a boost::filesystem::path::imbue equivalent and inability to set a predictable locale. Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Co-authored-by: Kiminuo <kiminuo@protonmail.com> Co-authored-by: MarcoFalke <falke.marco@gmail.com>
This commit is contained in:
58
src/fs.h
58
src/fs.h
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <tinyformat.h>
|
||||
|
||||
/** Filesystem operations and types */
|
||||
namespace fs {
|
||||
@@ -23,8 +24,8 @@ using namespace boost::filesystem;
|
||||
* Path class wrapper to prepare application code for transition from
|
||||
* boost::filesystem library to std::filesystem implementation. The main
|
||||
* purpose of the class is to define fs::path::u8string() and fs::u8path()
|
||||
* functions not present in boost. In the next git commit, it also blocks calls
|
||||
* to the fs::path(std::string) implicit constructor and the fs::path::string()
|
||||
* functions not present in boost. It also blocks calls to the
|
||||
* fs::path(std::string) implicit constructor and the fs::path::string()
|
||||
* method, which worked well in the boost::filesystem implementation, but have
|
||||
* unsafe and unpredictable behavior on Windows in the std::filesystem
|
||||
* implementation (see implementation note in \ref PathToString for details).
|
||||
@@ -33,7 +34,26 @@ class path : public boost::filesystem::path
|
||||
{
|
||||
public:
|
||||
using boost::filesystem::path::path;
|
||||
|
||||
// Allow path objects arguments for compatibility.
|
||||
path(boost::filesystem::path path) : boost::filesystem::path::path(std::move(path)) {}
|
||||
path& operator=(boost::filesystem::path path) { boost::filesystem::path::operator=(std::move(path)); return *this; }
|
||||
path& operator/=(boost::filesystem::path path) { boost::filesystem::path::operator/=(std::move(path)); return *this; }
|
||||
|
||||
// Allow literal string arguments, which are safe as long as the literals are ASCII.
|
||||
path(const char* c) : boost::filesystem::path(c) {}
|
||||
path& operator=(const char* c) { boost::filesystem::path::operator=(c); return *this; }
|
||||
path& operator/=(const char* c) { boost::filesystem::path::operator/=(c); return *this; }
|
||||
path& append(const char* c) { boost::filesystem::path::append(c); return *this; }
|
||||
|
||||
// Disallow std::string arguments to avoid locale-dependent decoding on windows.
|
||||
path(std::string) = delete;
|
||||
path& operator=(std::string) = delete;
|
||||
path& operator/=(std::string) = delete;
|
||||
path& append(std::string) = delete;
|
||||
|
||||
// Disallow std::string conversion method to avoid locale-dependent encoding on windows.
|
||||
std::string string() const = delete;
|
||||
|
||||
// Define UTF-8 string conversion method not present in boost::filesystem but present in std::filesystem.
|
||||
std::string u8string() const { return boost::filesystem::path::string(); }
|
||||
@@ -45,6 +65,33 @@ static inline path u8path(const std::string& string)
|
||||
return boost::filesystem::path(string);
|
||||
}
|
||||
|
||||
// Disallow implicit std::string conversion for system_complete to avoid
|
||||
// locale-dependent encoding on windows.
|
||||
static inline path system_complete(const path& p)
|
||||
{
|
||||
return boost::filesystem::system_complete(p);
|
||||
}
|
||||
|
||||
// Disallow implicit std::string conversion for exists to avoid
|
||||
// locale-dependent encoding on windows.
|
||||
static inline bool exists(const path& p)
|
||||
{
|
||||
return boost::filesystem::exists(p);
|
||||
}
|
||||
|
||||
// Allow explicit quoted stream I/O.
|
||||
static inline auto quoted(const std::string& s)
|
||||
{
|
||||
return boost::io::quoted(s, '&');
|
||||
}
|
||||
|
||||
// Allow safe path append operations.
|
||||
static inline path operator+(path p1, path p2)
|
||||
{
|
||||
p1 += std::move(p2);
|
||||
return p1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert path object to byte string. On POSIX, paths natively are byte
|
||||
* strings so this is trivial. On Windows, paths natively are Unicode, so an
|
||||
@@ -179,4 +226,11 @@ namespace fsbridge {
|
||||
#endif // WIN32 && __GLIBCXX__
|
||||
};
|
||||
|
||||
// Disallow path operator<< formatting in tinyformat to avoid locale-dependent
|
||||
// encoding on windows.
|
||||
namespace tinyformat {
|
||||
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const boost::filesystem::path&) = delete;
|
||||
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const fs::path&) = delete;
|
||||
} // namespace tinyformat
|
||||
|
||||
#endif // BITCOIN_FS_H
|
||||
|
||||
Reference in New Issue
Block a user