diff --git a/universal/src/yaml_config/yaml_config.cpp b/universal/src/yaml_config/yaml_config.cpp index 49b19375a31c..69e4660ef953 100644 --- a/universal/src/yaml_config/yaml_config.cpp +++ b/universal/src/yaml_config/yaml_config.cpp @@ -100,7 +100,7 @@ std::optional GetSharpCommandValue( if (env_value) { env_value = env_value->CloneWithReplacedPath(yaml[key].GetPath()); // Strip substitutions off to disallow nested substitutions - return YamlConfig{std::move(*env_value), {}, YamlConfig::Mode::kSecure}; + return YamlConfig{std::move(*env_value), {}, mode}; } const auto file_name = yaml[GetFileName(key)]; @@ -108,7 +108,7 @@ std::optional GetSharpCommandValue( if (file_value) { file_value = file_value->CloneWithReplacedPath(yaml[key].GetPath()); // Strip substitutions off to disallow nested substitutions - return YamlConfig{std::move(*file_value), {}, YamlConfig::Mode::kSecure}; + return YamlConfig{std::move(*file_value), {}, mode}; } if (met_substitution || !env_name.IsMissing() || !file_name.IsMissing()) { @@ -119,7 +119,7 @@ std::optional GetSharpCommandValue( return YamlConfig{ yaml[fallback_name].CloneWithReplacedPath(yaml[key].GetPath()), {}, - YamlConfig::Mode::kSecure + mode }; } } @@ -142,7 +142,7 @@ std::optional GetYamlConfig( if (!var_data.IsMissing()) { var_data = var_data.CloneWithReplacedPath(value.GetPath()); // Strip substitutions off to disallow nested substitutions - return YamlConfig{std::move(var_data), {}, YamlConfig::Mode::kSecure}; + return YamlConfig{std::move(var_data), {}, mode}; } auto res = GetSharpCommandValue( @@ -155,7 +155,7 @@ std::optional GetYamlConfig( return YamlConfig{ res->GetRawYamlWithoutConfigVars().CloneWithReplacedPath(value.GetPath()), {}, - YamlConfig::Mode::kSecure, + mode, }; } } @@ -206,7 +206,7 @@ YamlConfig YamlConfig::operator[](size_t index) const { if (!var_data.IsMissing()) { var_data = var_data.CloneWithReplacedPath(value.GetPath()); // Strip substitutions off to disallow nested substitutions - return YamlConfig{std::move(var_data), {}, Mode::kSecure}; + return YamlConfig{std::move(var_data), {}, mode_}; } auto res = GetSharpCommandValue( @@ -219,7 +219,7 @@ YamlConfig YamlConfig::operator[](size_t index) const { return YamlConfig{ res->GetRawYamlWithoutConfigVars().CloneWithReplacedPath(value.GetPath()), {}, - YamlConfig::Mode::kSecure, + mode_, }; } diff --git a/universal/src/yaml_config/yaml_config_test.cpp b/universal/src/yaml_config/yaml_config_test.cpp index 585126b279a5..834e97296285 100644 --- a/universal/src/yaml_config/yaml_config_test.cpp +++ b/universal/src/yaml_config/yaml_config_test.cpp @@ -432,6 +432,45 @@ TEST(YamlConfig, NoVariableMap) { ); } + +TEST(YamlConfig, NestedVarsEnv) { + auto vmap = formats::yaml::FromString(R"( + root: + value1#env: VALUE_1 + value2: value-2 + nested: + value3#env: VALUE_3 + value4: value-4 + nested: + value5#env: VALUE_5 + value6: value-6 + )"); + + auto node = formats::yaml::FromString(R"( + root: $root + )"); + + yaml_config::YamlConfig conf(std::move(node), std::move(vmap), yaml_config::YamlConfig::Mode::kEnvAllowed); + + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::setenv("VALUE_1", "value-1", 1); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::setenv("VALUE_3", "value-3", 1); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::setenv("VALUE_5", "value-5", 1); + + EXPECT_EQ(conf["root"]["value1"].As(), "value-1"); + EXPECT_EQ(conf["root"]["nested"]["value3"].As(), "value-3"); + EXPECT_EQ(conf["root"]["nested"]["nested"]["value5"].As(), "value-5"); + + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::unsetenv("VALUE_5"); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::unsetenv("VALUE_3"); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + ::unsetenv("VALUE_1"); +} + /// Common test base to make consistent tests between iterators and operator[] template class YamlConfigAccessor : public ::testing::Test {};