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