Skip to content

Commit 1eef3cc

Browse files
committed
CONT-234_fix-title-test
Prior to this commit, the title_tokens function provided by puppet lint was only able to successfully parse titles in single quotes. Titles in double quotes are of interest to us as they may contain unsafe interpolated variables. This commit adds a modified function for title_tokens called get_title_tokens and checks the result for any interpolated variables. This function returns a hash containing an array of tokens and the resource type. Another test has been added to test resources with an array of titles.
1 parent 077b383 commit 1eef3cc

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

lib/puppet-lint/plugins/check_unsafe_interpolations.rb

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@
22
COMMANDS = Array['command', 'onlyif', 'unless']
33
def check
44
# Gather any exec commands' resources into an array
5-
exec_resources = resource_indexes.map do |resource|
5+
exec_resources = resource_indexes.map { |resource|
66
resource_parameters = resource[:param_tokens].map(&:value)
77
resource if resource[:type].value == 'exec' && !(COMMANDS & resource_parameters).empty?
8+
}.compact
9+
10+
# Get title tokens with modified puppet lint function
11+
title_tokens_list = get_title_tokens
12+
13+
# Iterate over title tokens and raise a warning if any are variables
14+
title_tokens_list[:tokens].each do |token|
15+
if token.type == :VARIABLE
16+
notify_warning(token)
17+
end
818
end
919

1020
# Iterate over each command found in any exec
@@ -58,4 +68,49 @@ def parameterised?(token)
5868
current_token = current_token.next_token
5969
end
6070
end
71+
72+
# This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
73+
# This function adds a check for titles in double quotes where there could be interpolated variables
74+
def get_title_tokens
75+
tokens_array = []
76+
result = {}
77+
tokens.each_index do |token_idx|
78+
if tokens[token_idx].type == :COLON
79+
# Check if title is an array
80+
if tokens[token_idx - 1].type == :RBRACK
81+
array_start_idx = tokens.rindex do |r|
82+
r.type == :LBRACK
83+
end
84+
title_array_tokens = tokens[(array_start_idx + 1)..(token_idx - 2)]
85+
tokens_array.concat(title_array_tokens.select do |token|
86+
{ STRING: true, NAME: true }.include?(token.type)
87+
end)
88+
result = {
89+
tokens: tokens_array,
90+
resource_type: tokens[array_start_idx].prev_code_token.prev_code_token
91+
}
92+
# Check if title is double quotes string
93+
elsif tokens[token_idx - 1].type == :DQPOST
94+
# Find index of the start of the title
95+
title_start_idx = tokens.rindex do |r|
96+
r.type == :DQPRE
97+
end
98+
result = {
99+
# Title is tokens from :DQPRE to the index before :COLON
100+
tokens: tokens[title_start_idx..(token_idx - 1)],
101+
resource_type: tokens[title_start_idx].prev_code_token.prev_code_token
102+
}
103+
# Title is in single quotes
104+
else
105+
next_token = tokens[token_idx].next_code_token
106+
tokens_array.concat(tokens[..token_idx - 1]) unless next_token.type == :LBRACE
107+
result = {
108+
tokens: tokens_array,
109+
resource_type: tokens[token_idx - 1].prev_code_token.prev_code_token
110+
}
111+
end
112+
end
113+
end
114+
result
115+
end
61116
end

spec/puppet-lint/plugins/check_unsafe_interpolations_spec.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,10 @@ class foo {
6161
end
6262

6363
it 'detects one problem' do
64-
pending('not implemented yet')
6564
expect(problems).to have(1).problems
6665
end
6766

6867
it 'creates one warning' do
69-
pending('not implemented yet')
7068
expect(problems).to contain_warning(msg)
7169
end
7270
end
@@ -105,5 +103,22 @@ class foo {
105103
expect(problems).to have(0).problems
106104
end
107105
end
106+
107+
context 'exec that has an array of args in command' do
108+
let(:code) do
109+
<<-PUPPET
110+
class foo {
111+
112+
exec { ["foo", "bar", "baz"]:
113+
command => echo qux,
114+
}
115+
}
116+
PUPPET
117+
end
118+
119+
it 'detects zero problems' do
120+
expect(problems).to have(0).problems
121+
end
122+
end
108123
end
109124
end

0 commit comments

Comments
 (0)