fuzzr 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fuzzr might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.rdoc +28 -0
- data/bin/fuzz +11 -0
- data/fuzzers/check_ace_error.excludes +5 -0
- data/fuzzers/check_ace_error.rb +37 -0
- data/fuzzers/check_catch_ex_as_const.rb +41 -0
- data/fuzzers/check_cout_cerr.excludes +5 -0
- data/fuzzers/check_cout_cerr.rb +37 -0
- data/fuzzers/check_executablebit.rb +37 -0
- data/fuzzers/check_exit_keyword.excludes +2 -0
- data/fuzzers/check_exit_keyword.rb +37 -0
- data/fuzzers/check_fileheader.excludes +5 -0
- data/fuzzers/check_fileheader.rb +92 -0
- data/fuzzers/check_filename.excludes +8 -0
- data/fuzzers/check_filename.rb +33 -0
- data/fuzzers/check_id_tag.excludes +3 -0
- data/fuzzers/check_id_tag.rb +34 -0
- data/fuzzers/check_new_delete.excludes +6 -0
- data/fuzzers/check_new_delete.rb +37 -0
- data/fuzzers/check_printf_keyword.excludes +2 -0
- data/fuzzers/check_printf_keyword.rb +37 -0
- data/fuzzers/check_taox11_namespace.excludes +5 -0
- data/fuzzers/check_taox11_namespace.rb +38 -0
- data/lib/fuzz/console.rb +52 -0
- data/lib/fuzz/fuzz.rb +402 -0
- data/lib/fuzz/fuzzers/check_whitespace.rb +62 -0
- data/lib/fuzz/fzzr.rb +258 -0
- data/lib/fuzz/log.rb +97 -0
- data/lib/fuzz/options.rb +208 -0
- data/lib/fuzz/screen.rb +85 -0
- data/lib/fuzz/system.rb +57 -0
- data/lib/fuzz/version.rb +17 -0
- metadata +81 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# -------------------------------------------------------------------
|
3
|
+
# check_whitespace.rb - TAOX11 whitespace checker
|
4
|
+
#
|
5
|
+
# Author: Martin Corino
|
6
|
+
#
|
7
|
+
# Copyright (c) Remedy IT Expertise BV
|
8
|
+
# -------------------------------------------------------------------
|
9
|
+
|
10
|
+
module Fuzzers
|
11
|
+
class WhitespaceChecker
|
12
|
+
include Fuzz::Fzzr
|
13
|
+
def initialize
|
14
|
+
@fuzz_id = :check_whitespace
|
15
|
+
@description = 'checks for trailing whitespace, incorrect line endings and tabs'
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup(optparser)
|
19
|
+
optparser.on('--wsc:tab-spacing=NUM', Integer,
|
20
|
+
'Fuzzers::WhitespaceChecker - defines tab spacing to use for TAB replacement when --apply-fix is enabled.',
|
21
|
+
"Default: #{tab_spacing}") {|v| self.options[:tabspacing] = v }
|
22
|
+
end
|
23
|
+
|
24
|
+
def applies_to?(object)
|
25
|
+
Fuzz::FileObject === object && !is_excluded?(object)
|
26
|
+
end
|
27
|
+
|
28
|
+
def run(object, apply_fix)
|
29
|
+
_tws = []
|
30
|
+
_tabs = []
|
31
|
+
object.iterate(fuzz_id) do |lnptr|
|
32
|
+
if lnptr.text =~ /(\s\n|[\ \t\f\r\x0B])\Z/
|
33
|
+
if apply_fix
|
34
|
+
Fuzz.log_verbose(%Q{#{object.path}:#{lnptr.line_nr} - stripping trailing whitespace})
|
35
|
+
lnptr.text.rstrip!
|
36
|
+
lnptr.text << "\n" if $1.end_with?("\n")
|
37
|
+
else
|
38
|
+
_tws << lnptr.line_nr
|
39
|
+
end
|
40
|
+
end
|
41
|
+
if lnptr.text =~ /\t/
|
42
|
+
if apply_fix
|
43
|
+
Fuzz.log_warning(%Q{#{object.path}:#{lnptr.line_nr} - replacing tabs})
|
44
|
+
lnptr.text.gsub!(/\t/, ' ' * tab_spacing)
|
45
|
+
else
|
46
|
+
_tabs << lnptr.line_nr
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
Fuzz.log_error(%Q{#{object.path}:[#{_tws.join(',')}] trailing whitespace or incorrect line ending detected}) unless _tws.empty?
|
51
|
+
Fuzz.log_error(%Q{#{object.path}:[#{_tabs.join(',')}] tab(s) detected}) unless _tabs.empty?
|
52
|
+
return (_tws.empty? && _tabs.empty?)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def tab_spacing
|
57
|
+
self.options[:tabspacing] || 2
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Fuzz.register_fzzr(WhitespaceChecker.new)
|
62
|
+
end
|
data/lib/fuzz/fzzr.rb
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# -------------------------------------------------------------------
|
3
|
+
# fuzzr.rb - TAOX11 Fuzzer bases
|
4
|
+
#
|
5
|
+
# Author: Martin Corino
|
6
|
+
#
|
7
|
+
# Copyright (c) Remedy IT Expertise BV
|
8
|
+
# -------------------------------------------------------------------
|
9
|
+
|
10
|
+
module Fuzz
|
11
|
+
##
|
12
|
+
# Fuzzers are objects having the following readonly attributes:
|
13
|
+
# #fuzz_id : id of fuzzer (Symbol)
|
14
|
+
# #description: (String)
|
15
|
+
# #errormsg : (String)
|
16
|
+
#
|
17
|
+
# and having the following methods:
|
18
|
+
# #applies_to?(object) : checks if the test applies to the object passed
|
19
|
+
# (Fuzz::DirObject or Fuzz::FileObject)
|
20
|
+
# #run(object,apply_fix): runs the fzzr test on the object passed
|
21
|
+
# (Fuzz::DirObject or Fuzz::FileObject)
|
22
|
+
# when apply_fix == true Fuzzer is directed to
|
23
|
+
# attempt to fix any problems found (future)
|
24
|
+
#
|
25
|
+
# Fuzz::Fzzr is provided as a convenience Mixin for fuzzers
|
26
|
+
#
|
27
|
+
# Fuzzers can inspect the options passed to fuzz.rb by referencing Fuzz::OPTIONS
|
28
|
+
##
|
29
|
+
|
30
|
+
module Fzzr
|
31
|
+
attr_reader :fuzz_id, :description, :errormsg
|
32
|
+
|
33
|
+
def applies_to?(object)
|
34
|
+
!is_excluded?(object)
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup(optparser)
|
38
|
+
end
|
39
|
+
|
40
|
+
def run(object, apply_fix)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_excluded?(object)
|
45
|
+
# force excludes to be parsed
|
46
|
+
_excludes
|
47
|
+
# now examine
|
48
|
+
((!_is_included?(object)) || _excludes.any? { |excl| (object.fullpath =~ /#{excl}/) })
|
49
|
+
end
|
50
|
+
|
51
|
+
def options
|
52
|
+
Fuzz::OPTIONS[:config][:fzzr_opts][self.fuzz_id] ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def _is_included?(object)
|
58
|
+
Fuzz::DirObject === object || _includes.empty? || _includes.any? { |incl| (object.fullpath =~ /#{incl}/) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def _includes
|
62
|
+
@_includes ||= Fuzz.includes.dup
|
63
|
+
end
|
64
|
+
|
65
|
+
def _excludes
|
66
|
+
unless @_excludes
|
67
|
+
@_excludes = []
|
68
|
+
@_excludes.concat(Fuzz.excludes)
|
69
|
+
Fuzz::OPTIONS[:config][:fzzr_paths].each do |fzzrpath|
|
70
|
+
fzzr_excl_file = File.join(fzzrpath, "#{self.fuzz_id}.excludes")
|
71
|
+
if File.readable?(fzzr_excl_file)
|
72
|
+
lns = IO.readlines(fzzr_excl_file).collect { |l| l.strip }
|
73
|
+
@_excludes.concat(lns.select {|l| !(l.empty? || l[0] == '!') })
|
74
|
+
_includes.concat(lns.select {|l| !(l.empty? || l[0] != '!') }.collect {|l| l[1,l.size].strip })
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
@_excludes
|
81
|
+
end
|
82
|
+
end # Fzzr
|
83
|
+
|
84
|
+
class DirObject
|
85
|
+
attr_reader :path, :fullpath, :name, :ext
|
86
|
+
def initialize(path)
|
87
|
+
@path = path
|
88
|
+
@fullpath = File.expand_path(path)
|
89
|
+
@name = File.basename(path)
|
90
|
+
@ext = File.extname(path).sub(/^\./,'')
|
91
|
+
end
|
92
|
+
|
93
|
+
def changed?
|
94
|
+
false
|
95
|
+
end
|
96
|
+
|
97
|
+
def iterate(fzzr_id, &block)
|
98
|
+
# nothing to iterate over
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_s
|
103
|
+
"Dir:#{path}"
|
104
|
+
end
|
105
|
+
end # DirObject
|
106
|
+
|
107
|
+
class FileObject
|
108
|
+
EXTS = [
|
109
|
+
'h', 'hxx', 'hpp', 'c', 'cc', 'cxx', 'cpp', 'H', 'C', 'inl', 'asm',
|
110
|
+
'rb', 'erb', 'pl', 'pm', 'py',
|
111
|
+
'idl', 'pidl',
|
112
|
+
'mwc', 'mpc', 'mpb', 'mpt', 'mpd',
|
113
|
+
'cdp', 'xml', 'conf', 'html',
|
114
|
+
'asc', 'adoc'
|
115
|
+
]
|
116
|
+
FILES = [
|
117
|
+
'ChangeLog', 'README'
|
118
|
+
]
|
119
|
+
|
120
|
+
def self.extensions
|
121
|
+
EXTS
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.filenames
|
125
|
+
FILES
|
126
|
+
end
|
127
|
+
|
128
|
+
class LinePointer
|
129
|
+
attr_reader :err_lines
|
130
|
+
|
131
|
+
FZZR_ENABLE_RE = /X11_FUZZ\: enable ([^\s]+)/
|
132
|
+
FZZR_DISABLE_RE = /X11_FUZZ\: disable ([^\s]+)/
|
133
|
+
|
134
|
+
def initialize(lines, fzzr_id)
|
135
|
+
@lines = lines
|
136
|
+
@fzzr_id = fzzr_id.to_s
|
137
|
+
@err_lines = []
|
138
|
+
reset
|
139
|
+
end
|
140
|
+
def fzzr_disabled?
|
141
|
+
@fzzr_disabled
|
142
|
+
end
|
143
|
+
def line_nr
|
144
|
+
@line_nr+1
|
145
|
+
end
|
146
|
+
def text_at(offs)
|
147
|
+
ln = @line_nr+offs
|
148
|
+
if ln>=0 && ln<@lines.size
|
149
|
+
return @lines[ln]
|
150
|
+
end
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
def set_text_at(offs, txt)
|
154
|
+
ln = @line_nr+offs
|
155
|
+
if ln>=0 && ln<@lines.size
|
156
|
+
return (@lines[ln] = txt)
|
157
|
+
end
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
def text
|
161
|
+
text_at(0)
|
162
|
+
end
|
163
|
+
def text=(txt)
|
164
|
+
set_text_at(0, txt)
|
165
|
+
end
|
166
|
+
def move(offs)
|
167
|
+
if offs < 0
|
168
|
+
_backward(-offs) unless bof?
|
169
|
+
else
|
170
|
+
_forward(offs) unless eof?
|
171
|
+
end
|
172
|
+
self.line_nr
|
173
|
+
end
|
174
|
+
def reset
|
175
|
+
@line_nr = 0
|
176
|
+
@fzzr_disabled = false
|
177
|
+
_check_fzzr_escape
|
178
|
+
end
|
179
|
+
def to_eof
|
180
|
+
_forward(@lines.size - @line_nr)
|
181
|
+
end
|
182
|
+
def eof?
|
183
|
+
@line_nr >= @lines.size
|
184
|
+
end
|
185
|
+
def bof?
|
186
|
+
@line_nr <= 0
|
187
|
+
end
|
188
|
+
def mark_error(ln = nil)
|
189
|
+
@err_lines << (ln || (@line_nr+1))
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def _forward(distance)
|
195
|
+
distance.times do
|
196
|
+
@line_nr += 1
|
197
|
+
break if eof?
|
198
|
+
_check_fzzr_escape
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def _backward(distance)
|
203
|
+
distance.times do
|
204
|
+
break if bof?
|
205
|
+
@line_nr -= 1
|
206
|
+
_check_fzzr_escape(false)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def _check_fzzr_escape(forward = true)
|
211
|
+
begin
|
212
|
+
if FZZR_ENABLE_RE =~ @lines[@line_nr]
|
213
|
+
@fzzr_disabled = !forward if $1 == @fzzr_id
|
214
|
+
elsif FZZR_DISABLE_RE =~ @lines[@line_nr]
|
215
|
+
@fzzr_disabled = forward if $1 == @fzzr_id
|
216
|
+
end
|
217
|
+
rescue
|
218
|
+
Fuzz.log_error(%Q{ERROR: Exception while checking fzzr escapes in line #{@line_nr+1} - #{$!}\n#{@lines[@line_nr]}})
|
219
|
+
raise
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end # LinePointer
|
223
|
+
|
224
|
+
attr_reader :path, :fullpath, :name, :ext, :lines
|
225
|
+
|
226
|
+
def initialize(path)
|
227
|
+
@path = path
|
228
|
+
@fullpath = File.expand_path(path)
|
229
|
+
@name = File.basename(path)
|
230
|
+
@ext = File.extname(path).sub(/^\./,'')
|
231
|
+
@lines = nil
|
232
|
+
@pointer = nil
|
233
|
+
@changed = false
|
234
|
+
end
|
235
|
+
|
236
|
+
def changed?
|
237
|
+
@changed
|
238
|
+
end
|
239
|
+
|
240
|
+
def iterate(fzzr_id, &block)
|
241
|
+
@lines ||= IO.readlines(fullpath)
|
242
|
+
lines_copy = @lines.collect {|l| l.dup }
|
243
|
+
pointer = LinePointer.new(@lines, fzzr_id)
|
244
|
+
begin
|
245
|
+
block.call(pointer) unless pointer.fzzr_disabled?
|
246
|
+
pointer.move(1)
|
247
|
+
end while !pointer.eof?
|
248
|
+
Fuzz.log_error(%Q{#{self.path}[#{pointer.err_lines.join(',')}] #{Fuzz.get_fzzr(fzzr_id).errormsg}}) unless pointer.err_lines.empty?
|
249
|
+
@changed |= (@lines != lines_copy)
|
250
|
+
lines_copy = nil
|
251
|
+
return pointer.err_lines.empty?
|
252
|
+
end
|
253
|
+
|
254
|
+
def to_s
|
255
|
+
"File:#{fullpath}"
|
256
|
+
end
|
257
|
+
end # FileObject
|
258
|
+
end # Fuzz
|
data/lib/fuzz/log.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#--------------------------------------------------------------------
|
2
|
+
# @file log.rb
|
3
|
+
# @author Martin Corino
|
4
|
+
#
|
5
|
+
# @brief Fuzz logging support
|
6
|
+
#
|
7
|
+
# @copyright Copyright (c) Remedy IT Expertise BV
|
8
|
+
#--------------------------------------------------------------------
|
9
|
+
require 'fuzz/console'
|
10
|
+
|
11
|
+
module Fuzz
|
12
|
+
|
13
|
+
#
|
14
|
+
# Default Reporting/Logging
|
15
|
+
#
|
16
|
+
class Reporter
|
17
|
+
def initialize(output = Fuzz::Console)
|
18
|
+
@output = output
|
19
|
+
klass = class << self; self; end
|
20
|
+
klass.__send__(:include, @output.colorizer_include)
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :output
|
24
|
+
|
25
|
+
def log_error(msg)
|
26
|
+
output.error_println 'Fuzz - ', red(bold 'ERROR'), ' : ', msg
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_warning(msg)
|
30
|
+
output.error_println 'Fuzz - ', yellow(bold 'WARNING'), ' : ', msg
|
31
|
+
end
|
32
|
+
|
33
|
+
def log_info(msg)
|
34
|
+
output.println 'Fuzz - ', msg
|
35
|
+
end
|
36
|
+
|
37
|
+
def show_error(msg)
|
38
|
+
log_error(msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def show_warning(msg)
|
42
|
+
log_error(msg)
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_msg(msg)
|
46
|
+
log(msg)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module LogMethods
|
51
|
+
def log_fatal(msg, rc=1)
|
52
|
+
Fuzz.reporter.log_error(msg)
|
53
|
+
exit rc
|
54
|
+
end
|
55
|
+
|
56
|
+
def log_error(msg)
|
57
|
+
Fuzz.reporter.log_error(msg)
|
58
|
+
end
|
59
|
+
|
60
|
+
def log_warning(msg)
|
61
|
+
Fuzz.reporter.log_warning(msg)
|
62
|
+
end
|
63
|
+
|
64
|
+
def log_info(msg)
|
65
|
+
Fuzz.reporter.log_info(msg)
|
66
|
+
end
|
67
|
+
|
68
|
+
def log(lvl, msg)
|
69
|
+
Fuzz.reporter.log_info(msg) if lvl <= verbosity
|
70
|
+
end
|
71
|
+
|
72
|
+
def show_error(msg)
|
73
|
+
Fuzz.reporter.show_error(msg)
|
74
|
+
end
|
75
|
+
|
76
|
+
def show_warning(msg)
|
77
|
+
Fuzz.reporter.show_warning(msg)
|
78
|
+
end
|
79
|
+
|
80
|
+
def show_msg(msg)
|
81
|
+
Fuzz.reporter.show_msg(msg)
|
82
|
+
end
|
83
|
+
|
84
|
+
def verbosity
|
85
|
+
Fuzz.verbosity
|
86
|
+
end
|
87
|
+
|
88
|
+
def verbose?
|
89
|
+
verbosity > 1
|
90
|
+
end
|
91
|
+
|
92
|
+
def silent?
|
93
|
+
verbosity < 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end # Fuzz
|
data/lib/fuzz/options.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
#--------------------------------------------------------------------
|
2
|
+
# @file options.rb
|
3
|
+
# @author Martin Corino
|
4
|
+
#
|
5
|
+
# @brief Options module for fuzz
|
6
|
+
#
|
7
|
+
# @copyright Copyright (c) Remedy IT Expertise BV
|
8
|
+
#--------------------------------------------------------------------
|
9
|
+
|
10
|
+
require 'ostruct'
|
11
|
+
require 'yaml'
|
12
|
+
require 'fuzz/log'
|
13
|
+
|
14
|
+
module Fuzz
|
15
|
+
|
16
|
+
FUZZRC = '.fuzzrc'
|
17
|
+
FUZZRC_GLOBAL = File.expand_path(File.join(ENV['HOME'] || ENV['HOMEPATH'] || '~', FUZZRC))
|
18
|
+
|
19
|
+
OPTIONS = OpenStruct.new
|
20
|
+
|
21
|
+
class << OPTIONS
|
22
|
+
|
23
|
+
include Fuzz::LogMethods
|
24
|
+
|
25
|
+
def options
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
class Config < OpenStruct
|
30
|
+
|
31
|
+
include Fuzz::LogMethods
|
32
|
+
|
33
|
+
def initialize(hash=nil)
|
34
|
+
super
|
35
|
+
@table = _merge(_defaults, @table)
|
36
|
+
end
|
37
|
+
|
38
|
+
def options
|
39
|
+
Fuzz.options
|
40
|
+
end
|
41
|
+
|
42
|
+
def merge(from)
|
43
|
+
_merge(@table, from)
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def load(rcpath)
|
48
|
+
log(3, "Loading #{FUZZRC} from #{rcpath}")
|
49
|
+
_cfg = YAML.load(IO.read(rcpath))
|
50
|
+
log(4, "Read from #{rcpath}: [#{_cfg}]")
|
51
|
+
# handle automatic env var expansion in fzzr_paths
|
52
|
+
_cfg[:fzzr_paths] = (_cfg[:fzzr_paths] || []).collect do |p|
|
53
|
+
log(5, "Examining fzzr_path [#{p}]")
|
54
|
+
# for paths coming from rc files environment vars are immediately expanded and
|
55
|
+
p.gsub!(/\$([^\s\/]+)/) { |m| ENV[$1] }
|
56
|
+
log(6, "Expanded fzzr_path [#{p}]")
|
57
|
+
# resulting relative paths converted to absolute paths
|
58
|
+
if File.directory?(p) # relative to working dir?
|
59
|
+
p = File.expand_path(p)
|
60
|
+
else # relative to rc location?
|
61
|
+
_fp = File.expand_path(File.join(File.dirname(rcpath), p))
|
62
|
+
log(4, "Ignoring invalid fuzzer search path #{p} configured in #{rcpath}") unless File.directory?(_fp)
|
63
|
+
p = _fp
|
64
|
+
end
|
65
|
+
log(4, "Adding fuzzer search path: #{p}")
|
66
|
+
p
|
67
|
+
end
|
68
|
+
merge(_cfg)
|
69
|
+
end
|
70
|
+
|
71
|
+
def save(rcpath)
|
72
|
+
File.open(rcpath, 'w') {|f| f << YAML.dump(@table) }
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def _defaults
|
78
|
+
{
|
79
|
+
:brix_paths => []
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def _merge(to, from)
|
84
|
+
from.each_pair do |(k,v)|
|
85
|
+
k = k.to_sym
|
86
|
+
if to.has_key?(k)
|
87
|
+
case to[k]
|
88
|
+
when Array
|
89
|
+
to[k].concat v
|
90
|
+
when Hash
|
91
|
+
to[k].merge!(v)
|
92
|
+
when OpenStruct
|
93
|
+
_merge(to[k].__send__(:table), v)
|
94
|
+
else
|
95
|
+
to[k] = v
|
96
|
+
end
|
97
|
+
else
|
98
|
+
to[k] = v
|
99
|
+
end
|
100
|
+
end
|
101
|
+
to
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def _defaults
|
109
|
+
{
|
110
|
+
:verbose => (ENV['FUZZ_VERBOSE'] || 1).to_i,
|
111
|
+
:recurse => true,
|
112
|
+
:apply_fix => false,
|
113
|
+
:config => Config.new({
|
114
|
+
:follow_symlink => true,
|
115
|
+
:exts => [],
|
116
|
+
:filenames => [],
|
117
|
+
:excludes => [],
|
118
|
+
:add_files => false,
|
119
|
+
:fzzr_paths => [],
|
120
|
+
:fzzr_opts => {},
|
121
|
+
:fzzr_excludes => []
|
122
|
+
})
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
def _rc_paths
|
127
|
+
@rc_paths ||= []
|
128
|
+
end
|
129
|
+
def _loaded_rc_paths
|
130
|
+
@loaded_rc_paths ||= []
|
131
|
+
end
|
132
|
+
|
133
|
+
def _add_rcpath(path)
|
134
|
+
if _loaded_rc_paths.include?(File.expand_path(path))
|
135
|
+
log(3, "ignoring already loaded rc : #{path}")
|
136
|
+
else
|
137
|
+
log(3, "adding rc path : #{path}")
|
138
|
+
_rc_paths << path
|
139
|
+
end
|
140
|
+
_rc_paths
|
141
|
+
end
|
142
|
+
|
143
|
+
public
|
144
|
+
|
145
|
+
def reset
|
146
|
+
@table.clear
|
147
|
+
@table.merge!(_defaults)
|
148
|
+
_rc_paths.clear
|
149
|
+
_rc_paths << FUZZRC_GLOBAL
|
150
|
+
_loaded_rc_paths.clear
|
151
|
+
(ENV['FUZZRC'] || '').split(/:|;/).each do |p|
|
152
|
+
_add_rcpath(p)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def load_config
|
157
|
+
# first collect config from known (standard and configured) locations
|
158
|
+
_rc_paths.collect {|path| File.expand_path(path) }.each do |rcp|
|
159
|
+
log(3, "Testing rc path #{rcp}")
|
160
|
+
if File.readable?(rcp) && !_loaded_rc_paths.include?(rcp)
|
161
|
+
_cfg = Config.new.load(rcp)
|
162
|
+
self[:config].merge(_cfg)
|
163
|
+
_loaded_rc_paths << rcp
|
164
|
+
else
|
165
|
+
log(3, "Ignoring #{File.readable?(rcp) ? 'already loaded' : 'inaccessible'} rc path #{rcp}")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
# now scan working path for any rc files unless specified otherwise
|
169
|
+
unless self[:no_rc_scan]
|
170
|
+
_cwd = File.expand_path(Dir.getwd)
|
171
|
+
log(3, "scanning working path #{_cwd} for rc files")
|
172
|
+
# first collect any rc files found
|
173
|
+
_rcpaths = []
|
174
|
+
begin
|
175
|
+
_rcp = File.join(_cwd, FUZZRC)
|
176
|
+
if File.readable?(_rcp) && !_loaded_rc_paths.include?(_rcp)
|
177
|
+
_rcpaths << _rcp
|
178
|
+
else
|
179
|
+
log(3, "Ignoring #{File.readable?(_rcp) ? 'already loaded' : 'inaccessible'} rc path #{_rcp}")
|
180
|
+
end
|
181
|
+
break if /\A(.:(\\|\/)|\.|\/)\Z/ =~ _cwd
|
182
|
+
_cwd = File.dirname(_cwd)
|
183
|
+
end while true
|
184
|
+
# now load them in reverse order
|
185
|
+
_rcpaths.reverse.each do |_rcp|
|
186
|
+
_cfg = Config.new.load(_rcp)
|
187
|
+
self[:config].merge(_cfg)
|
188
|
+
_loaded_rc_paths << _rcp
|
189
|
+
end
|
190
|
+
end
|
191
|
+
# lastly merge config specified by user on commandline
|
192
|
+
self[:config].merge(user_config)
|
193
|
+
end
|
194
|
+
|
195
|
+
def add_config(rcpath)
|
196
|
+
log_fatal("inaccessible rc path specified : #{rcpath}") unless File.readable?(rcpath)
|
197
|
+
_add_rcpath(rcpath)
|
198
|
+
end
|
199
|
+
|
200
|
+
def user_config
|
201
|
+
@user_config ||= Config.new
|
202
|
+
end
|
203
|
+
|
204
|
+
end # OPTIONS class
|
205
|
+
|
206
|
+
OPTIONS.reset # initialize
|
207
|
+
|
208
|
+
end # Fuzz
|