Class: Brakeman::ModelProcessor

Inherits:
BaseProcessor show all
Defined in:
lib/brakeman/processors/model_processor.rb

Overview

Processes models. Puts results in tracker.models

Constant Summary collapse

ASSOCIATIONS =
Set[:belongs_to, :has_one, :has_many, :has_and_belongs_to_many]

Constants included from Util

Util::ALL_PARAMETERS, Util::COOKIES, Util::PARAMETERS, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::SESSION

Constants inherited from SexpProcessor

SexpProcessor::VERSION

Instance Attribute Summary

Attributes inherited from BaseProcessor

#ignore

Attributes inherited from SexpProcessor

#context, #env, #expected

Instance Method Summary collapse

Methods inherited from BaseProcessor

#find_render_type, #make_render, #make_render_in_view, #process_arglist, #process_attrasgn, #process_block, #process_default, #process_dstr, #process_evstr, #process_hash, #process_if, #process_ignore, #process_iter, #process_lasgn, #process_scope

Methods included from Util

#array?, #call?, #camelize, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #node_type?, #number?, #params?, #pluralize, #regexp?, #request_env?, #request_value?, #result?, #set_env_defaults, #sexp?, #string?, #symbol?, #table_to_csv, #true?, #truncate_table, #underscore

Methods included from ProcessorHelper

#class_name, #process_all, #process_module

Methods inherited from SexpProcessor

#error_handler, #in_context, #process, #process_dummy, #scope

Constructor Details

#initialize(tracker) ⇒ ModelProcessor

Returns a new instance of ModelProcessor.



8
9
10
11
12
13
14
# File 'lib/brakeman/processors/model_processor.rb', line 8

def initialize tracker
  super 
  @model = nil
  @current_method = nil
  @visibility = :public
  @file_name = nil
end

Instance Method Details

#process_call(exp) ⇒ Object

Handle calls outside of methods, such as include, attr_accessible, private, etc.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/brakeman/processors/model_processor.rb', line 55

def process_call exp
  return exp unless @model
  target = exp.target
  if sexp? target
    target = process target
  end

  method = exp.method
  args = exp.args

  #Methods called inside class definition
  #like attr_* and other settings
  if @current_method.nil? and target.nil?
    if args.empty?
      case method
      when :private, :protected, :public
        @visibility = method
      when :attr_accessible
        @model[:attr_accessible] ||= []
      else
        #??
      end
    else
      case method
      when :include
        @model[:includes] << class_name(args.first) if @model
      when :attr_accessible
        @model[:attr_accessible] ||= []
        args = args.map do |e|
          e[1]
        end

        @model[:attr_accessible].concat args
      else
        if @model
          if ASSOCIATIONS.include? method
            @model[:associations][method] ||= []
            @model[:associations][method].concat exp.args
          else
            @model[:options][method] ||= []
            @model[:options][method] << exp.arglist
          end
        end
      end
    end
    ignore
  else
    call = Sexp.new :call, target, method, process(exp.arglist)
    call.line(exp.line)
    call
  end
end

#process_class(exp) ⇒ Object

s(:class, NAME, PARENT, s(:scope …))



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/brakeman/processors/model_processor.rb', line 23

def process_class exp
  name = class_name exp.class_name

  if @model
    Brakeman.debug "[Notice] Skipping inner class: #{name}"
    ignore
  else
    begin
      parent = class_name exp.parent_name
    rescue StandardError => e
      Brakeman.debug e
      parent = nil
    end

    @model = { :name => name,
      :parent => parent,
      :includes => [],
      :public => {},
      :private => {},
      :protected => {},
      :options => {},
      :associations => {},
      :file => @file_name }
    @tracker.models[@model[:name]] = @model
    res = process exp.body
    @model = nil
    res
  end
end

#process_defn(exp) ⇒ Object

Add method definition to tracker



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/brakeman/processors/model_processor.rb', line 109

def process_defn exp
  return exp unless @model
  name = exp.method_name

  @current_method = name
  res = Sexp.new :methdef, name, exp[2], process(exp.body.value)
  res.line(exp.line)
  @current_method = nil
  if @model
    list = @model[@visibility]
    list[name] = res
  end
  res
end

#process_defs(exp) ⇒ Object

Add method definition to tracker



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/brakeman/processors/model_processor.rb', line 125

def process_defs exp
  return exp unless @model
  name = exp.method_name

  if exp[1].node_type == :self
    target = @model[:name]
  else
    target = class_name exp[1]
  end

  @current_method = name
  res = Sexp.new :selfdef, target, name, exp[3], process(exp.body.value)
  res.line(exp.line)
  @current_method = nil
  if @model
    @model[@visibility][name] = res unless @model.nil?
  end
  res
end

#process_model(src, file_name = nil) ⇒ Object

Process model source



17
18
19
20
# File 'lib/brakeman/processors/model_processor.rb', line 17

def process_model src, file_name = nil
  @file_name = file_name
  process src
end