diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/moneystr.h | 11 | ||||
-rw-r--r-- | src/util/strencodings.cpp | 2 | ||||
-rw-r--r-- | src/util/strencodings.h | 18 | ||||
-rw-r--r-- | src/util/system.cpp | 49 | ||||
-rw-r--r-- | src/util/system.h | 15 |
5 files changed, 69 insertions, 26 deletions
diff --git a/src/util/moneystr.h b/src/util/moneystr.h index 9133f46d5d..b8e2812a96 100644 --- a/src/util/moneystr.h +++ b/src/util/moneystr.h @@ -9,16 +9,17 @@ #ifndef BITCOIN_UTIL_MONEYSTR_H #define BITCOIN_UTIL_MONEYSTR_H -#include <stdint.h> -#include <string> - #include <amount.h> +#include <attributes.h> + +#include <cstdint> +#include <string> /* Do not use these functions to represent or parse monetary amounts to or from * JSON but use AmountFromValue and ValueFromAmount for that. */ std::string FormatMoney(const CAmount& n); -bool ParseMoney(const std::string& str, CAmount& nRet); -bool ParseMoney(const char* pszIn, CAmount& nRet); +NODISCARD bool ParseMoney(const std::string& str, CAmount& nRet); +NODISCARD bool ParseMoney(const char* pszIn, CAmount& nRet); #endif // BITCOIN_UTIL_MONEYSTR_H diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 2a2df43337..46146be66f 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -263,7 +263,7 @@ std::string DecodeBase32(const std::string& str) return std::string((const char*)vchRet.data(), vchRet.size()); } -static bool ParsePrechecks(const std::string& str) +NODISCARD static bool ParsePrechecks(const std::string& str) { if (str.empty()) // No empty string allowed return false; diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 87ccf40a1b..7d16d7dcfd 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -9,7 +9,9 @@ #ifndef BITCOIN_UTIL_STRENCODINGS_H #define BITCOIN_UTIL_STRENCODINGS_H -#include <stdint.h> +#include <attributes.h> + +#include <cstdint> #include <string> #include <vector> @@ -92,35 +94,35 @@ constexpr inline bool IsSpace(char c) noexcept { * @returns true if the entire string could be parsed as valid integer, * false if not the entire string could be parsed or when overflow or underflow occurred. */ -bool ParseInt32(const std::string& str, int32_t *out); +NODISCARD bool ParseInt32(const std::string& str, int32_t *out); /** * Convert string to signed 64-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, * false if not the entire string could be parsed or when overflow or underflow occurred. */ -bool ParseInt64(const std::string& str, int64_t *out); +NODISCARD bool ParseInt64(const std::string& str, int64_t *out); /** * Convert decimal string to unsigned 32-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, * false if not the entire string could be parsed or when overflow or underflow occurred. */ -bool ParseUInt32(const std::string& str, uint32_t *out); +NODISCARD bool ParseUInt32(const std::string& str, uint32_t *out); /** * Convert decimal string to unsigned 64-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, * false if not the entire string could be parsed or when overflow or underflow occurred. */ -bool ParseUInt64(const std::string& str, uint64_t *out); +NODISCARD bool ParseUInt64(const std::string& str, uint64_t *out); /** * Convert string to double with strict parse error feedback. * @returns true if the entire string could be parsed as valid double, * false if not the entire string could be parsed or when overflow or underflow occurred. */ -bool ParseDouble(const std::string& str, double *out); +NODISCARD bool ParseDouble(const std::string& str, double *out); template<typename T> std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) @@ -173,7 +175,7 @@ bool TimingResistantEqual(const T& a, const T& b) * @returns true on success, false on error. * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger. */ -bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out); +NODISCARD bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out); /** Convert from one power-of-2 number base to another. */ template<int frombits, int tobits, bool pad, typename O, typename I> @@ -200,7 +202,7 @@ bool ConvertBits(const O& outfn, I it, I end) { } /** Parse an HD keypaths like "m/7/0'/2000". */ -bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath); +NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath); /** * Converts the given character to its lowercase equivalent. diff --git a/src/util/system.cpp b/src/util/system.cpp index 633b616dc3..a4bf126900 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -73,7 +73,6 @@ #include <malloc.h> #endif -#include <boost/thread.hpp> #include <openssl/crypto.h> #include <openssl/rand.h> #include <openssl/conf.h> @@ -372,15 +371,17 @@ ArgsManager::ArgsManager() : // nothing to do } -void ArgsManager::WarnForSectionOnlyArgs() +const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const { + std::set<std::string> unsuitables; + LOCK(cs_args); // if there's no section selected, don't worry - if (m_network.empty()) return; + if (m_network.empty()) return std::set<std::string> {}; // if it's okay to use the default section for this network, don't worry - if (m_network == CBaseChainParams::MAIN) return; + if (m_network == CBaseChainParams::MAIN) return std::set<std::string> {}; for (const auto& arg : m_network_only_args) { std::pair<bool, std::string> found_result; @@ -398,8 +399,28 @@ void ArgsManager::WarnForSectionOnlyArgs() if (!found_result.first) continue; // otherwise, issue a warning - LogPrintf("Warning: Config setting for %s only applied on %s network when in [%s] section.\n", arg, m_network, m_network); + unsuitables.insert(arg); } + return unsuitables; +} + + +const std::set<std::string> ArgsManager::GetUnrecognizedSections() const +{ + // Section names to be recognized in the config file. + static const std::set<std::string> available_sections{ + CBaseChainParams::REGTEST, + CBaseChainParams::TESTNET, + CBaseChainParams::MAIN + }; + std::set<std::string> diff; + + LOCK(cs_args); + std::set_difference( + m_config_sections.begin(), m_config_sections.end(), + available_sections.begin(), available_sections.end(), + std::inserter(diff, diff.end())); + return diff; } void ArgsManager::SelectConfigNetwork(const std::string& network) @@ -820,27 +841,38 @@ static std::string TrimString(const std::string& str, const std::string& pattern return str.substr(front, end - front + 1); } -static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>> &options) +static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::set<std::string>& sections) { std::string str, prefix; std::string::size_type pos; int linenr = 1; while (std::getline(stream, str)) { + bool used_hash = false; if ((pos = str.find('#')) != std::string::npos) { str = str.substr(0, pos); + used_hash = true; } const static std::string pattern = " \t\r\n"; str = TrimString(str, pattern); if (!str.empty()) { if (*str.begin() == '[' && *str.rbegin() == ']') { - prefix = str.substr(1, str.size() - 2) + '.'; + const std::string section = str.substr(1, str.size() - 2); + sections.insert(section); + prefix = section + '.'; } else if (*str.begin() == '-') { error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str); return false; } else if ((pos = str.find('=')) != std::string::npos) { std::string name = prefix + TrimString(str.substr(0, pos), pattern); std::string value = TrimString(str.substr(pos + 1), pattern); + if (used_hash && name.find("rpcpassword") != std::string::npos) { + error = strprintf("parse error on line %i, using # in rpcpassword can be ambiguous and should be avoided", linenr); + return false; + } options.emplace_back(name, value); + if ((pos = name.rfind('.')) != std::string::npos) { + sections.insert(name.substr(0, pos)); + } } else { error = strprintf("parse error on line %i: %s", linenr, str); if (str.size() >= 2 && str.substr(0, 2) == "no") { @@ -858,7 +890,8 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, boo { LOCK(cs_args); std::vector<std::pair<std::string, std::string>> options; - if (!GetConfigOptions(stream, error, options)) { + m_config_sections.clear(); + if (!GetConfigOptions(stream, error, options, m_config_sections)) { return false; } for (const std::pair<std::string, std::string>& option : options) { diff --git a/src/util/system.h b/src/util/system.h index 5634b8dd61..dca32cc6fc 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -14,6 +14,7 @@ #include <config/bitcoin-config.h> #endif +#include <attributes.h> #include <compat.h> #include <fs.h> #include <logging.h> @@ -148,8 +149,9 @@ protected: std::string m_network GUARDED_BY(cs_args); std::set<std::string> m_network_only_args GUARDED_BY(cs_args); std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args); + std::set<std::string> m_config_sections GUARDED_BY(cs_args); - bool ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys = false); + NODISCARD bool ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys = false); public: ArgsManager(); @@ -159,8 +161,8 @@ public: */ void SelectConfigNetwork(const std::string& network); - bool ParseParameters(int argc, const char* const argv[], std::string& error); - bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false); + NODISCARD bool ParseParameters(int argc, const char* const argv[], std::string& error); + NODISCARD bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false); /** * Log warnings for options in m_section_only_args when @@ -168,7 +170,12 @@ public: * on the command line or in a network-specific section in the * config file. */ - void WarnForSectionOnlyArgs(); + const std::set<std::string> GetUnsuitableSectionOnlyArgs() const; + + /** + * Log warnings for unrecognized section names in the config file. + */ + const std::set<std::string> GetUnrecognizedSections() const; /** * Return a vector of strings of the given argument |