11PuppetLint . new_check ( :check_unsafe_interpolations ) do
22 COMMANDS = Array [ 'command' , 'onlyif' , 'unless' ]
3+ INTERPOLATED_STRINGS = Array [ :DQPRE , :DQMID ]
34 def check
45 # Gather any exec commands' resources into an array
56 exec_resources = resource_indexes . map { |resource |
67 resource_parameters = resource [ :param_tokens ] . map ( &:value )
78 resource if resource [ :type ] . value == 'exec' && !( COMMANDS & resource_parameters ) . empty?
89 } . compact
910
10- # Get title tokens with modified puppet lint function
11- title_tokens_list = get_title_tokens
11+ # Filter the list of titles returned by get_title_tokens for those contained in an exec
12+ exec_title_tokens = get_title_tokens . select { |title |
13+ title if title [ :resource_type ] . value == 'exec'
14+ } . compact
1215
1316 # 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+ unless exec_title_tokens . empty?
18+ exec_title_tokens . each do | title |
19+ check_unsafe_title ( title )
1720 end
1821 end
1922
@@ -23,11 +26,18 @@ def check
2326 end
2427 end
2528
26- # Iterates over tokens in a command and raises a warning if an interpolated variable is found
29+ # Iterate over the tokens in a title and raise a warning if an interpolated variable is found
30+ def check_unsafe_title ( title )
31+ title [ :tokens ] . each do |token |
32+ notify_warning ( token . next_code_token ) if interpolated? ( token )
33+ end
34+ end
35+
36+ # Iterates over an exec resource and if a command, onlyif or unless paramter is found, it is checked for unsafe interpolations
2737 def check_unsafe_interpolations ( command_resources )
2838 command_resources [ :tokens ] . each do |token |
29- # We are only interested in tokens from command onwards
30- next unless token . type == :NAME
39+ # Skip iteration if token isn't a command of type :NAME
40+ next unless COMMANDS . include? ( token . value ) && token . type == :NAME
3141 # Don't check the command if it is parameterised
3242 next if parameterised? ( token )
3343
@@ -54,9 +64,7 @@ def check_command(token)
5464 # Iterate through tokens in command
5565 while current_token . type != :NEWLINE
5666 # Check if token is a varibale and if it is parameterised
57- if current_token . type == :VARIABLE
58- rule_violations . append ( current_token )
59- end
67+ rule_violations . append ( current_token . next_code_token ) if interpolated? ( current_token )
6068 current_token = current_token . next_token
6169 end
6270
@@ -76,45 +84,48 @@ def parameterised?(token)
7684 # This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
7785 # This function adds a check for titles in double quotes where there could be interpolated variables
7886 def get_title_tokens
79- tokens_array = [ ]
80- result = { }
87+ result = [ ]
8188 tokens . each_index do |token_idx |
82- if tokens [ token_idx ] . type == :COLON
83- # Check if title is an array
84- if tokens [ token_idx - 1 ] . type == :RBRACK
85- array_start_idx = tokens . rindex do |r |
86- r . type == :LBRACK
87- end
88- title_array_tokens = tokens [ ( array_start_idx + 1 ) ..( token_idx - 2 ) ]
89- tokens_array . concat ( title_array_tokens . select do |token |
90- { STRING : true , NAME : true } . include? ( token . type )
91- end )
92- result = {
93- tokens : tokens_array ,
94- resource_type : tokens [ array_start_idx ] . prev_code_token . prev_code_token
95- }
96- # Check if title is double quotes string
97- elsif tokens [ token_idx - 1 ] . type == :DQPOST
98- # Find index of the start of the title
99- title_start_idx = tokens . rindex do |r |
100- r . type == :DQPRE
101- end
102- result = {
103- # Title is tokens from :DQPRE to the index before :COLON
104- tokens : tokens [ title_start_idx ..( token_idx - 1 ) ] ,
105- resource_type : tokens [ title_start_idx ] . prev_code_token . prev_code_token
106- }
107- # Title is in single quotes
108- else
109- next_token = tokens [ token_idx ] . next_code_token
110- tokens_array . concat ( tokens [ ..token_idx - 1 ] ) unless next_token . type == :LBRACE
111- result = {
112- tokens : tokens_array ,
113- resource_type : tokens [ token_idx - 1 ] . prev_code_token . prev_code_token
114- }
89+ next unless tokens [ token_idx ] . type == :COLON
90+ tokens_array = [ ]
91+ # Check if title is an array
92+ if tokens [ token_idx - 1 ] . type == :RBRACK
93+ array_start_idx = tokens . rindex do |r |
94+ r . type == :LBRACK
95+ end
96+ title_array_tokens = tokens [ ( array_start_idx + 1 ) ..( token_idx - 2 ) ]
97+ tokens_array . concat ( title_array_tokens . select do |token |
98+ { STRING : true , NAME : true } . include? ( token . type )
99+ end )
100+ result << {
101+ tokens : tokens_array ,
102+ resource_type : tokens [ array_start_idx ] . prev_code_token . prev_code_token
103+ }
104+ # Check if title is double quotes string
105+ elsif tokens [ token_idx - 1 ] . type == :DQPOST
106+ # Find index of the start of the title
107+ title_start_idx = tokens . rindex do |r |
108+ r . type == :DQPRE
115109 end
110+ result << {
111+ # Title is tokens from :DQPRE to the index before :COLON
112+ tokens : tokens [ title_start_idx ..( token_idx - 1 ) ] ,
113+ resource_type : tokens [ title_start_idx ] . prev_code_token . prev_code_token
114+ }
115+ # Title is in single quotes
116+ else
117+ next_token = tokens [ token_idx ] . next_code_token
118+ tokens_array . concat ( [ tokens [ token_idx - 1 ] ] ) unless next_token . type == :LBRACE
119+ result << {
120+ tokens : tokens_array ,
121+ resource_type : tokens [ token_idx - 1 ] . prev_code_token . prev_code_token
122+ }
116123 end
117124 end
118125 result
119126 end
127+
128+ def interpolated? ( token )
129+ INTERPOLATED_STRINGS . include? ( token . type )
130+ end
120131end
0 commit comments