Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix to dup default values to make it safe if plugins modify provided values #827

Merged
merged 1 commit into from
Mar 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/fluent/config/section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def self.generate(proxy, conf, logger, plugin_class, stack = [])

proxy.defaults.each_pair do |name, defval|
varname = name.to_sym
section_params[varname] = defval
section_params[varname] = (defval.dup rescue defval)
end

if proxy.argument
Expand Down
37 changes: 37 additions & 0 deletions test/config/test_configurable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ class Example5
config_param :secret_param2, :string, secret: true
end
end

class Example6
include Fluent::Configurable
config_param :obj1, :hash, default: {}
config_param :obj2, :array, default: []
end
end

module Fluent::Config
Expand Down Expand Up @@ -251,6 +257,37 @@ def e(attrs)
assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt2" => "fooooooo"})) }
assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt3" => "c"})) }
end

sub_test_case 'default values should be duplicated before touched in plugin code' do
test 'default object should be dupped for cases configured twice' do
x6a = ConfigurableSpec::Example6.new
assert_nothing_raised { x6a.configure(e({})) }
assert_equal({}, x6a.obj1)
assert_equal([], x6a.obj2)

x6b = ConfigurableSpec::Example6.new
assert_nothing_raised { x6b.configure(e({})) }
assert_equal({}, x6b.obj1)
assert_equal([], x6b.obj2)

assert { x6a.obj1.object_id != x6b.obj1.object_id }
assert { x6a.obj2.object_id != x6b.obj2.object_id }

x6c = ConfigurableSpec::Example6.new
assert_nothing_raised { x6c.configure(e({})) }
assert_equal({}, x6c.obj1)
assert_equal([], x6c.obj2)

x6c.obj1['k'] = 'v'
x6c.obj2 << 'v'

assert_equal({'k' => 'v'}, x6c.obj1)
assert_equal(['v'], x6c.obj2)

assert_equal({}, x6a.obj1)
assert_equal([], x6a.obj2)
end
end
end
end

Expand Down
6 changes: 6 additions & 0 deletions test/config/test_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ class TestConfigTypes < ::Test::Unit::TestCase

test 'array' do
assert_equal(["1","2",1], Config::ARRAY_TYPE.call('["1","2",1]', {}))

array_options = {
default: [],
}
assert_equal(["1","2"], Config::ARRAY_TYPE.call('["1","2"]', array_options))
assert_equal(["3"], Config::ARRAY_TYPE.call('["3"]', array_options))
end
end
end