lint_fu 0.5.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/README.rdoc +4 -2
  2. data/bin/lint_fu +2 -86
  3. data/lib/lint_fu/blessing.rb +40 -0
  4. data/lib/lint_fu/checker.rb +49 -3
  5. data/lib/lint_fu/cli/command.rb +48 -0
  6. data/lib/lint_fu/cli/prune.rb +78 -0
  7. data/lib/lint_fu/cli/scan.rb +78 -0
  8. data/lib/lint_fu/cli.rb +52 -0
  9. data/lib/lint_fu/eidos.rb +35 -0
  10. data/lib/lint_fu/{model_element_builder.rb → eidos_builder.rb} +8 -3
  11. data/lib/lint_fu/eidos_container.rb +25 -0
  12. data/lib/lint_fu/file_range.rb +43 -0
  13. data/lib/lint_fu/mixins/sexp_instance_methods.rb +57 -9
  14. data/lib/lint_fu/parser.rb +1 -2
  15. data/lib/lint_fu/plugins/action_pack/controller_eidos.rb +7 -0
  16. data/lib/lint_fu/{action_pack/model_controller_builder.rb → plugins/action_pack/controller_eidos_builder.rb} +6 -6
  17. data/lib/lint_fu/plugins/action_pack.rb +2 -0
  18. data/lib/lint_fu/{active_record/model_model.rb → plugins/active_record/model_eidos.rb} +3 -3
  19. data/lib/lint_fu/{active_record/model_model_builder.rb → plugins/active_record/model_eidos_builder.rb} +17 -11
  20. data/lib/lint_fu/plugins/active_record.rb +2 -0
  21. data/lib/lint_fu/{rails → plugins/rails}/buggy_eager_load_checker.rb +6 -5
  22. data/lib/lint_fu/{rails/scan_builder.rb → plugins/rails/issue_builder.rb} +9 -16
  23. data/lib/lint_fu/plugins/rails/model_application.rb +21 -0
  24. data/lib/lint_fu/plugins/rails/model_application_factory.rb +31 -0
  25. data/lib/lint_fu/{rails → plugins/rails}/sql_injection_checker.rb +9 -5
  26. data/lib/lint_fu/{rails → plugins/rails}/unsafe_find_checker.rb +17 -30
  27. data/lib/lint_fu/plugins/rails.rb +29 -0
  28. data/lib/lint_fu/plugins.rb +11 -0
  29. data/lib/lint_fu/scan.rb +1 -49
  30. data/lib/lint_fu.rb +13 -8
  31. data/lint_fu.gemspec +10 -7
  32. metadata +140 -24
  33. data/lib/lint_fu/action_pack/model_controller.rb +0 -7
  34. data/lib/lint_fu/action_pack.rb +0 -2
  35. data/lib/lint_fu/active_record.rb +0 -2
  36. data/lib/lint_fu/model_element.rb +0 -48
  37. data/lib/lint_fu/rails/model_application.rb +0 -16
  38. data/lib/lint_fu/rails/model_application_builder.rb +0 -32
  39. data/lib/lint_fu/rails.rb +0 -6
@@ -0,0 +1,21 @@
1
+ module LintFu::Plugins
2
+ module Rails
3
+ class ModelApplication
4
+ attr_reader :fs_root
5
+
6
+ include LintFu::EidosContainer
7
+
8
+ def initialize(fs_root)
9
+ @fs_root = fs_root
10
+ end
11
+
12
+ def controllers
13
+ eide.select { |m| m.kind_of?(LintFu::Plugins::ActionPack::ControllerEidos) }
14
+ end
15
+
16
+ def models
17
+ eide.select { |m| m.kind_of?(LintFu::Plugins::ActiveRecord::ModelEidos) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module LintFu::Plugins
2
+ module Rails
3
+ class ModelApplicationFactory < LintFu::EidosBuilder
4
+ def initialize(fs_root)
5
+ super
6
+ @application = ModelApplication.new(fs_root)
7
+ self.eide << @application
8
+ end
9
+
10
+ def build
11
+ models_dir = File.join(@application.fs_root, 'app', 'models')
12
+ builder = LintFu::Plugins::ActiveRecord::ModelEidosBuilder.new
13
+ #TODO ensure the Rails app is using ActiveRecord
14
+ Dir.glob(File.join(models_dir, '**', '*.rb')).each do |f|
15
+ sexp = LintFu::Parser.parse_ruby(f)
16
+ builder.process(sexp)
17
+ end
18
+ builder.eide.each { |elem| @application.add_eidos(elem) }
19
+
20
+ controllers_dir = File.join(@application.fs_root, 'app', 'controllers')
21
+ builder = ActionPack::ControllerEidosBuilder.new
22
+ Dir.glob(File.join(controllers_dir, '**', '*.rb')).each do |f|
23
+ sexp = LintFu::Parser.parse_ruby(f)
24
+ sexp.file = f
25
+ builder.process(sexp)
26
+ end
27
+ builder.eide.each { |elem| @application.add_eidos(elem) }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,6 +1,6 @@
1
- module LintFu
1
+ module LintFu::Plugins
2
2
  module Rails
3
- class SqlInjection < Issue
3
+ class SqlInjection < LintFu::Issue
4
4
  def initialize(scan, file, sexp, subject, confidence=1.0)
5
5
  super(scan, file, sexp, confidence)
6
6
  @subject = subject
@@ -44,7 +44,7 @@ EOF
44
44
 
45
45
  # Visit a Rails controller looking for ActiveRecord queries that contain interpolated
46
46
  # strings.
47
- class SqlInjectionChecker < Checker
47
+ class SqlInjectionChecker < LintFu::Checker
48
48
  FINDER_REGEXP = /^(find|first|all)(_or_initialize)?(_by_.*_id)?/
49
49
  SINK_OPTIONS = Set.new([:conditions, :select, :order, :group, :from, :include, :join])
50
50
 
@@ -55,30 +55,34 @@ EOF
55
55
  end
56
56
 
57
57
  def observe_class_begin(sexp)
58
+ super(sexp)
58
59
  @class_definition_scope.push sexp
59
60
  end
60
61
 
61
62
  def observe_class_end(sexp)
63
+ super(sexp)
62
64
  @class_definition_scope.pop
63
65
  end
64
66
 
65
67
  def observe_defn_begin(sexp)
66
-
68
+ super(sexp)
67
69
  @in_method = true
68
70
  end
69
71
 
70
72
  def observe_defn_end(sexp)
73
+ super(sexp)
71
74
  @in_method = false
72
75
  end
73
76
 
74
77
  def observe_call(sexp)
78
+ super(sexp)
75
79
  return if @class_definition_scope.empty? || !@in_method
76
80
 
77
81
  call = sexp[2].to_s
78
82
  arglist = sexp[3]
79
83
 
80
84
  tp = tainted_params(arglist)
81
- if finder?(call) && !tp.empty?
85
+ if finder?(call) && !tp.empty? && !suppressed?(UnsafeFind)
82
86
  scan.issues << SqlInjection.new(scan, self.file, sexp, tp[0].to_ruby_string, @base_confidence)
83
87
  end
84
88
  end
@@ -1,6 +1,6 @@
1
- module LintFu
1
+ module LintFu::Plugins
2
2
  module Rails
3
- class UnsafeFind < Issue
3
+ class UnsafeFind < LintFu::Issue
4
4
  def initialize(scan, file, sexp, subject)
5
5
  super(scan, file, sexp)
6
6
  @subject = subject
@@ -55,64 +55,51 @@ EOF
55
55
  # Visit a Rails controller looking for ActiveRecord finders being called in a way that
56
56
  # might allow an attacker to perform unauthorized operations on resources, e.g. creating,
57
57
  # updating or deleting someone else's records.
58
- class UnsafeFindChecker < Checker
58
+ class UnsafeFindChecker < LintFu::Checker
59
59
  FINDER_REGEXP = /^(find|first|all)(_or_initialize)?(_by_.*_id)?/
60
-
61
- #sexp:: s(:class, <class_name>, <superclass>, s(:scope, <class_definition>))
62
- def observe_class_begin(sexp)
63
- #TODO get rid of RightScale-specific assumption
64
- @in_admin_controller = !!(sexp[1].to_ruby_string =~ /^Admin/)
65
- end
66
-
67
- #sexp:: s(:class, <class_name>, <superclass>, s(:scope, <class_definition>))
68
- def observe_class_end(sexp)
69
- @in_admin_controller = false
70
- end
60
+ #TODO: make this tunable, also expose it to the user to make sure it's appropriate!!
61
+ SAFE_INSTANCE_METHODS = [:current_user, :current_account]
71
62
 
72
63
  #sexp:: s(:call, <target>, <method_name>, s(:arglist))
73
64
  def observe_call(sexp)
65
+ super(sexp)
74
66
  check_suspicious_finder(sexp)
75
67
  end
76
68
 
77
69
  protected
78
70
 
79
71
  def check_suspicious_finder(sexp)
80
- return if @in_admin_controller
81
-
82
72
  #sexp:: :call, <target>, <method_name>, <argslist...>
83
73
  if (sexp[1] != nil) && (sexp[1][0] == :const || sexp[1][0] == :colon2)
84
74
  name = sexp[1].to_ruby_string
85
75
  type = self.context.models.detect { |m| m.modeled_class_name == name }
86
76
  call = sexp[2].to_s
87
77
  params = sexp[3]
88
- if finder?(type, call) && !params.constant? && !sexp_contains_scope?(params)
78
+ if finder?(type, call) && !params.constant? &&
79
+ !safely_scoped?(params) && !suppressed?(UnsafeFind)
89
80
  scan.issues << UnsafeFind.new(scan, self.file, sexp, params.to_ruby_string)
90
81
  end
91
- end
82
+ end
92
83
  end
93
84
 
94
85
  def finder?(type, call)
95
- type.kind_of?(LintFu::ActiveRecord::ModelModel) &&
86
+ type.kind_of?(LintFu::Plugins::ActiveRecord::ModelEidos) &&
96
87
  ( call =~ FINDER_REGEXP || type.associations.has_key?(call) )
97
88
  end
98
89
 
99
- def sexp_contains_scope?(sexp)
90
+ def safely_scoped?(sexp)
100
91
  return false if !sexp.kind_of?(Sexp) || sexp.empty?
92
+ return true if sexp.constant?
101
93
 
102
- sexp_type = sexp[0]
103
-
104
- #If calling a method -- check to see if we're accessing a current_* method
105
- if (sexp_type == :call) && (sexp[1] == nil)
94
+ #Some local methods introduce safe scope
95
+ if (sexp[0] == :call)
106
96
  #TODO get rid of RightScale-specific assumptions
107
- return true if (sexp[2] == :current_user)
108
- return true if (sexp[2] == :current_account)
97
+ return true if sexp[1].nil? && SAFE_INSTANCE_METHODS.include?(sexp[2])
109
98
  end
110
99
 
111
- #Generic case: check all subexpressions of the sexp
100
+ #Generic case: check that all subexpressions of the sexp are safely scoped
112
101
  sexp.each do |subexp|
113
- if subexp.kind_of?(Sexp)
114
- return true if sexp_contains_scope?(subexp)
115
- end
102
+ return false if subexp.kind_of?(Sexp) && !safely_scoped?(subexp)
116
103
  end
117
104
 
118
105
  return false
@@ -0,0 +1,29 @@
1
+ require 'lint_fu/plugins/action_pack'
2
+ require 'lint_fu/plugins/active_record'
3
+
4
+ require 'lint_fu/plugins/rails/model_application'
5
+ require 'lint_fu/plugins/rails/model_application_factory'
6
+ require 'lint_fu/plugins/rails/buggy_eager_load_checker'
7
+ require 'lint_fu/plugins/rails/sql_injection_checker'
8
+ require 'lint_fu/plugins/rails/unsafe_find_checker'
9
+ require 'lint_fu/plugins/rails/issue_builder'
10
+
11
+ module LintFu::Plugins
12
+ module Rails
13
+ def self.applies_to?(dir)
14
+ File.exist?(File.join(dir, 'app')) &&
15
+ File.exist?(File.join(dir, 'config', 'environments')) &&
16
+ File.exist?(File.join(dir, 'config', 'environment.rb'))
17
+ end
18
+
19
+ def self.context_builder_for(dir)
20
+ return nil unless applies_to?(dir)
21
+ ModelApplicationFactory.new(dir)
22
+ end
23
+
24
+ def self.issue_builder_for(dir)
25
+ return nil unless applies_to?(dir)
26
+ IssueBuilder.new(dir)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ #Ensure the module's namespace exists, so plugin authors can
2
+ #abbreviate the namespace decls in their files.
3
+ module LintFu
4
+ module Plugins
5
+ end
6
+ end
7
+
8
+ plugins_dir = File.expand_path('../plugins', __FILE__)
9
+ Dir[File.join(plugins_dir, '*.rb')].each do |file|
10
+ require file
11
+ end
data/lib/lint_fu/scan.rb CHANGED
@@ -2,10 +2,6 @@ module LintFu
2
2
  class ScanNotFinalized < Exception; end
3
3
 
4
4
  class Scan
5
- COMMENT = /^\s*#/
6
- VERBOSE_BLESSING_COMMENT = /#\s*(lint|security)\s*[-:]\s*not\s*a?n?\s*([a-z0-9 ]*) ?(as|because|;)\s*(.*)/i
7
- BLESSING_COMMENT = /#\s*(lint|security)\s*[-:]\s*not\s*a?n?\s*([a-z0-9 ]*)/i
8
-
9
5
  attr_reader :fs_root, :issues
10
6
 
11
7
  def initialize(fs_root)
@@ -14,51 +10,7 @@ module LintFu
14
10
  end
15
11
 
16
12
  def blessed?(issue)
17
- comments = preceeding_comments(issue.sexp)
18
- return false unless comments
19
-
20
- match = nil
21
- comments.each do |line|
22
- match = VERBOSE_BLESSING_COMMENT.match(line)
23
- match = BLESSING_COMMENT.match(line) unless match
24
- break if match
25
- end
26
-
27
- return false unless match
28
- blessed_issue_class = match[2].downcase.split(/\s+/).join('_').camelize
29
-
30
- # Determine whether the blessed issue class appears anywhere in the class hierarchy of
31
- # issue_class.
32
- klass = issue.class
33
- while klass
34
- return true if klass.name.index(blessed_issue_class)
35
- klass = klass.superclass
36
- end
37
-
38
- return false
13
+ issue.sexp.blessings.any? { |b| b.issue_class = issue.class }
39
14
  end
40
-
41
- def preceeding_comments(sexp)
42
- @file_contents ||= {}
43
- @file_contents[sexp.file] ||= File.readlines(sexp.file)
44
- cont = @file_contents[sexp.file]
45
-
46
- comments = ''
47
-
48
- max_line = sexp.line - 1 - 1
49
- max_line = 0 if max_line < 0
50
- min_line = max_line
51
-
52
- while cont[min_line] =~ COMMENT && min_line >= 0
53
- min_line -= 1
54
- end
55
-
56
- if cont[max_line] =~ COMMENT
57
- min_line +=1 unless min_line == max_line
58
- return cont[min_line..max_line]
59
- else
60
- return nil
61
- end
62
- end
63
15
  end
64
16
  end
data/lib/lint_fu.rb CHANGED
@@ -4,10 +4,11 @@ require 'digest/md5'
4
4
  require 'digest/sha1'
5
5
 
6
6
  # Activate the various gems we depend on
7
- require 'active_support'
7
+ require 'trollop'
8
8
  require 'ruby_parser'
9
9
  require 'sexp_processor'
10
10
  require 'ruby2ruby'
11
+ require 'active_support'
11
12
  require 'builder'
12
13
  require 'redcloth'
13
14
 
@@ -15,20 +16,24 @@ require 'redcloth'
15
16
  require 'lint_fu/mixins'
16
17
 
17
18
  # Core lint-fu sources
19
+ require 'lint_fu/file_range'
18
20
  require 'lint_fu/parser'
19
- require 'lint_fu/model_element'
20
- require 'lint_fu/model_element_builder'
21
+ require 'lint_fu/eidos'
22
+ require 'lint_fu/eidos_container'
23
+ require 'lint_fu/eidos_builder'
21
24
  require 'lint_fu/source_control_provider'
22
25
  require 'lint_fu/issue'
26
+ require 'lint_fu/blessing'
23
27
  require 'lint_fu/checker'
24
28
  require 'lint_fu/visitor'
25
29
  require 'lint_fu/scan'
26
30
  require 'lint_fu/report'
27
31
 
28
- # lint-fu source control providers
32
+ # source control providers
29
33
  require 'lint_fu/source_control/git'
30
34
 
31
- # lint-fu plugins
32
- require 'lint_fu/active_record'
33
- require 'lint_fu/action_pack'
34
- require 'lint_fu/rails'
35
+ # plugins
36
+ require 'lint_fu/plugins'
37
+
38
+ # command line interface
39
+ require 'lint_fu/cli'
data/lint_fu.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- mode: ruby; encoding: utf-8 -*-
2
2
 
3
3
  require 'rubygems'
4
4
 
@@ -7,7 +7,7 @@ spec = Gem::Specification.new do |s|
7
7
  s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
8
8
 
9
9
  s.name = 'lint_fu'
10
- s.version = '0.5.0'
10
+ s.version = '0.5.3'
11
11
  s.date = '2011-02-19'
12
12
 
13
13
  s.authors = ['Tony Spataro']
@@ -17,10 +17,18 @@ spec = Gem::Specification.new do |s|
17
17
  s.summary = %q{Security scanner that performs static analysis of Ruby code.}
18
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
19
 
20
+ s.add_runtime_dependency('trollop', [">= 1.16.0"])
20
21
  s.add_runtime_dependency('ruby_parser', ["~> 2.0"])
21
22
  s.add_runtime_dependency('ruby2ruby', ["~> 1.2"])
22
23
  s.add_runtime_dependency('activesupport', ["~> 2.3"])
24
+ s.add_runtime_dependency('builder', ["~> 2.1"])
25
+ s.add_runtime_dependency('RedCloth', ["~> 4.2"])
23
26
 
27
+ s.add_development_dependency('rake', [">= 0.8.7"])
28
+ s.add_development_dependency('ruby-debug', [">= 0.10.3"])
29
+ s.add_development_dependency('rspec', ["~> 1.3"])
30
+ s.add_development_dependency('flexmock', ["~> 0.8"])
31
+
24
32
  s.executables = ["lint_fu"]
25
33
 
26
34
  candidates = ['lint_fu.gemspec', 'MIT-LICENSE', 'README.rdoc'] +
@@ -28,8 +36,3 @@ spec = Gem::Specification.new do |s|
28
36
  Dir['bin/*']
29
37
  s.files = candidates.sort
30
38
  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 CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lint_fu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 0
10
- version: 0.5.0
9
+ - 3
10
+ version: 0.5.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tony Spataro
@@ -19,9 +19,25 @@ date: 2011-02-19 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: ruby_parser
22
+ name: trollop
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 87
30
+ segments:
31
+ - 1
32
+ - 16
33
+ - 0
34
+ version: 1.16.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ruby_parser
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
25
41
  none: false
26
42
  requirements:
27
43
  - - ~>
@@ -32,11 +48,11 @@ dependencies:
32
48
  - 0
33
49
  version: "2.0"
34
50
  type: :runtime
35
- version_requirements: *id001
51
+ version_requirements: *id002
36
52
  - !ruby/object:Gem::Dependency
37
53
  name: ruby2ruby
38
54
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
55
+ requirement: &id003 !ruby/object:Gem::Requirement
40
56
  none: false
41
57
  requirements:
42
58
  - - ~>
@@ -47,11 +63,11 @@ dependencies:
47
63
  - 2
48
64
  version: "1.2"
49
65
  type: :runtime
50
- version_requirements: *id002
66
+ version_requirements: *id003
51
67
  - !ruby/object:Gem::Dependency
52
68
  name: activesupport
53
69
  prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
70
+ requirement: &id004 !ruby/object:Gem::Requirement
55
71
  none: false
56
72
  requirements:
57
73
  - - ~>
@@ -62,7 +78,99 @@ dependencies:
62
78
  - 3
63
79
  version: "2.3"
64
80
  type: :runtime
65
- version_requirements: *id003
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: builder
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ hash: 1
91
+ segments:
92
+ - 2
93
+ - 1
94
+ version: "2.1"
95
+ type: :runtime
96
+ version_requirements: *id005
97
+ - !ruby/object:Gem::Dependency
98
+ name: RedCloth
99
+ prerelease: false
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ hash: 31
106
+ segments:
107
+ - 4
108
+ - 2
109
+ version: "4.2"
110
+ type: :runtime
111
+ version_requirements: *id006
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
114
+ prerelease: false
115
+ requirement: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 49
121
+ segments:
122
+ - 0
123
+ - 8
124
+ - 7
125
+ version: 0.8.7
126
+ type: :development
127
+ version_requirements: *id007
128
+ - !ruby/object:Gem::Dependency
129
+ name: ruby-debug
130
+ prerelease: false
131
+ requirement: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 49
137
+ segments:
138
+ - 0
139
+ - 10
140
+ - 3
141
+ version: 0.10.3
142
+ type: :development
143
+ version_requirements: *id008
144
+ - !ruby/object:Gem::Dependency
145
+ name: rspec
146
+ prerelease: false
147
+ requirement: &id009 !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ hash: 9
153
+ segments:
154
+ - 1
155
+ - 3
156
+ version: "1.3"
157
+ type: :development
158
+ version_requirements: *id009
159
+ - !ruby/object:Gem::Dependency
160
+ name: flexmock
161
+ prerelease: false
162
+ requirement: &id010 !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ~>
166
+ - !ruby/object:Gem::Version
167
+ hash: 27
168
+ segments:
169
+ - 0
170
+ - 8
171
+ version: "0.8"
172
+ type: :development
173
+ version_requirements: *id010
66
174
  description: This tool helps identify bugs in your code. It is Rails-centric but its modular design allows support for other application frameworks.
67
175
  email: code@tracker.xeger.net
68
176
  executables:
@@ -76,28 +184,36 @@ files:
76
184
  - README.rdoc
77
185
  - bin/lint_fu
78
186
  - 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
187
+ - lib/lint_fu/blessing.rb
85
188
  - lib/lint_fu/checker.rb
189
+ - lib/lint_fu/cli.rb
190
+ - lib/lint_fu/cli/command.rb
191
+ - lib/lint_fu/cli/prune.rb
192
+ - lib/lint_fu/cli/scan.rb
193
+ - lib/lint_fu/eidos.rb
194
+ - lib/lint_fu/eidos_builder.rb
195
+ - lib/lint_fu/eidos_container.rb
196
+ - lib/lint_fu/file_range.rb
86
197
  - lib/lint_fu/issue.rb
87
198
  - lib/lint_fu/mixins.rb
88
199
  - lib/lint_fu/mixins/file_class_methods.rb
89
200
  - lib/lint_fu/mixins/sexp_instance_methods.rb
90
201
  - lib/lint_fu/mixins/symbol_instance_methods.rb
91
- - lib/lint_fu/model_element.rb
92
- - lib/lint_fu/model_element_builder.rb
93
202
  - 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
203
+ - lib/lint_fu/plugins.rb
204
+ - lib/lint_fu/plugins/action_pack.rb
205
+ - lib/lint_fu/plugins/action_pack/controller_eidos.rb
206
+ - lib/lint_fu/plugins/action_pack/controller_eidos_builder.rb
207
+ - lib/lint_fu/plugins/active_record.rb
208
+ - lib/lint_fu/plugins/active_record/model_eidos.rb
209
+ - lib/lint_fu/plugins/active_record/model_eidos_builder.rb
210
+ - lib/lint_fu/plugins/rails.rb
211
+ - lib/lint_fu/plugins/rails/buggy_eager_load_checker.rb
212
+ - lib/lint_fu/plugins/rails/issue_builder.rb
213
+ - lib/lint_fu/plugins/rails/model_application.rb
214
+ - lib/lint_fu/plugins/rails/model_application_factory.rb
215
+ - lib/lint_fu/plugins/rails/sql_injection_checker.rb
216
+ - lib/lint_fu/plugins/rails/unsafe_find_checker.rb
101
217
  - lib/lint_fu/report.rb
102
218
  - lib/lint_fu/scan.rb
103
219
  - lib/lint_fu/source_control/git.rb