Class: Brakeman::Checks

Inherits:
Object
  • Object
show all
Defined in:
lib/brakeman/checks.rb

Overview

Collects up results from running different checks.

Checks can be added with Check.add(check_class)

All .rb files in checks/ will be loaded.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = { }) ⇒ Checks

No need to use this directly.



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/brakeman/checks.rb', line 58

def initialize options = { }
  if options[:min_confidence]
    @min_confidence = options[:min_confidence]
  else
    @min_confidence = Brakeman.get_defaults[:min_confidence]
  end

  @warnings = []
  @template_warnings = []
  @model_warnings = []
  @controller_warnings = []
  @checks_run = []
end

Instance Attribute Details

#checks_runObject (readonly)

Returns the value of attribute checks_run.



13
14
15
# File 'lib/brakeman/checks.rb', line 13

def checks_run
  @checks_run
end

#controller_warningsObject (readonly)

Returns the value of attribute controller_warnings.



13
14
15
# File 'lib/brakeman/checks.rb', line 13

def controller_warnings
  @controller_warnings
end

#model_warningsObject (readonly)

Returns the value of attribute model_warnings.



13
14
15
# File 'lib/brakeman/checks.rb', line 13

def model_warnings
  @model_warnings
end

#template_warningsObject (readonly)

Returns the value of attribute template_warnings.



13
14
15
# File 'lib/brakeman/checks.rb', line 13

def template_warnings
  @template_warnings
end

#warningsObject (readonly)

Returns the value of attribute warnings.



13
14
15
# File 'lib/brakeman/checks.rb', line 13

def warnings
  @warnings
end

Class Method Details

.actually_run_checks(checks, check_runner, tracker) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/brakeman/checks.rb', line 118

def self.actually_run_checks(checks, check_runner, tracker)
  threads = [] # Results for parallel
  results = [] # Results for sequential
  parallel = tracker.options[:parallel_checks]
  error_mutex = Mutex.new

  checks.each do |c|
    check_name = get_check_name c
    Brakeman.notify " - #{check_name}"

    if parallel
      threads << Thread.new do
        self.run_a_check(c, error_mutex, tracker)
      end
    else
      results << self.run_a_check(c, error_mutex, tracker)
    end

    #Maintain list of which checks were run
    #mainly for reporting purposes
    check_runner.checks_run << check_name[5..-1]
  end

  threads.each { |t| t.join }

  Brakeman.notify "Checks finished, collecting results..."

  if parallel
    threads.each do |thread|
      thread.value.each do |warning|
        check_runner.add_warning warning
      end
    end
  else
    results.each do |warnings|
      warnings.each do |warning|
        check_runner.add_warning warning
      end
    end
  end

  check_runner
end

.add(klass) ⇒ Object

Add a check. This will call klass.new when running tests



16
17
18
# File 'lib/brakeman/checks.rb', line 16

def self.add klass
  @checks << klass unless @checks.include? klass
end

.add_optional(klass) ⇒ Object

Add an optional check



21
22
23
# File 'lib/brakeman/checks.rb', line 21

def self.add_optional klass
  @optional_checks << klass unless @checks.include? klass
end

.checksObject



25
26
27
# File 'lib/brakeman/checks.rb', line 25

def self.checks
  @checks + @optional_checks
end

.initialize_checks(check_directory = "") ⇒ Object



33
34
35
36
37
38
# File 'lib/brakeman/checks.rb', line 33

def self.initialize_checks check_directory = ""
  #Load all files in check_directory
  Dir.glob(File.join(check_directory, "*.rb")).sort.each do |f|
    require f
  end
end

.missing_checks(check_args) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/brakeman/checks.rb', line 40

def self.missing_checks check_args
  check_args = check_args.to_a.map(&:to_s).to_set

  if check_args == Set['CheckNone']
    return []
  else
    loaded = self.checks.map { |name| name.to_s.gsub('Brakeman::', '') }.to_set
    missing = check_args - loaded

    unless missing.empty?
      return missing
    end
  end

  []
end

.optional_checksObject



29
30
31
# File 'lib/brakeman/checks.rb', line 29

def self.optional_checks
  @optional_checks
end

.run_checks(tracker) ⇒ Object

Run all the checks on the given Tracker. Returns a new instance of Checks with the results.



112
113
114
115
116
# File 'lib/brakeman/checks.rb', line 112

def self.run_checks(tracker)
  checks = self.checks_to_run(tracker)
  check_runner = self.new :min_confidence => tracker.options[:min_confidence]
  self.actually_run_checks(checks, check_runner, tracker)
end

Instance Method Details

#add_warning(warning) ⇒ Object

Add Warning to list of warnings to report. Warnings are split into four different arrays for template, controller, model, and generic warnings.

Will not add warnings which are below the minimum confidence level.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/brakeman/checks.rb', line 77

def add_warning warning
  unless warning.confidence > @min_confidence
    case warning.warning_set
    when :template
      @template_warnings << warning
    when :warning
      @warnings << warning
    when :controller
      @controller_warnings << warning
    when :model
      @model_warnings << warning
    else
      raise "Unknown warning: #{warning.warning_set}"
    end
  end
end

#all_warningsObject

Return an array of all warnings found.



106
107
108
# File 'lib/brakeman/checks.rb', line 106

def all_warnings
  @warnings + @template_warnings + @controller_warnings + @model_warnings
end

#diff(other_checks) ⇒ Object

Return a hash of arrays of new and fixed warnings

diff = checks.diff old_checks
diff[:fixed]  # [...]
diff[:new]    # [...]


99
100
101
102
103
# File 'lib/brakeman/checks.rb', line 99

def diff other_checks
  my_warnings = self.all_warnings
  other_warnings = other_checks.all_warnings
  Brakeman::Differ.new(my_warnings, other_warnings).diff
end