lib/contrast/agent/protect/rule/default_scanner.rb in contrast-agent-6.6.1 vs lib/contrast/agent/protect/rule/default_scanner.rb in contrast-agent-6.6.2

- old
+ new

@@ -18,27 +18,32 @@ # :STATE_INSIDE_STRING_ESCAPE_BLOCK # :STATE_INSIDE_LINE_COMMENT # inside a comment that will continue to the end of the line # :STATE_INSIDE_BLOCK_COMMENT # inside a commend that will end with a closing tag # :STATE_SKIP_NEXT_CHARACTER + # @param query [String] the query being executed + # @param index [Integer] the index of the input in the query + # @param input [String] the input value provided by the user + # @return [Array<Integer>, nil] the boundary overrun by the input or nil if no overrun def crosses_boundary query, index, input last_boundary = 0 - token_boundaries(query).each do |boundary| + scan_token_boundaries(query).each do |boundary| if boundary > index - return last_boundary, boundary if boundary < index + input.length + # We should report the previous and overrun boundary if the input crosses one. + return last_boundary, boundary if boundary < (index + input.length) break end last_boundary = boundary end nil end - def token_boundaries query - @_token_boundaries ||= scan_token_boundaries(query) - end + private + # @param query [String] the query being executed + # @return [Array<Integer>] the boundaries of the query def scan_token_boundaries query boundaries = [] return boundaries unless query && !query.empty? state = :STATE_EXPECTING_TOKEN @@ -71,10 +76,15 @@ index += 1 end boundaries end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param current_state [Symbol] the state of the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def process_state boundaries, current_state, char, index, query case current_state when :STATE_EXPECTING_TOKEN process_expecting_token(boundaries, char, index, query) when :STATE_INSIDE_NUMBER @@ -86,10 +96,14 @@ when :STATE_INSIDE_SINGLEQUOTE process_single_quote(boundaries, char, index, query) end end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def process_expecting_token boundaries, char, index, query if char == Contrast::Utils::ObjectShare::SINGLE_QUOTE boundaries << index :STATE_INSIDE_SINGLEQUOTE elsif char == Contrast::Utils::ObjectShare::DOUBLE_QUOTE @@ -110,10 +124,14 @@ else :STATE_EXPECTING_TOKEN end end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def process_inside_token boundaries, char, index, query if char == Contrast::Utils::ObjectShare::SINGLE_QUOTE boundaries << index :STATE_INSIDE_SINGLEQUOTE elsif char == Contrast::Utils::ObjectShare::DOUBLE_QUOTE @@ -131,19 +149,27 @@ else :STATE_INSIDE_TOKEN end end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param _query [String] the query being executed def process_number boundaries, char, index, _query if char.match?(Contrast::Utils::ObjectShare::DIGIT_REGEXP) || char == Contrast::Utils::ObjectShare::PERIOD :STATE_INSIDE_NUMBER else boundaries << index :STATE_EXPECTING_TOKEN end end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def process_double_quote boundaries, char, index, query if escape_char?(char) :STATE_SKIP_NEXT_CHARACTER elsif escape_sequence_start?(char) :STATE_INSIDE_STRING_ESCAPE_BLOCK @@ -157,10 +183,14 @@ else :STATE_INSIDE_DOUBLEQUOTE end end + # @param boundaries [Array<Integer>] the indexes of the state changes in the query + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def process_single_quote boundaries, char, index, query if escape_char?(char) :STATE_SKIP_NEXT_CHARACTER elsif escape_sequence_start?(char) :STATE_INSIDE_STRING_ESCAPE_BLOCK @@ -174,22 +204,28 @@ else :STATE_INSIDE_SINGLEQUOTE end end + # @param query [String] the query being executed + # @param index [Integer] the location of the character in the query def double_quote? query, index return false unless index >= 0 && index < query.length query[index] == Contrast::Utils::ObjectShare::DOUBLE_QUOTE end + # @param query [String] the query being executed + # @param index [Integer] the location of the character in the query def single_quote? query, index return false unless index >= 0 && index < query.length query[index] == Contrast::Utils::ObjectShare::SINGLE_QUOTE end + # @param query [String] the query being executed + # @param index [Integer] the location of the character in the query def find_escape_sequence_boundary query, index idx = index while idx < query.length char = query[idx] break if escape_sequence_end?(char) @@ -197,10 +233,12 @@ idx += 1 end idx end + # @param query [String] the query being executed + # @param index [Integer] the location of the character in the query def find_block_comment_boundary query, index idx = index while idx < query.length char = query[idx] break if end_block_comment?(char, idx, query) @@ -208,10 +246,12 @@ idx += 1 end idx end + # @param query [String] the query being executed + # @param index [Integer] the location of the character in the query def find_new_line_boundary query, index idx = index while idx < query.length char = query[idx] break if char == Contrast::Utils::ObjectShare::NEW_LINE @@ -220,34 +260,47 @@ idx += 1 end idx end + # @param char [String] the character being evaluated def operator? char char.match?(OPERATOR_PATTERN) end # @note: Any class extending this module should override these methods as needed # Are the current and subsequent characters both '-' ? + # + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def start_line_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::DASH return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::DASH end # Is the current character / sequence of characters the start of a block comment # We assume '/*' starts the comment by default + # + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def start_block_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::SLASH return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::ASTERISK end # Is the current character / sequence of characters the end of a block comment # We assume '*/' ends the comment by default + # + # @param char [String] the character being evaluated + # @param index [Integer] the location of the character in the query + # @param query [String] the query being executed def end_block_comment? char, index, query return false unless char == Contrast::Utils::ObjectShare::ASTERISK return false unless (query.length - 2) >= index query[index + 1] == Contrast::Utils::ObjectShare::SLASH @@ -265,21 +318,27 @@ true end # Is the character provided an escape character? # By default, we'll assume + # + # @param char [String] the character being evaluated def escape_char? char char == Contrast::Utils::ObjectShare::BACK_SLASH end # Is this the start of a string escape sequence? # Since escape sequences aren't supported, the answer is always false + # + # @param _char [String] the character being evaluated def escape_sequence_start? _char false end # Is this the end of a string escape sequence? # Since escape sequences aren't supported, the answer is always false + # + # @param _char [String] the character being evaluated def escape_sequence_end? _char false end end