@@ -22,10 +22,10 @@ def check
22
22
end
23
23
end
24
24
25
- # Iterate over the tokens in a title and raise a warning if an interpolated variable is found
25
+ # Iterate over the tokens in a title and raise a warning if an unsafe interpolated variable is found
26
26
def check_unsafe_title ( title )
27
27
title . each do |token |
28
- notify_warning ( token . next_code_token ) if interpolated ?( token )
28
+ notify_warning ( token . next_code_token ) if unsafe_interpolated ?( token )
29
29
end
30
30
end
31
31
@@ -60,7 +60,7 @@ def check_command(token)
60
60
# Iterate through tokens in command
61
61
while current_token . type != :NEWLINE
62
62
# Check if token is a varibale and if it is parameterised
63
- rule_violations . append ( current_token . next_code_token ) if interpolated ?( current_token )
63
+ rule_violations . append ( current_token . next_code_token ) if unsafe_interpolated ?( current_token )
64
64
current_token = current_token . next_token
65
65
end
66
66
@@ -78,7 +78,7 @@ def parameterised?(token)
78
78
end
79
79
80
80
# This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
81
- # This function adds a check for titles in double quotes where there could be interpolated variables
81
+ # This function adds a check for titles in double quotes where there could be unsafe interpolated variables
82
82
def get_exec_titles
83
83
result = [ ]
84
84
tokens . each_index do |token_idx |
@@ -114,8 +114,52 @@ def get_exec_titles
114
114
result
115
115
end
116
116
117
- def interpolated? ( token )
118
- INTERPOLATED_STRINGS . include? ( token . type )
117
+ def find_closing_brack ( token )
118
+ while ( token = token . next_code_token )
119
+ case token . type
120
+ when :RBRACK
121
+ return token
122
+ when :LBRACK
123
+ token = find_closing_brack ( token )
124
+ end
125
+ end
126
+ raise 'not reached'
127
+ end
128
+
129
+ def find_closing_paren ( token )
130
+ while ( token = token . next_code_token )
131
+ case token . type
132
+ when :RPAREN
133
+ return token
134
+ when :LPAREN
135
+ token = find_closing_paren ( token )
136
+ end
137
+ end
138
+ raise 'not reached'
139
+ end
140
+
141
+ def unsafe_interpolated? ( token )
142
+ # XXX: Since stdlib 9.0.0 'shell_escape' is deprecated in favor or 'stdlib::shell_escape'
143
+ # When the shell_escape function is removed from stdlib, we want to remove it bellow.
144
+ return false unless INTERPOLATED_STRINGS . include? ( token . type )
145
+
146
+ token = token . next_code_token
147
+
148
+ if token . type == :FUNCTION_NAME && [ 'shell_escape' , 'stdlib::shell_escape' ] . include? ( token . value )
149
+ token = token . next_code_token
150
+ token = find_closing_paren ( token ) . next_code_token if token . type == :LPAREN
151
+ return ![ :DQPOST , :DQMID ] . include? ( token . type )
152
+ elsif token . type == :VARIABLE
153
+ token = token . next_code_token
154
+ token = find_closing_brack ( token ) . next_code_token if token . type == :LBRACK
155
+ if token . type == :DOT && [ :NAME , :FUNCTION_NAME ] . include? ( token . next_code_token . type ) && [ 'shell_escape' , 'stdlib::shell_escape' ] . include? ( token . next_code_token . value )
156
+ token = token . next_code_token . next_code_token
157
+ token = find_closing_paren ( token ) . next_code_token if token . type == :LPAREN
158
+ return ![ :DQPOST , :DQMID ] . include? ( token . type )
159
+ end
160
+ end
161
+
162
+ true
119
163
end
120
164
121
165
# Finds the index offset of the next instance of `value` in `tokens_slice` from the original index
0 commit comments