lint_fu 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ module LintFu
2
+ module SourceControl
3
+ class Git < SourceControlProvider
4
+ BLAME_REGEXP = /^(.*) \((.+) [0-9]{4}-[0-9]{1,2}-[0-9]{1,2}\s+([0-9]+)\)/
5
+
6
+ def initialize(path)
7
+ super(path)
8
+
9
+ `git version`
10
+ raise ProviderNotInstalled, self unless $?.success?
11
+
12
+ dot_git = File.join(path, '.git')
13
+ raise ProviderError.new(self, path) unless File.directory?(dot_git)
14
+ end
15
+
16
+ # ==Return
17
+ # An array containing [author, commit_ref]
18
+ def blame(file, line)
19
+ #commit, author, line_no,
20
+ output = `git blame --date=short -w -L #{line} #{file}`
21
+ match = BLAME_REGEXP.match(output)
22
+ if $?.success? && match && (match[3].to_i == line)
23
+ return [ match[1].strip, match[2].strip ]
24
+ else
25
+ raise ProviderError, output
26
+ end
27
+ end
28
+
29
+ def excerpt(file, range, options={})
30
+ blame = options.has_key?(:blame) ? options[:blame] : true
31
+
32
+ return super unless blame
33
+
34
+ Dir.chdir(@root) do
35
+ start_line = range.first
36
+ end_line = range.last
37
+ relative_path = File.relative_path(@root, file)
38
+
39
+ output = `git blame --date=short #{blame ? '' : '-s'} -w -L #{start_line},#{end_line} #{relative_path} 2> /dev/null`
40
+ return output if $?.success?
41
+
42
+ #HACK: if git blame failed, assume we need to bound according to end of file
43
+ file_length = `wc -l #{relative_path}`.split[0].to_i
44
+ end_line = file_length
45
+ output = `git blame --date=short #{blame ? '' : '-s'} -w -L #{start_line},#{end_line} #{relative_path}`
46
+ return output.split("\n") if $?.success?
47
+
48
+ raise ProviderError.new("'git blame' failed with code #{$?.exitstatus}: #{output}")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,58 @@
1
+ module LintFu
2
+ class ProviderError < Exception
3
+ def initialize(*args)
4
+ if args.length == 2 && args[0].kind_of?(LintFu::SourceControlProvider)
5
+ provider = args[0]
6
+ path = args[1]
7
+ super("The #{provider.class.name} source control provider does not recognize #{path} as a valid repository")
8
+ else
9
+ super(*args)
10
+ end
11
+ end
12
+ end
13
+
14
+ class ProviderNotInstalled < ProviderError
15
+ def initialize(provider)
16
+ super("The #{provider.name} source control provider does not seem to be installed on this system.")
17
+ end
18
+ end
19
+
20
+ class SourceControlProvider
21
+ @@subclasses = Set.new
22
+
23
+ # Inherited callback to ensure this base class knows about all derived classes.
24
+ def self.inherited(base)
25
+ @@subclasses << base
26
+ end
27
+
28
+ # Instantiate the appropriate Provider subclass for a given directory.
29
+ def self.for_directory(path)
30
+ @@subclasses.each do |provider|
31
+ begin
32
+ return provider.new(path)
33
+ rescue Exception => e
34
+ next
35
+ end
36
+ end
37
+
38
+ return nil
39
+ end
40
+
41
+ def initialize(path)
42
+ @root = path
43
+ end
44
+
45
+ def excerpt(file, range, options={})
46
+ blame = options.has_key?(:blame) ? options[:blame] : true
47
+ raise ProviderError, "Blame is not supported for this source control provider" if blame
48
+
49
+ Dir.chdir(@root) do
50
+ start_line = range.first
51
+ end_line = range.last
52
+ io = File.open(File.relative_path(@root, file), 'r')
53
+ lines = io.readlines
54
+ return lines[(start_line-1)..(end_line-1)]
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,36 @@
1
+ module LintFu
2
+ class Visitor < SexpProcessor
3
+ attr_reader :observers
4
+
5
+ def initialize
6
+ super
7
+ self.require_empty = false
8
+ self.auto_shift_type = false
9
+ @observers = []
10
+ end
11
+
12
+ def process(sexp)
13
+ tag = sexp[0]
14
+
15
+ begin_meth = "observe_#{tag}_begin".to_sym
16
+ around_meth = "observe_#{tag}".to_sym
17
+ end_meth = "observe_#{tag}_end".to_sym
18
+
19
+ observers.each do |o|
20
+ o.__send__(begin_meth, sexp) if o.respond_to?(begin_meth)
21
+ end
22
+
23
+ observers.each do |o|
24
+ o.__send__(around_meth, sexp) if o.respond_to?(around_meth)
25
+ end
26
+
27
+ result = super(sexp)
28
+
29
+ observers.each do |o|
30
+ o.__send__(end_meth, sexp) if o.respond_to?(end_meth)
31
+ end
32
+
33
+ return result
34
+ end
35
+ end
36
+ end
data/lib/lint_fu.rb ADDED
@@ -0,0 +1,34 @@
1
+ # Load Ruby std library classes we depend upon
2
+ require 'set'
3
+ require 'digest/md5'
4
+ require 'digest/sha1'
5
+
6
+ # Activate the various gems we depend on
7
+ require 'active_support'
8
+ require 'ruby_parser'
9
+ require 'sexp_processor'
10
+ require 'ruby2ruby'
11
+ require 'builder'
12
+ require 'redcloth'
13
+
14
+ # Mixins for various Ruby builtins and classes defined by other gems
15
+ require 'lint_fu/mixins'
16
+
17
+ # Core lint-fu sources
18
+ require 'lint_fu/parser'
19
+ require 'lint_fu/model_element'
20
+ require 'lint_fu/model_element_builder'
21
+ require 'lint_fu/source_control_provider'
22
+ require 'lint_fu/issue'
23
+ require 'lint_fu/checker'
24
+ require 'lint_fu/visitor'
25
+ require 'lint_fu/scan'
26
+ require 'lint_fu/report'
27
+
28
+ # lint-fu source control providers
29
+ require 'lint_fu/source_control/git'
30
+
31
+ # lint-fu plugins
32
+ require 'lint_fu/active_record'
33
+ require 'lint_fu/action_pack'
34
+ require 'lint_fu/rails'
data/lint_fu.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
7
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
8
+
9
+ s.name = 'lint_fu'
10
+ s.version = '0.5.0'
11
+ s.date = '2011-02-19'
12
+
13
+ s.authors = ['Tony Spataro']
14
+ s.email = 'code@tracker.xeger.net'
15
+ s.homepage= 'http://github.com/xeger/lint_fu'
16
+
17
+ s.summary = %q{Security scanner that performs static analysis of Ruby code.}
18
+ s.description = %q{This tool helps identify bugs in your code. It is Rails-centric but its modular design allows support for other application frameworks.}
19
+
20
+ s.add_runtime_dependency('ruby_parser', ["~> 2.0"])
21
+ s.add_runtime_dependency('ruby2ruby', ["~> 1.2"])
22
+ s.add_runtime_dependency('activesupport', ["~> 2.3"])
23
+
24
+ s.executables = ["lint_fu"]
25
+
26
+ candidates = ['lint_fu.gemspec', 'MIT-LICENSE', 'README.rdoc'] +
27
+ Dir['lib/**/*'] +
28
+ Dir['bin/*']
29
+ s.files = candidates.sort
30
+ end
31
+
32
+ if $PROGRAM_NAME == __FILE__
33
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
34
+ Gem::Builder.new(spec).build
35
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lint_fu
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
11
+ platform: ruby
12
+ authors:
13
+ - Tony Spataro
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-19 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ruby_parser
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 2
32
+ - 0
33
+ version: "2.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: ruby2ruby
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 11
45
+ segments:
46
+ - 1
47
+ - 2
48
+ version: "1.2"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: activesupport
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 5
60
+ segments:
61
+ - 2
62
+ - 3
63
+ version: "2.3"
64
+ type: :runtime
65
+ version_requirements: *id003
66
+ description: This tool helps identify bugs in your code. It is Rails-centric but its modular design allows support for other application frameworks.
67
+ email: code@tracker.xeger.net
68
+ executables:
69
+ - lint_fu
70
+ extensions: []
71
+
72
+ extra_rdoc_files: []
73
+
74
+ files:
75
+ - MIT-LICENSE
76
+ - README.rdoc
77
+ - bin/lint_fu
78
+ - lib/lint_fu.rb
79
+ - lib/lint_fu/action_pack.rb
80
+ - lib/lint_fu/action_pack/model_controller.rb
81
+ - lib/lint_fu/action_pack/model_controller_builder.rb
82
+ - lib/lint_fu/active_record.rb
83
+ - lib/lint_fu/active_record/model_model.rb
84
+ - lib/lint_fu/active_record/model_model_builder.rb
85
+ - lib/lint_fu/checker.rb
86
+ - lib/lint_fu/issue.rb
87
+ - lib/lint_fu/mixins.rb
88
+ - lib/lint_fu/mixins/file_class_methods.rb
89
+ - lib/lint_fu/mixins/sexp_instance_methods.rb
90
+ - lib/lint_fu/mixins/symbol_instance_methods.rb
91
+ - lib/lint_fu/model_element.rb
92
+ - lib/lint_fu/model_element_builder.rb
93
+ - lib/lint_fu/parser.rb
94
+ - lib/lint_fu/rails.rb
95
+ - lib/lint_fu/rails/buggy_eager_load_checker.rb
96
+ - lib/lint_fu/rails/model_application.rb
97
+ - lib/lint_fu/rails/model_application_builder.rb
98
+ - lib/lint_fu/rails/scan_builder.rb
99
+ - lib/lint_fu/rails/sql_injection_checker.rb
100
+ - lib/lint_fu/rails/unsafe_find_checker.rb
101
+ - lib/lint_fu/report.rb
102
+ - lib/lint_fu/scan.rb
103
+ - lib/lint_fu/source_control/git.rb
104
+ - lib/lint_fu/source_control_provider.rb
105
+ - lib/lint_fu/visitor.rb
106
+ - lint_fu.gemspec
107
+ has_rdoc: true
108
+ homepage: http://github.com/xeger/lint_fu
109
+ licenses: []
110
+
111
+ post_install_message:
112
+ rdoc_options: []
113
+
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: 57
122
+ segments:
123
+ - 1
124
+ - 8
125
+ - 7
126
+ version: 1.8.7
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
135
+ version: "0"
136
+ requirements: []
137
+
138
+ rubyforge_project:
139
+ rubygems_version: 1.3.7
140
+ signing_key:
141
+ specification_version: 3
142
+ summary: Security scanner that performs static analysis of Ruby code.
143
+ test_files: []
144
+