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 inherited from BaseProcessor

BaseProcessor::IGNORE

Constants included from Util

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

Constants inherited from SexpProcessor

SexpProcessor::VERSION

Instance Attribute Summary

Attributes inherited from SexpProcessor

#context, #env, #expected

Instance Method Summary collapse

Methods inherited from BaseProcessor

#find_render_type, #ignore, #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?, #block?, #call?, #camelize, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #make_call, #node_type?, #number?, #params?, #pluralize, #regexp?, #relative_path, #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_all!, #process_call_args, #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.



50
51
52
53
54
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
107
108
# File 'lib/brakeman/processors/model_processor.rb', line 50

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

  method = exp.method
  first_arg = exp.first_arg

  #Methods called inside class definition
  #like attr_* and other settings
  if @current_method.nil? and target.nil?
    if first_arg.nil?
      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(first_arg) if @model
      when :attr_accessible
        @model[:attr_accessible] ||= []
        args = []

        exp.each_arg do |e|
          if node_type? e, :lit
            args << e.value
          elsif hash? e
            @model[:options][:role_accessible] ||= []
            @model[:options][:role_accessible].concat args
          end
        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.line(exp.line)
          end
        end
      end
    end
    ignore
  else
    call = make_call target, method, process_all!(exp.args)
    call.line(exp.line)
    call
  end
end

#process_class(exp) ⇒ Object

s(:class, NAME, PARENT, BODY)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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
    parent = class_name exp.parent_name

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

#process_defn(exp) ⇒ Object

Add method definition to tracker



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

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

  @current_method = name
  res = Sexp.new :methdef, name, exp.formal_args, *process_all!(exp.body)
  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



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

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.formal_args, *process_all!(exp.body)
  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