lint_fu 0.5.0 → 0.5.3
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.
- data/README.rdoc +4 -2
- data/bin/lint_fu +2 -86
- data/lib/lint_fu/blessing.rb +40 -0
- data/lib/lint_fu/checker.rb +49 -3
- data/lib/lint_fu/cli/command.rb +48 -0
- data/lib/lint_fu/cli/prune.rb +78 -0
- data/lib/lint_fu/cli/scan.rb +78 -0
- data/lib/lint_fu/cli.rb +52 -0
- data/lib/lint_fu/eidos.rb +35 -0
- data/lib/lint_fu/{model_element_builder.rb → eidos_builder.rb} +8 -3
- data/lib/lint_fu/eidos_container.rb +25 -0
- data/lib/lint_fu/file_range.rb +43 -0
- data/lib/lint_fu/mixins/sexp_instance_methods.rb +57 -9
- data/lib/lint_fu/parser.rb +1 -2
- data/lib/lint_fu/plugins/action_pack/controller_eidos.rb +7 -0
- data/lib/lint_fu/{action_pack/model_controller_builder.rb → plugins/action_pack/controller_eidos_builder.rb} +6 -6
- data/lib/lint_fu/plugins/action_pack.rb +2 -0
- data/lib/lint_fu/{active_record/model_model.rb → plugins/active_record/model_eidos.rb} +3 -3
- data/lib/lint_fu/{active_record/model_model_builder.rb → plugins/active_record/model_eidos_builder.rb} +17 -11
- data/lib/lint_fu/plugins/active_record.rb +2 -0
- data/lib/lint_fu/{rails → plugins/rails}/buggy_eager_load_checker.rb +6 -5
- data/lib/lint_fu/{rails/scan_builder.rb → plugins/rails/issue_builder.rb} +9 -16
- data/lib/lint_fu/plugins/rails/model_application.rb +21 -0
- data/lib/lint_fu/plugins/rails/model_application_factory.rb +31 -0
- data/lib/lint_fu/{rails → plugins/rails}/sql_injection_checker.rb +9 -5
- data/lib/lint_fu/{rails → plugins/rails}/unsafe_find_checker.rb +17 -30
- data/lib/lint_fu/plugins/rails.rb +29 -0
- data/lib/lint_fu/plugins.rb +11 -0
- data/lib/lint_fu/scan.rb +1 -49
- data/lib/lint_fu.rb +13 -8
- data/lint_fu.gemspec +10 -7
- metadata +140 -24
- data/lib/lint_fu/action_pack/model_controller.rb +0 -7
- data/lib/lint_fu/action_pack.rb +0 -2
- data/lib/lint_fu/active_record.rb +0 -2
- data/lib/lint_fu/model_element.rb +0 -48
- data/lib/lint_fu/rails/model_application.rb +0 -16
- data/lib/lint_fu/rails/model_application_builder.rb +0 -32
- 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
|
-
|
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? &&
|
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::
|
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
|
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
|
-
|
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]
|
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
|
-
|
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 '
|
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/
|
20
|
-
require 'lint_fu/
|
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
|
-
#
|
32
|
+
# source control providers
|
29
33
|
require 'lint_fu/source_control/git'
|
30
34
|
|
31
|
-
#
|
32
|
-
require 'lint_fu/
|
33
|
-
|
34
|
-
|
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.
|
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:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
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:
|
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: *
|
51
|
+
version_requirements: *id002
|
36
52
|
- !ruby/object:Gem::Dependency
|
37
53
|
name: ruby2ruby
|
38
54
|
prerelease: false
|
39
|
-
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: *
|
66
|
+
version_requirements: *id003
|
51
67
|
- !ruby/object:Gem::Dependency
|
52
68
|
name: activesupport
|
53
69
|
prerelease: false
|
54
|
-
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: *
|
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/
|
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/
|
95
|
-
- lib/lint_fu/
|
96
|
-
- lib/lint_fu/
|
97
|
-
- lib/lint_fu/
|
98
|
-
- lib/lint_fu/
|
99
|
-
- lib/lint_fu/
|
100
|
-
- lib/lint_fu/
|
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
|