Class: Brakeman::ModelProcessor

Inherits:
BaseProcessor
  • Object
show all
Includes:
ModuleHelper
Defined in:
lib/brakeman/processors/model_processor.rb

Overview

Processes models. Puts results in tracker.models

Instance Method Summary collapse

Methods included from ModuleHelper

#handle_class, #handle_module, #make_defs, #process_defn, #process_defs, #process_sclass

Constructor Details

#initialize(tracker) ⇒ ModelProcessor

Returns a new instance of ModelProcessor.



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

def initialize tracker
  super
  @current_class = nil
  @current_method = nil
  @current_module = nil
  @visibility = :public
  @current_file = nil
end

Instance Method Details

#add_enum_method(call) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/brakeman/processors/model_processor.rb', line 93

def add_enum_method call
  if call.second_arg.nil?
    # Rails < 7.1 syntax: enum status: { active: 0, archived: 1 }
    arg = call.first_arg
    return unless hash? arg
    return unless symbol? arg[1]

    enum_name = arg[1].value # first key
    enums = arg[2] # first value
  else
    # Rails >= 7.1 syntax: enum :status, { active: 0, archived: 1 }
    first_arg = call.first_arg
    second_arg = call.second_arg
    return unless symbol? first_arg
    return unless hash? second_arg or array? second_arg

    enum_name = first_arg.value
    enums = second_arg
  end

  enums_name = pluralize(enum_name.to_s).to_sym

  call_line = call.line

  if hash? enums
    enum_values = enums
  elsif array? enums
    # Build hash for enum values like Rails does
    enum_values = s(:hash).line(call_line)

    enums.each_sexp.with_index do |v, index|
      enum_values << v
      enum_values << s(:lit, index).line(call_line)
    end
  end

  enum_method = s(:defn, enum_name, s(:args), safe_literal(call_line))
  enums_method = s(:defs, s(:self), enums_name, s(:args), enum_values)

  @current_class.add_method :public, enum_name, enum_method, @current_file
  @current_class.add_method :public, enums_name, enums_method, @current_file
end

#process_call(exp) ⇒ Object

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



44
45
46
47
48
49
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
# File 'lib/brakeman/processors/model_processor.rb', line 44

def process_call exp
  return exp unless @current_class
  return exp if process_call_defn? exp

  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
        @current_class.set_attr_accessible
      else
        #??
      end
    else
      case method
      when :include
        @current_class.add_include class_name(first_arg) if @current_class
      when :attr_accessible
        @current_class.set_attr_accessible exp
      when :attr_protected
        @current_class.set_attr_protected exp
      when :enum
        add_enum_method exp
      else
        if @current_class
          @current_class.add_option method, exp
        end
      end
    end

    exp
  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)



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/brakeman/processors/model_processor.rb', line 25

def process_class exp
  name = class_name(exp.class_name)

  #If inside an inner class we treat it as a library.
  if @current_class
    Brakeman.debug "Treating inner class as library: #{name}"
    Brakeman::LibraryProcessor.new(@tracker).process_library exp, @current_file
    return exp
  end

  handle_class exp, @tracker.models, Brakeman::Model
end

#process_model(src, current_file = @current_file) ⇒ Object

Process model source



19
20
21
22
# File 'lib/brakeman/processors/model_processor.rb', line 19

def process_model src, current_file = @current_file
  @current_file = current_file
  process src
end

#process_module(exp) ⇒ Object



38
39
40
# File 'lib/brakeman/processors/model_processor.rb', line 38

def process_module exp
  handle_module exp, Brakeman::Model
end