module Pluginscan # Responsible for checking a string against set of rexgexps and returning all matches class Check attr_reader :name, :message, :patterns, :ignores def initialize(check_hash) @name = check_hash[:name] @message = check_hash[:message] @patterns = Array(check_hash[:patterns]) @ignores = Array(check_hash[:ignores]).map do |ignore_thing| IgnoreThing.new(ignore_thing) end end def run(content) pattern_matches(content).map{ |matchdata| match(matchdata) } end def ignore?(_match, content) # `match` is not used in the default case, but is included # so that classes inheriting from this one can use it when deciding # whether or not to ignore content by overriding this function ignores.any? { |ignore_thing| ignore_thing.ignore?(content) } end private def pattern_matches(content) @patterns.map { |pattern| content.match(pattern) }.compact end IgnoreThing = Struct.new(:ignore_thing) do def ignore?(content) case ignore_thing when Regexp content.match(ignore_thing) when Proc ignore_thing.call(content) end end end def match(matchdata) # Select the string we were interested in from the matchdata matchdata.to_a.last # This will return what we want assuming that we have either: # a single item from a simple regex: # #.to_a # => ["$_POST"] # a whole match and a specific match, from a function_list item: # #.to_a # => ["@unlink(", "unlink"] end end end