From 76bf8d0b4e7ceeb59be7ff0bc4ba4e92e6443854 Mon Sep 17 00:00:00 2001 From: Gavin Patton Date: Fri, 10 Feb 2023 12:46:25 +0000 Subject: [PATCH] (CONT-551) Fix get_exec_titles bug Prior to this commit, get_exec_titles (which acts as a replacement to puppet-lint's get_titles function) had a bug where, often, the title string of an exec resource was obtained incorrectly. There were multiple examples where the resulting hash of title tokens would contain much more tokens than were actually in the title - i.e. many tokens after the semi colon concluding the title. This resulted in many identical warnings in the output of the lint check for one interpolated variable. The source of this bug was in how the index in the tokens array for the start and end of the title were retrieved. This commit fixes this by removing the use of rindex method which returns the index of the last object in the array. Returning the last object in the array (tokens) is not what should be done here. Instead we want to find the NEXT INSTANCE of objects. The start of the title is next_code_token.next_code_token after an exec and the end of the title is the NEXT INSTANCE in the tokens array of ':'. --- .../plugins/check_unsafe_interpolations.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/puppet-lint/plugins/check_unsafe_interpolations.rb b/lib/puppet-lint/plugins/check_unsafe_interpolations.rb index 89a7899..33838f1 100644 --- a/lib/puppet-lint/plugins/check_unsafe_interpolations.rb +++ b/lib/puppet-lint/plugins/check_unsafe_interpolations.rb @@ -100,8 +100,8 @@ def get_exec_titles # Check if title is double quotes string elsif tokens[token_idx].next_code_token.next_code_token.type == :DQPRE # Find the start and end of the title - title_start_idx = tokens.rindex { |r| r.type == :DQPRE } - title_end_idx = tokens.rindex { |r| r.type == :DQPOST } + title_start_idx = tokens.find_index(tokens[token_idx].next_code_token.next_code_token) + title_end_idx = title_start_idx + index_offset_for(':', tokens[title_start_idx..tokens.length]) result << tokens[title_start_idx..title_end_idx] # Title is in single quotes @@ -117,4 +117,13 @@ def get_exec_titles def interpolated?(token) INTERPOLATED_STRINGS.include?(token.type) end + + # Finds the index offset of the next instance of `value` in `tokens_slice` from the original index + def index_offset_for(value, tokens_slice) + i = 0 + while i < tokens_slice.length + return i if value.include?(tokens_slice[i].value) + i += 1 + end + end end