/
config.rb
160 lines (134 loc) · 3.95 KB
/
config.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
require 'set'
require 'json'
module Brakeman
class IgnoreConfig
attr_reader :shown_warnings, :ignored_warnings
attr_accessor :file
def initialize file, new_warnings
@file = file
@new_warnings = new_warnings
@already_ignored = []
@ignored_fingerprints = Set.new
@used_fingerprints = Set.new
@notes = {}
@shown_warnings = @ignored_warnings = nil
@changed = false
end
# Populate ignored_warnings and shown_warnings based on ignore
# configuration
def filter_ignored
@shown_warnings = []
@ignored_warnings = []
@used_fingerprints = Set.new
@new_warnings.each do |w|
if ignored? w
@ignored_warnings << w
else
@shown_warnings << w
end
end
@shown_warnings
end
# Remove warning from ignored list
def unignore warning
@ignored_fingerprints.delete warning.fingerprint
if @already_ignored.reject! { |w|w[:fingerprint] == warning.fingerprint }
@changed = true
end
end
# Determine if warning should be ignored
def ignored? warning
@used_fingerprints << warning.fingerprint
@ignored_fingerprints.include? warning.fingerprint
end
def ignore warning
@changed = true unless ignored? warning
@ignored_fingerprints << warning.fingerprint
end
# Add note for warning
def add_note warning, note
@changed = true
@notes[warning.fingerprint] = note
end
# Retrieve note for warning if it exists. Returns nil if no
# note is found
def note_for warning
if warning.is_a? Warning
fingerprint = warning.fingerprint
else
fingerprint = warning[:fingerprint]
end
@already_ignored.each do |w|
if fingerprint == w[:fingerprint]
return w[:note]
end
end
nil
end
# The set of unused ignore entries
def obsolete_fingerprints
(@ignored_fingerprints - @used_fingerprints).to_a
end
def prune_obsolete
obsolete = obsolete_fingerprints.to_set
@ignored_fingerprints -= obsolete
@already_ignored.reject! do |w|
if obsolete.include? w[:fingerprint]
@changed = true
end
end
end
def already_ignored_entries_with_empty_notes
@already_ignored.select { |i| i if i[:note].strip.empty? }
end
# Read configuration to file
def read_from_file file = @file
if File.exist? file
begin
@already_ignored = JSON.parse(File.read(file), :symbolize_names => true)[:ignored_warnings]
rescue => e
raise e, "\nError[#{e.class}] while reading brakeman ignore file: #{file}\n"
end
else
Brakeman.notify "[Notice] Could not find ignore configuration in #{file}"
@already_ignored = []
end
@already_ignored.each do |w|
@ignored_fingerprints << w[:fingerprint]
@notes[w[:fingerprint]] = w[:note]
end
end
# Save configuration to file
def save_to_file warnings, file = @file
warnings = warnings.map do |w|
if w.is_a? Warning
w = w.to_hash(absolute_paths: false)
end
w[:note] = @notes[w[:fingerprint]] || ""
w
end.sort_by { |w| [w[:fingerprint], w[:line]] }
output = {
:ignored_warnings => warnings,
:updated => Time.now.to_s,
:brakeman_version => Brakeman::Version
}
File.open file, "w" do |f|
f.puts JSON.pretty_generate(output)
end
end
# Save old ignored warnings and newly ignored ones
def save_with_old
warnings = @ignored_warnings.dup
# Only add ignored warnings not already ignored
@already_ignored.each do |w|
fingerprint = w[:fingerprint]
unless @ignored_warnings.find { |ignored_warning| ignored_warning.fingerprint == fingerprint }
warnings << w
end
end
if @changed
save_to_file warnings
end
end
end
end