Class: Brakeman::HamlTemplateProcessor

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

Overview

Processes HAML templates.

Constant Summary collapse

HAML_FORMAT_METHOD =
/format_script_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)/
HAML_HELPERS =
s(:colon2, s(:const, :Haml), :Helpers)
JAVASCRIPT_FILTER =
s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Javascript)
COFFEE_FILTER =
s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Coffee)

Constants inherited from BaseProcessor

BaseProcessor::IGNORE

Constants included from Util

Util::ALL_COOKIES, Util::ALL_PARAMETERS, Util::COOKIES, Util::COOKIES_SEXP, Util::PARAMETERS, Util::PARAMS_SEXP, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_COOKIES, 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 TemplateProcessor

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

Methods inherited from BaseProcessor

#find_render_type, #ignore, #initialize, #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

#array?, #block?, #call?, #camelize, #class_name, #constant?, #contains_class?, #context_for, #cookies?, #false?, #file_by_name, #file_for, #github_url, #hash?, #hash_access, #hash_insert, #hash_iterate, #integer?, #make_call, #node_type?, #number?, #params?, #pluralize, #rails_version, #regexp?, #relative_path, #request_env?, #request_value?, #result?, #set_env_defaults, #sexp?, #string?, #string_interp?, #symbol?, #table_to_csv, #template_path_to_name, #true?, #truncate_table, #underscore

Methods included from ProcessorHelper

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

Methods inherited from SexpProcessor

#in_context, #initialize, #process, processors, #scope

Constructor Details

This class inherits a constructor from Brakeman::TemplateProcessor

Instance Method Details

#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



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/brakeman/processors/haml_template_processor.rb', line 140

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

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

Gets outputs from values interpolated into _hamlout.push_text



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/brakeman/processors/haml_template_processor.rb', line 157

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, :dstr
    exp.map! { |e| get_pushed_value e }
  when :if
    clauses = [get_pushed_value(exp.then_clause), get_pushed_value(exp.else_clause)].compact

    if clauses.length > 1
      s(:or, *clauses)
    else
      clauses.first
    end
  else
    if call? exp and exp.target == HAML_HELPERS and exp.method == :html_escape
      add_escaped_output exp.first_arg
    elsif @javascript and call? exp and (exp.method == :j or exp.method == :escape_javascript)
      add_escaped_output exp.first_arg
    else
      add_output exp, default
    end
  end
end

#is_buffer_target?(exp) ⇒ Boolean

Checks if the buffer is the target in a method call Sexp. TODO: Test this

Returns:

  • (Boolean)


131
132
133
134
135
136
# File 'lib/brakeman/processors/haml_template_processor.rb', line 131

def is_buffer_target? exp
  exp.node_type == :call and
  node_type? exp.target, :lvar and
  exp.target.value == :_hamlout and
  exp.method == :buffer
end

#process_block(exp) ⇒ Object

If inside an output stream, only return the final expression



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/brakeman/processors/haml_template_processor.rb', line 106

def process_block exp
  exp = exp.dup
  exp.shift
  if @inside_concat
    @inside_concat = false
    exp[0..-2].each do |e|
      process e
    end
    @inside_concat = true
    process exp[-1]
  else
    exp.map! do |e|
      res = process e
      if res.empty?
        nil
      else
        res
      end
    end
    Sexp.new(:rlist).concat(exp).compact
  end
end

#process_call(exp) ⇒ Object

Processes call, looking for template output



11
12
13
14
15
16
17
18
19
20
21
22
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
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
# File 'lib/brakeman/processors/haml_template_processor.rb', line 11

def process_call exp
  target = exp.target
  if sexp? target
    target = process target
  end

  method = exp.method

  if (call? target and target.method == :_hamlout)
    res = case method
          when :adjust_tabs, :rstrip!, :attributes #Check attributes, maybe?
            ignore
          when :options, :buffer
            exp
          when :open_tag
            process_call_args exp
          else
            arg = exp.first_arg

            if arg
              @inside_concat = true
              exp.first_arg = process(arg)
              out = normalize_output(exp.first_arg)
              @inside_concat = false
            else
              raise "Empty _hamlout.#{method}()?"
            end

            if string? out
              ignore
            else
              r = case method.to_s
                  when "push_text"
                    build_output_from_push_text(out)
                  when HAML_FORMAT_METHOD
                    if $4 == "true"
                      if string_interp? out
                        build_output_from_push_text(out, :escaped_output)
                      else
                        Sexp.new :format_escaped, out
                      end
                    else
                      if string_interp? out
                        build_output_from_push_text(out)
                      else
                        Sexp.new :format, out
                      end
                    end

                  else
                    raise "Unrecognized action on _hamlout: #{method}"
                  end

              @javascript = false
              r
            end
          end

    res.line(exp.line)
    res

    #_hamlout.buffer <<
    #This seems to be used rarely, but directly appends args to output buffer.
    #Has something to do with values of blocks?
  elsif sexp? target and method == :<< and is_buffer_target? target
    @inside_concat = true
    exp.first_arg = process(exp.first_arg)
    out = normalize_output(exp.first_arg)
    @inside_concat = false

    if out.node_type == :str #ignore plain strings
      ignore
    else
      add_output out
    end
  elsif target == nil and method == :render
    #Process call to render()
    exp.arglist = process exp.arglist
    make_render_in_view exp
  elsif target == nil and method == :find_and_preserve and exp.first_arg
    process exp.first_arg
  elsif method == :render_with_options
    if target == JAVASCRIPT_FILTER or target == COFFEE_FILTER
      @javascript = true
    end

    process exp.first_arg
  else
    exp.target = target
    exp.arglist = process exp.arglist
    exp
  end
end