Skip to content

Commit

Permalink
Warn unrecognized sections in the config file
Browse files Browse the repository at this point in the history
In the config file, sections are specified by square bracket pair "[]"$,
or included in the option name itself which separated by a period"(.)".

Typicaly, [testnet] is not a correct section name and specified options
in that section are ignored but user cannot recognize what is happen.

So, add some log/stderr-warning messages if unrecognized section names
are present in the config file after checking section only args.
  • Loading branch information
AkioNak committed Nov 20, 2018
1 parent 1b99d15 commit 3fb09b9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 9 deletions.
10 changes: 9 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,15 @@ void InitParameterInteraction()
// Warn if network-specific options (-addnode, -connect, etc) are
// specified in default section of config file, but not overridden
// on the command line or in this network's section of the config file.
gArgs.WarnForSectionOnlyArgs();
std::string network = gArgs.GetChainName();
for (const auto& arg : gArgs.GetUnsuitableSectionOnlyArgs()) {
InitWarning(strprintf(_("Config setting for %s only applied on %s network when in [%s] section."), arg, network, network));
}

// Warn if unrecognized section name are present in the config file.
for (const auto& section : gArgs.GetUnrecognizedSections()) {
InitWarning(strprintf(_("Section [%s] is not recognized."), section));
}
}

static std::string ResolveErrMsg(const char * const optname, const std::string& strBind)
Expand Down
42 changes: 35 additions & 7 deletions src/util/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,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;
Expand All @@ -397,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)
Expand Down Expand Up @@ -819,7 +841,7 @@ 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;
Expand All @@ -834,7 +856,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
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;
Expand All @@ -846,6 +870,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
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") {
Expand All @@ -863,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) {
Expand Down
8 changes: 7 additions & 1 deletion src/util/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class ArgsManager
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);

Expand All @@ -169,7 +170,12 @@ class ArgsManager
* 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
Expand Down
5 changes: 5 additions & 0 deletions test/functional/feature_config_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ def test_config_file_parser(self):
conf.write('server=1\nrpcuser=someuser\nrpcpassword=some#pass')
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')

with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('testnot.datadir=1\n[testnet]\n')
self.restart_node(0)
self.nodes[0].stop_node(expected_stderr='Warning: Section [testnet] is not recognized.' + os.linesep + 'Warning: Section [testnot] is not recognized.')

with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('') # clear

Expand Down

0 comments on commit 3fb09b9

Please sign in to comment.