From 936fbb2424e7c6a56fddf26223328a2adcfa8153 Mon Sep 17 00:00:00 2001 From: Stephen Shelton Date: Wed, 29 Apr 2020 09:41:07 -0600 Subject: [PATCH] Fix config not falling back to undeclared handler for missing option --- llarp/config/definition.cpp | 21 ++++++++++++++--- test/config/test_llarp_config_definition.cpp | 24 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/llarp/config/definition.cpp b/llarp/config/definition.cpp index 64f713b4f..aae33bb82 100644 --- a/llarp/config/definition.cpp +++ b/llarp/config/definition.cpp @@ -37,12 +37,17 @@ namespace llarp ConfigDefinition& ConfigDefinition::addConfigValue(string_view section, string_view name, string_view value) { + // see if we have an undeclared handler to fall back to in case section or section:name is + // absent + auto undItr = m_undeclaredHandlers.find(std::string(section)); + bool haveUndeclaredHandler = (undItr != m_undeclaredHandlers.end()); + + // get section, falling back to undeclared handler if needed auto secItr = m_definitions.find(std::string(section)); if (secItr == m_definitions.end()) { // fallback to undeclared handler if available - auto undItr = m_undeclaredHandlers.find(std::string(section)); - if (undItr == m_undeclaredHandlers.end()) + if (not haveUndeclaredHandler) throw std::invalid_argument(stringify("no declared section [", section, "]")); else { @@ -53,10 +58,20 @@ namespace llarp } // section was valid, get definition by name + // fall back to undeclared handler if needed auto& sectionDefinitions = secItr->second; auto defItr = sectionDefinitions.find(std::string(name)); if (defItr == sectionDefinitions.end()) - throw std::invalid_argument(stringify("no declared option [", section, "]:", name)); + { + if (not haveUndeclaredHandler) + throw std::invalid_argument(stringify("no declared option [", section, "]:", name)); + else + { + auto& handler = undItr->second; + handler(section, name, value); + return *this; + } + } OptionDefinition_ptr& definition = defItr->second; definition->parseValue(std::string(value)); diff --git a/test/config/test_llarp_config_definition.cpp b/test/config/test_llarp_config_definition.cpp index 5aaae45c3..44792fd64 100644 --- a/test/config/test_llarp_config_definition.cpp +++ b/test/config/test_llarp_config_definition.cpp @@ -363,3 +363,27 @@ TEST_CASE("ConfigDefinition multiple values", "[config]") CHECK(values[1] == 2); CHECK(values[2] == 3); } + +TEST_CASE("ConfigDefinition [bind]iface regression", "[config regression]") +{ + llarp::ConfigDefinition config; + + std::string val1; + std::string undeclaredName; + std::string undeclaredValue; + + config.defineOption( + "bind", "*", false, false, "1090", [&](std::string arg) { val1 = arg; }); + + config.addUndeclaredHandler("bind", [&](string_view, string_view name, string_view value) { + undeclaredName = std::string(name); + undeclaredValue = std::string(value); + }); + + config.addConfigValue("bind", "enp35s0", "1091"); + CHECK_NOTHROW(config.acceptAllOptions()); + + CHECK(val1 == "1090"); + CHECK(undeclaredName == "enp35s0"); + CHECK(undeclaredValue == "1091"); +}