From e0e18a1017fa3dc5d6ebeda6ec35c4263327d17c Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Sat, 27 Jul 2019 09:29:50 +0300
Subject: [PATCH] refactoring: Check IsArgKnown() early

---
 src/util/system.cpp | 44 +++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/src/util/system.cpp b/src/util/system.cpp
index c27b0cc10..f3010d06f 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -403,13 +403,6 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
         if (key.length() > 1 && key[1] == '-')
             key.erase(0, 1);
 
-        // Check for -nofoo
-        if (InterpretNegatedOption(key, val)) {
-            m_override_args[key].clear();
-        } else {
-            m_override_args[key].push_back(val);
-        }
-
         // Check that the arg is known
         if (!(IsSwitchChar(key[0]) && key.size() == 1)) {
             if (!IsArgKnown(key)) {
@@ -417,6 +410,13 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
                 return false;
             }
         }
+
+        // Check for -nofoo
+        if (InterpretNegatedOption(key, val)) {
+            m_override_args[key].clear();
+        } else {
+            m_override_args[key].push_back(val);
+        }
     }
 
     // we do not allow -includeconf from command line, so we clear it here
@@ -434,17 +434,23 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin
 
 bool ArgsManager::IsArgKnown(const std::string& key) const
 {
+    assert(key[0] == '-');
+
     size_t option_index = key.find('.');
-    std::string arg_no_net;
     if (option_index == std::string::npos) {
-        arg_no_net = key;
+        option_index = 1;
     } else {
-        arg_no_net = std::string("-") + key.substr(option_index + 1, std::string::npos);
+        ++option_index;
     }
+    if (key.substr(option_index, 2) == "no") {
+        option_index += 2;
+    }
+
+    const std::string base_arg_name = '-' + key.substr(option_index);
 
     LOCK(cs_args);
     for (const auto& arg_map : m_available_args) {
-        if (arg_map.second.count(arg_no_net)) return true;
+        if (arg_map.second.count(base_arg_name)) return true;
     }
     return false;
 }
@@ -840,14 +846,6 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& file
     }
     for (const std::pair<std::string, std::string>& option : options) {
         std::string strKey = std::string("-") + option.first;
-        std::string strValue = option.second;
-
-        if (InterpretNegatedOption(strKey, strValue)) {
-            m_config_args[strKey].clear();
-        } else {
-            m_config_args[strKey].push_back(strValue);
-        }
-
         // Check that the arg is known
         if (!IsArgKnown(strKey)) {
             if (!ignore_invalid_keys) {
@@ -855,8 +853,16 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, const std::string& file
                 return false;
             } else {
                 LogPrintf("Ignoring unknown configuration value %s\n", option.first);
+                continue;
             }
         }
+
+        std::string strValue = option.second;
+        if (InterpretNegatedOption(strKey, strValue)) {
+            m_config_args[strKey].clear();
+        } else {
+            m_config_args[strKey].push_back(strValue);
+        }
     }
     return true;
 }