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.

@@ -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
@@ -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
@@ -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
@@ -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