summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc A. Paradise <marc.paradise@gmail.com>2019-11-14 12:16:30 -0500
committerMarc A. Paradise <marc.paradise@gmail.com>2019-11-14 12:21:20 -0500
commit04b56f69bcd80e2440442ea027bf7a3cc69d8155 (patch)
tree6bff2a3a38812f3a234b5c29c3a95aa34c4ecd77
parent895bb8a27c73325aa441e689df9868257ab51bd2 (diff)
downloadmixlib-config-04b56f69bcd80e2440442ea027bf7a3cc69d8155.tar.gz
Do not crash when loading undefined context from hash
When loading `from_hash` and with `strict_mode false`, a config context that is not defined will cause mixlib-config to crash. This is because we used `internal_get` without checking to see if the result was nil. nil occurs when the scenario above is met. Now, we will define the context when this happens, and continue to populate that context from the hash. Signed-off-by: Marc A. Paradise <marc.paradise@gmail.com>
-rw-r--r--lib/mixlib/config.rb5
-rw-r--r--spec/mixlib/config_spec.rb57
2 files changed, 41 insertions, 21 deletions
diff --git a/lib/mixlib/config.rb b/lib/mixlib/config.rb
index 9937182..00385da 100644
--- a/lib/mixlib/config.rb
+++ b/lib/mixlib/config.rb
@@ -569,7 +569,10 @@ module Mixlib
def apply_nested_hash(hash)
hash.each do |k, v|
if v.is_a? Hash
- internal_get(k.to_sym).apply_nested_hash(v)
+ # If loading from hash, and we reference a context that doesn't exist
+ # and warning/strict is off, we need to create the config context that we expected to be here.
+ context = internal_get(k.to_sym) || config_context(k.to_sym)
+ context.apply_nested_hash(v)
else
internal_set(k.to_sym, v)
end
diff --git a/spec/mixlib/config_spec.rb b/spec/mixlib/config_spec.rb
index de4147b..1155e75 100644
--- a/spec/mixlib/config_spec.rb
+++ b/spec/mixlib/config_spec.rb
@@ -1274,28 +1274,45 @@ describe Mixlib::Config do
end
describe ".from_hash" do
- let(:hash) do
- {
- "alpha" => "beta",
- gamma: "delta",
- "foo" => %w{ bar baz matazz},
- "bar" => { "baz" => { "fizz" => "buzz" } },
- "windows_path" => 'C:\Windows Has Awful\Paths',
- }
- end
-
- it "configures the config object from a hash" do
- ConfigIt.config_context :bar do
- config_context :baz do
- default :fizz, "quux"
+ context "when contexts in the hash are defined" do
+ let(:hash) do
+ {
+ "alpha" => "beta",
+ gamma: "delta",
+ "foo" => %w{ bar baz matazz},
+ "bar" => { "baz" => { "fizz" => "buzz" } },
+ "windows_path" => 'C:\Windows Has Awful\Paths',
+ }
+ end
+ it "configures the config object from a hash" do
+ ConfigIt.config_context :bar do
+ config_context :baz do
+ default :fizz, "quux"
+ end
end
+ ConfigIt.from_hash(hash)
+ expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
+ expect(ConfigIt.alpha).to eql("beta")
+ expect(ConfigIt.gamma).to eql("delta")
+ expect(ConfigIt[:bar][:baz][:fizz]).to eql("buzz")
+ expect(ConfigIt.windows_path).to eql('C:\Windows Has Awful\Paths')
+ end
+ end
+ context "when contexts in the hash are undefined and strict disabled" do
+ before do
+ ConfigIt.strict_mode = true
+ end
+ let(:hash) do
+ {
+ "brrr" => { "baz" => { "fizz" => "buzz" } },
+ "windows_path" => 'C:\Windows Has Awful\Paths',
+ }
+ end
+ it "configures the config object, creating contexts as needed" do
+ ConfigIt.from_hash(hash)
+ expect(ConfigIt[:brrr][:baz][:fizz]).to eql("buzz")
+ expect(ConfigIt.windows_path).to eql('C:\Windows Has Awful\Paths')
end
- ConfigIt.from_hash(hash)
- expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
- expect(ConfigIt.alpha).to eql("beta")
- expect(ConfigIt.gamma).to eql("delta")
- expect(ConfigIt[:bar][:baz][:fizz]).to eql("buzz")
- expect(ConfigIt.windows_path).to eql('C:\Windows Has Awful\Paths')
end
end
end