Class: Brakeman::HamlTemplateProcessor

Inherits:
TemplateProcessor show all
Defined in:
lib/brakeman/processors/haml_template_processor.rb

Overview

Processes HAML templates.

Constant Summary collapse

HAMLOUT =
s(:call, nil, :_hamlout)
HAML_BUFFER =
s(:call, HAMLOUT, :buffer)
HAML_HELPERS =
s(:colon2, s(:const, :Haml), :Helpers)
HAML_HELPERS2 =
s(:colon2, s(:colon3, :Haml), :Helpers)
JAVASCRIPT_FILTER =
s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Javascript)
COFFEE_FILTER =
s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Coffee)
ATTRIBUTE_BUILDER =
s(:colon2, s(:colon3, :Haml), :AttributeBuilder)
PRESERVE_METHODS =
[:find_and_preserve, :preserve]
ESCAPE_METHODS =
[
  :html_escape,
  :html_escape_without_haml_xss,
  :escape_once,
  :escape_once_without_haml_xss
]

Constants inherited from BaseProcessor

BaseProcessor::IGNORE

Constants included from Util

Util::ALL_COOKIES, Util::ALL_PARAMETERS, Util::COOKIES, Util::COOKIES_SEXP, Util::DIR_CONST, Util::LITERALS, Util::PARAMETERS, Util::PARAMS_SEXP, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_COOKIES, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::REQUEST_REQUEST_PARAMETERS, Util::SAFE_LITERAL, Util::SESSION, Util::SESSION_SEXP, Util::SIMPLE_LITERALS

Constants inherited from SexpProcessor

SexpProcessor::VERSION

Instance Attribute Summary

Attributes inherited from SexpProcessor

#context, #env, #expected

Instance Method Summary collapse

Methods inherited from TemplateProcessor

#add_escaped_output, #add_output, #normalize_output, #process, #process_escaped_output, #process_lasgn, #process_output

Methods inherited from BaseProcessor

#find_render_type, #ignore, #make_inline_render, #make_render, #make_render_in_view, #process_arglist, #process_attrasgn, #process_cdecl, #process_default, #process_dstr, #process_evstr, #process_file, #process_hash, #process_if, #process_ignore, #process_iter, #process_lasgn, #process_scope

Methods included from Util

#all_literals?, #array?, #block?, #call?, #camelize, #class_name, #constant?, #contains_class?, #cookies?, #dir_glob?, #false?, #hash?, #hash_access, #hash_insert, #hash_iterate, #hash_values, #integer?, #kwsplat?, #literal?, #make_call, #node_type?, #number?, #params?, #pluralize, #rails_version, #recurse_check?, #regexp?, #remove_kwsplat, #request_headers?, #request_value?, #result?, #safe_literal, #safe_literal?, #safe_literal_target?, #set_env_defaults, #sexp?, #simple_literal?, #string?, #string_interp?, #symbol?, #template_path_to_name, #true?, #underscore

Methods included from ProcessorHelper

#current_file, #process_all, #process_all!, #process_call_args, #process_call_defn?, #process_class, #process_module

Methods inherited from SexpProcessor

#in_context, #process, processors, #scope

Constructor Details

#initialize(*args) ⇒ HamlTemplateProcessor

Returns a new instance of HamlTemplateProcessor.



13
14
15
16
# File 'lib/brakeman/processors/haml_template_processor.rb', line 13

def initialize *args
  super
  @javascript = false
end

Instance Method Details

#buffer_append?(exp) ⇒ Boolean

_haml_out.buffer << …

Returns:

  • (Boolean)


31
32
33
34
35
# File 'lib/brakeman/processors/haml_template_processor.rb', line 31

def buffer_append? exp
  call? exp and
    exp.target == HAML_BUFFER and
    exp.method == :<<
end

#build_output_from_push_text(exp, default = :output) ⇒ Object

HAML likes to put interpolated values into _hamlout.push_text but we want to handle those individually



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/brakeman/processors/haml_template_processor.rb', line 64

def build_output_from_push_text exp, default = :output
  if string_interp? exp
    exp.map! do |e|
      if sexp? e
        if node_type? e, :evstr and e[1]
          e = e.value
        end

        get_pushed_value e, default
      else
        e
      end
    end
  end
end

#find_and_preserve?(exp) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/brakeman/processors/haml_template_processor.rb', line 39

def find_and_preserve? exp
  call? exp and
    PRESERVE_METHODS.include?(exp.method) and
    exp.first_arg
end

#fix_textareas?(exp) ⇒ Boolean

Returns:

  • (Boolean)


166
167
168
169
170
# File 'lib/brakeman/processors/haml_template_processor.rb', line 166

def fix_textareas? exp
  call? exp and
    exp.target == HAMLOUT and
    exp.method == :fix_textareas! 
end

#get_pushed_value(exp, default = :output) ⇒ Object



87
88
89
90
91
92
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
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/brakeman/processors/haml_template_processor.rb', line 87

def get_pushed_value exp, default = :output
  return exp unless sexp? exp

  case exp.node_type
  when :format
    exp.node_type = :output
    @current_template.add_output exp
    exp
  when :format_escaped
    exp.node_type = :escaped_output
    @current_template.add_output exp
    exp
  when :str, :ignore, :output, :escaped_output
    exp
  when :block, :rlist
    exp.map! { |e| get_pushed_value(e, default) }
  when :dstr
    build_output_from_push_text(exp, default)
  when :if
    clauses = [get_pushed_value(exp.then_clause, default), get_pushed_value(exp.else_clause, default)].compact

    if clauses.length > 1
      s(:or, *clauses).line(exp.line)
    else
      clauses.first
    end
  when :call
    if exp.method == :to_s or exp.method == :strip
      get_pushed_value(exp.target, default)
    elsif haml_helpers? exp.target and ESCAPE_METHODS.include? exp.method
      get_pushed_value(exp.first_arg, :escaped_output)
    elsif @javascript and (exp.method == :j or exp.method == :escape_javascript) # TODO: Remove - this is not safe
      get_pushed_value(exp.first_arg, :escaped_output)
    elsif find_and_preserve? exp or fix_textareas? exp
      get_pushed_value(exp.first_arg, default)
    elsif raw? exp
      get_pushed_value(exp.first_arg, :output)
    elsif hamlout_attributes? exp
      ignore # ignore _hamlout.attributes calls
    elsif exp.target.nil? and exp.method == :render
      #Process call to render()
      exp.arglist = process exp.arglist
      make_render_in_view exp
    elsif exp.method == :render_with_options
      if exp.target == JAVASCRIPT_FILTER or exp.target == COFFEE_FILTER
        @javascript = true
      end

      get_pushed_value(exp.first_arg, default)
      @javascript = false
    elsif haml_attribute_builder? exp
      ignore # probably safe... seems escaped by default?
    else
      add_output exp, default
    end
  else
    add_output exp, default
  end
end

#haml_attribute_builder?(exp) ⇒ Boolean

Returns:

  • (Boolean)


160
161
162
163
164
# File 'lib/brakeman/processors/haml_template_processor.rb', line 160

def haml_attribute_builder? exp
  call? exp and
    exp.target == ATTRIBUTE_BUILDER and
    exp.method == :build
end

#haml_helpers?(exp) ⇒ Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
# File 'lib/brakeman/processors/haml_template_processor.rb', line 147

def haml_helpers? exp
  # Sometimes its Haml::Helpers and
  # sometimes its ::Haml::Helpers
  exp == HAML_HELPERS or
    exp == HAML_HELPERS2
end

#hamlout_attributes?(exp) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
157
158
# File 'lib/brakeman/processors/haml_template_processor.rb', line 154

def hamlout_attributes? exp
  call? exp and
    exp.target == HAMLOUT and
    exp.method == :attributes
end

#process_block(exp) ⇒ Object

If inside an output stream, only return the final expression



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/brakeman/processors/haml_template_processor.rb', line 46

def process_block exp
  exp = exp.dup
  exp.shift

  exp.map! do |e|
    res = process e
    if res.empty?
      nil
    else
      res
    end
  end

  Sexp.new(:rlist).concat(exp).compact
end

#process_call(exp) ⇒ Object

Processes call, looking for template output



19
20
21
22
23
24
25
26
27
28
# File 'lib/brakeman/processors/haml_template_processor.rb', line 19

def process_call exp
  exp = process_default exp

  if buffer_append? exp
    output = normalize_output(exp.first_arg)
    res = get_pushed_value(output)
  end

  res or exp
end

#raw?(exp) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
175
# File 'lib/brakeman/processors/haml_template_processor.rb', line 172

def raw? exp
  call? exp and
    exp.method == :raw
end