lint_fu 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+