diff options
author | Jacob Helwig <jacob@technosorcery.net> | 2018-07-12 14:07:56 -0700 |
---|---|---|
committer | Jacob Helwig <jacob@technosorcery.net> | 2018-07-12 14:07:56 -0700 |
commit | eec1c193d9043622bf27e162dfb8ffb248ae0caa (patch) | |
tree | 0ca0d6631b2b12fc9a26d3c75ffbf4b669c09742 /spec/unit/provider | |
parent | e85283b0f41ae1635954c76b2978e34c260794cd (diff) | |
download | puppet-augeas_core-eec1c193d9043622bf27e162dfb8ffb248ae0caa.tar.gz puppet-augeas_core-eec1c193d9043622bf27e162dfb8ffb248ae0caa.tar.bz2 |
(MODULE-7443) Safely deserialize stringified array
This ports PUP-8974, and the related follow-up maintenance commits from
the Puppet repo.
The augeas provider used Kernel#eval to convert stringified arrays to Ruby
arrays. For example, it extracted the array part of the "clause" below:
onlyif => 'values HostKey == ["/etc/ssh/ssh_host_rsa_key"]'
and called Kernel#eval with '["/etc/ssh/ssh_host_rsa_key"]'. Using eval is
bad because it executes arbitrary code.
This commit changes the provider to convert the comma delimited string to
a Ruby array. This mostly maintains the functionality of the original
Kernel#eval (minus running arbitrary code) except for no longer handling
the \M-x, \M-\C-x, \M-\cx, \c\M-x, \c?, and \C-? escape sequences in
double-quoted strings, and \u{nnnn ...} is more lenient about whitespace.
Diffstat (limited to 'spec/unit/provider')
-rw-r--r-- | spec/unit/provider/augeas/augeas_spec.rb | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/spec/unit/provider/augeas/augeas_spec.rb b/spec/unit/provider/augeas/augeas_spec.rb index 6166140..180f89c 100644 --- a/spec/unit/provider/augeas/augeas_spec.rb +++ b/spec/unit/provider/augeas/augeas_spec.rb @@ -262,6 +262,49 @@ describe Puppet::Type.type(:augeas).provider(:augeas) do command = ['values', 'fake value', "== ['set', 'of', 'values']"] expect(provider.process_values(command)).to eq(true) end + it 'returns true for an array match with double quotes and spaces' do + command = ['values', 'fake value', '== [ "set" , "of" , "values" ] '] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with internally escaped single quotes' do + provider.aug.stubs(:match).returns(['set', "o'values", 'here']) + provider.aug.stubs(:get).returns('set').then.returns("o'values").then.returns('here') + command = ['values', 'fake value', "== [ 'set', 'o\\'values', 'here']"] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with octal character sequences' do + command = ['values', 'fake value', '== ["\\x73et", "of", "values"]'] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with hex character sequences' do + command = ['values', 'fake value', '== ["\\163et", "of", "values"]'] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with short unicode escape sequences' do + command = ['values', 'fake value', '== ["\\u0073et", "of", "values"]'] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with single character long unicode escape sequences' do + command = ['values', 'fake value', '== ["\\u{0073}et", "of", "values"]'] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with multi-character long unicode escape sequences' do + command = ['values', 'fake value', '== ["\\u{0073 0065 0074}", "of", "values"]'] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an array match with literal backslashes' do + provider.aug.stubs(:match).returns(['set', 'o\\values', 'here']) + provider.aug.stubs(:get).returns('set').then.returns('o\\values').then.returns('here') + command = ['values', 'fake value', '== [ "set", "o\\\\values", "here"]'] + expect(provider.process_values(command)).to eq(true) + end it 'returns false for an array non match' do command = ['values', 'fake value', "== ['this', 'should', 'not', 'match']"] @@ -277,6 +320,18 @@ describe Puppet::Type.type(:augeas).provider(:augeas) do command = ['values', 'fake value', "!= ['this', 'should', 'not', 'match']"] expect(provider.process_values(command)).to eq(true) end + + it 'returns true for an array non match with double quotes and spaces' do + command = ['values', 'fake value', '!= [ "this" , "should" ,"not", "match" ] '] + expect(provider.process_values(command)).to eq(true) + end + + it 'returns true for an empty array match' do + provider.aug.stubs(:match).returns([]) + provider.aug.stubs(:get) + command = ['values', 'fake value', '== []'] + expect(provider.process_values(command)).to eq(true) + end end describe 'match filters' do @@ -322,6 +377,11 @@ describe Puppet::Type.type(:augeas).provider(:augeas) do expect(provider.process_match(command)).to eq(true) end + it 'returns true for an array match with double quotes and spaces' do + command = ['match', 'fake value', '== [ "set" , "of" , "values" ] '] + expect(provider.process_match(command)).to eq(true) + end + it 'returns false for an array non match' do command = ['match', 'fake value', "== ['this', 'should', 'not', 'match']"] expect(provider.process_match(command)).to eq(false) @@ -336,6 +396,11 @@ describe Puppet::Type.type(:augeas).provider(:augeas) do command = ['match', 'fake value', "!= ['this', 'should', 'not', 'match']"] expect(provider.process_match(command)).to eq(true) end + + it 'returns true for an array non match with double quotes and spaces' do + command = ['match', 'fake value', '!= [ "this" , "should" ,"not", "match" ] '] + expect(provider.process_match(command)).to eq(true) + end end describe 'need to run' do |