From 83aafd5b3266ea2f6b7ff33d956548085dc63c32 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 30 Aug 2018 13:04:19 +0200 Subject: util: Report parse errors in configuration file Report errors while parsing the configuration file, instead of silently ignoring them. $ src/bitcoind -regtest Error reading configuration file: parse error on line 22: nodebuglogfile, if you intended to specify a negated option, use nodebuglogfile=1 instead $ src/bitcoind -regtest Error reading configuration file: parse error on line 22: sdafsdfafs $ src/bitcoind -regtest Error reading configuration file: parse error on line 24: -nodebuglogfile=1, options in the configuration file must be specified without leading - Github-Pull: #14105 Rebased-From: a66c0f78a941968340f030911765a84219908c4d Tree-SHA512: 2b6be1ab643623e6ef9b53354820147a6c5d2baae3795ffe428fc60d8563ec00a68a379aee4029380f80f892abe23763afb1c75c32b60a13bffe7b82496bf2bb --- src/util.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/util.cpp b/src/util.cpp index 95bc427bb2..a391c5e857 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -820,11 +820,11 @@ static std::string TrimString(const std::string& str, const std::string& pattern return str.substr(front, end - front + 1); } -static std::vector> GetConfigOptions(std::istream& stream) +static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector> &options) { - std::vector> options; std::string str, prefix; std::string::size_type pos; + int linenr = 1; while (std::getline(stream, str)) { if ((pos = str.find('#')) != std::string::npos) { str = str.substr(0, pos); @@ -834,21 +834,34 @@ static std::vector> GetConfigOptions(std::is if (!str.empty()) { if (*str.begin() == '[' && *str.rbegin() == ']') { prefix = str.substr(1, str.size() - 2) + '.'; + } 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); options.emplace_back(name, value); + } else { + error = strprintf("parse error on line %i: %s", linenr, str); + if (str.size() >= 2 && str.substr(0, 2) == "no") { + error += strprintf(", if you intended to specify a negated option, use %s=1 instead", str); + } + return false; } } + ++linenr; } - return options; + return true; } bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys) { LOCK(cs_args); - - for (const std::pair& option : GetConfigOptions(stream)) { + std::vector> options; + if (!GetConfigOptions(stream, error, options)) { + return false; + } + for (const std::pair& option : options) { std::string strKey = std::string("-") + option.first; std::string strValue = option.second; -- cgit v1.2.3