brakeman-lib 4.4.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +63 -0
  3. data/README.md +6 -7
  4. data/lib/brakeman.rb +7 -0
  5. data/lib/brakeman/app_tree.rb +34 -22
  6. data/lib/brakeman/call_index.rb +54 -15
  7. data/lib/brakeman/checks.rb +7 -7
  8. data/lib/brakeman/checks/base_check.rb +75 -56
  9. data/lib/brakeman/checks/check_content_tag.rb +12 -0
  10. data/lib/brakeman/checks/check_cookie_serialization.rb +22 -0
  11. data/lib/brakeman/checks/check_cross_site_scripting.rb +15 -10
  12. data/lib/brakeman/checks/check_default_routes.rb +5 -0
  13. data/lib/brakeman/checks/check_deserialize.rb +49 -0
  14. data/lib/brakeman/checks/check_dynamic_finders.rb +1 -1
  15. data/lib/brakeman/checks/check_evaluation.rb +0 -1
  16. data/lib/brakeman/checks/check_execute.rb +44 -1
  17. data/lib/brakeman/checks/check_file_access.rb +7 -1
  18. data/lib/brakeman/checks/check_force_ssl.rb +27 -0
  19. data/lib/brakeman/checks/check_header_dos.rb +2 -2
  20. data/lib/brakeman/checks/check_i18n_xss.rb +2 -2
  21. data/lib/brakeman/checks/check_jruby_xml.rb +2 -2
  22. data/lib/brakeman/checks/check_json_parsing.rb +7 -2
  23. data/lib/brakeman/checks/check_link_to_href.rb +6 -1
  24. data/lib/brakeman/checks/check_mail_to.rb +1 -1
  25. data/lib/brakeman/checks/check_mime_type_dos.rb +2 -2
  26. data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -1
  27. data/lib/brakeman/checks/check_model_attributes.rb +12 -50
  28. data/lib/brakeman/checks/check_model_serialize.rb +1 -1
  29. data/lib/brakeman/checks/check_nested_attributes_bypass.rb +4 -4
  30. data/lib/brakeman/checks/check_reverse_tabnabbing.rb +54 -0
  31. data/lib/brakeman/checks/check_sanitize_methods.rb +2 -2
  32. data/lib/brakeman/checks/check_secrets.rb +1 -1
  33. data/lib/brakeman/checks/check_send.rb +0 -1
  34. data/lib/brakeman/checks/check_session_manipulation.rb +0 -1
  35. data/lib/brakeman/checks/check_session_settings.rb +15 -12
  36. data/lib/brakeman/checks/check_simple_format.rb +5 -0
  37. data/lib/brakeman/checks/check_skip_before_filter.rb +1 -1
  38. data/lib/brakeman/checks/check_sql.rb +27 -20
  39. data/lib/brakeman/checks/check_validation_regex.rb +1 -1
  40. data/lib/brakeman/checks/check_xml_dos.rb +2 -2
  41. data/lib/brakeman/checks/check_yaml_parsing.rb +10 -18
  42. data/lib/brakeman/differ.rb +16 -28
  43. data/lib/brakeman/file_parser.rb +6 -8
  44. data/lib/brakeman/file_path.rb +85 -0
  45. data/lib/brakeman/options.rb +7 -0
  46. data/lib/brakeman/parsers/haml_embedded.rb +44 -0
  47. data/lib/brakeman/parsers/slim_embedded.rb +44 -0
  48. data/lib/brakeman/parsers/template_parser.rb +8 -8
  49. data/lib/brakeman/processor.rb +4 -5
  50. data/lib/brakeman/processors/alias_processor.rb +49 -7
  51. data/lib/brakeman/processors/base_processor.rb +10 -7
  52. data/lib/brakeman/processors/controller_alias_processor.rb +10 -7
  53. data/lib/brakeman/processors/controller_processor.rb +9 -13
  54. data/lib/brakeman/processors/gem_processor.rb +10 -2
  55. data/lib/brakeman/processors/haml_template_processor.rb +92 -123
  56. data/lib/brakeman/processors/lib/call_conversion_helper.rb +4 -0
  57. data/lib/brakeman/processors/lib/find_all_calls.rb +27 -4
  58. data/lib/brakeman/processors/lib/find_call.rb +3 -64
  59. data/lib/brakeman/processors/lib/module_helper.rb +8 -8
  60. data/lib/brakeman/processors/lib/processor_helper.rb +3 -3
  61. data/lib/brakeman/processors/lib/rails2_config_processor.rb +4 -4
  62. data/lib/brakeman/processors/lib/rails2_route_processor.rb +2 -2
  63. data/lib/brakeman/processors/lib/rails3_config_processor.rb +3 -3
  64. data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -2
  65. data/lib/brakeman/processors/lib/render_helper.rb +2 -2
  66. data/lib/brakeman/processors/lib/render_path.rb +18 -1
  67. data/lib/brakeman/processors/library_processor.rb +5 -5
  68. data/lib/brakeman/processors/model_processor.rb +4 -5
  69. data/lib/brakeman/processors/output_processor.rb +5 -0
  70. data/lib/brakeman/processors/slim_template_processor.rb +16 -0
  71. data/lib/brakeman/processors/template_alias_processor.rb +32 -5
  72. data/lib/brakeman/processors/template_processor.rb +14 -10
  73. data/lib/brakeman/report.rb +3 -3
  74. data/lib/brakeman/report/ignore/config.rb +2 -3
  75. data/lib/brakeman/report/ignore/interactive.rb +2 -2
  76. data/lib/brakeman/report/pager.rb +1 -0
  77. data/lib/brakeman/report/report_base.rb +51 -6
  78. data/lib/brakeman/report/report_codeclimate.rb +3 -3
  79. data/lib/brakeman/report/report_hash.rb +1 -1
  80. data/lib/brakeman/report/report_html.rb +2 -2
  81. data/lib/brakeman/report/report_json.rb +1 -24
  82. data/lib/brakeman/report/report_table.rb +20 -4
  83. data/lib/brakeman/report/report_tabs.rb +1 -1
  84. data/lib/brakeman/report/report_text.rb +2 -2
  85. data/lib/brakeman/rescanner.rb +13 -12
  86. data/lib/brakeman/scanner.rb +24 -18
  87. data/lib/brakeman/tracker.rb +35 -7
  88. data/lib/brakeman/tracker/collection.rb +4 -3
  89. data/lib/brakeman/tracker/config.rb +44 -48
  90. data/lib/brakeman/tracker/constants.rb +2 -1
  91. data/lib/brakeman/util.rb +18 -147
  92. data/lib/brakeman/version.rb +1 -1
  93. data/lib/brakeman/warning.rb +27 -13
  94. data/lib/brakeman/warning_codes.rb +4 -0
  95. data/lib/ruby_parser/bm_sexp.rb +1 -1
  96. data/lib/ruby_parser/bm_sexp_processor.rb +1 -0
  97. metadata +58 -43
@@ -15,11 +15,12 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
15
15
  super()
16
16
  @last = nil
17
17
  @tracker = tracker
18
- @current_template = @current_module = @current_class = @current_method = @file_name = nil
18
+ @app_tree = tracker.app_tree if tracker
19
+ @current_template = @current_module = @current_class = @current_method = @current_file = nil
19
20
  end
20
21
 
21
- def process_file exp, file_name
22
- @file_name = file_name
22
+ def process_file exp, current_file
23
+ @current_file = current_file
23
24
  process exp
24
25
  end
25
26
 
@@ -113,6 +114,8 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
113
114
  exp.unshift :rlist
114
115
  end
115
116
 
117
+ alias process_rlist process_block
118
+
116
119
  #Processes the inside of an interpolated String.
117
120
  def process_evstr exp
118
121
  exp = exp.dup
@@ -182,7 +185,7 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
182
185
  if @tracker
183
186
  @tracker.add_constant exp.lhs,
184
187
  exp.rhs,
185
- :file => current_file_name,
188
+ :file => current_file,
186
189
  :module => @current_module,
187
190
  :class => @current_class,
188
191
  :method => @current_method
@@ -234,8 +237,8 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
234
237
  elsif first_arg.is_a? Symbol or first_arg.is_a? String
235
238
  type = :action
236
239
  value = Sexp.new(:lit, first_arg.to_sym)
237
- elsif first_arg.nil?
238
- type = :default
240
+ elsif first_arg.nil?
241
+ type = :default
239
242
  elsif not hash? first_arg
240
243
  type = :action
241
244
  value = first_arg
@@ -287,7 +290,7 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
287
290
  template_name = "#@current_method/inline@#{value.line}:#{class_or_module}".to_sym
288
291
  type, ast = Brakeman::TemplateParser.parse_inline_erb(@tracker, value.value)
289
292
  ast = ast.deep_clone(value.line)
290
- @tracker.processor.process_template(template_name, ast, type, nil, @file_name)
293
+ @tracker.processor.process_template(template_name, ast, type, nil, @current_file)
291
294
  @tracker.processor.process_template_alias(@tracker.templates[template_name])
292
295
 
293
296
  return s(:lit, template_name), options
@@ -11,22 +11,22 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
11
11
  #If only_method is specified, only that method will be processed,
12
12
  #other methods will be skipped.
13
13
  #This is for rescanning just a single action.
14
- def initialize app_tree, tracker, only_method = nil
14
+ def initialize tracker, only_method = nil
15
15
  super tracker
16
- @app_tree = app_tree
16
+ @app_tree = tracker.app_tree
17
17
  @only_method = only_method
18
18
  @rendered = false
19
19
  @current_class = @current_module = @current_method = nil
20
20
  @method_cache = {} #Cache method lookups
21
21
  end
22
22
 
23
- def process_controller name, src, file_name
23
+ def process_controller name, src, current_file
24
24
  if not node_type? src, :class
25
25
  Brakeman.debug "#{name} is not a class, it's a #{src.node_type}"
26
26
  return
27
27
  else
28
28
  @current_class = name
29
- @file_name = file_name
29
+ @current_file = @app_tree.file_path(current_file)
30
30
 
31
31
  process_default src
32
32
 
@@ -37,6 +37,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
37
37
  #Process modules mixed into the controller, in case they contain actions.
38
38
  def process_mixins
39
39
  controller = @tracker.controllers[@current_class]
40
+ original_file = @current_file
40
41
 
41
42
  controller.includes.each do |i|
42
43
  mixin = @tracker.libs[i]
@@ -49,7 +50,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
49
50
  methods.each do |name|
50
51
  #Need to process the method like it was in a controller in order
51
52
  #to get the renders set
52
- processor = Brakeman::ControllerProcessor.new(@app_tree, @tracker)
53
+ processor = Brakeman::ControllerProcessor.new(@tracker, mixin.file)
53
54
  method = mixin.get_method(name)[:src].deep_clone
54
55
 
55
56
  if node_type? method, :defn
@@ -59,11 +60,13 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
59
60
  method = processor.process method
60
61
  end
61
62
 
62
- @file_name = mixin.file
63
+ @current_file = mixin.file
63
64
  #Then process it like any other method in the controller
64
65
  process method
65
66
  end
66
67
  end
68
+ ensure
69
+ @current_file = original_file
67
70
  end
68
71
 
69
72
  #Skip it, must be an inner class
@@ -187,7 +190,7 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
187
190
  end
188
191
  end
189
192
 
190
- render_path = Brakeman::RenderPath.new.add_controller_render(@current_class, @current_method, line, relative_path(@file_name))
193
+ render_path = Brakeman::RenderPath.new.add_controller_render(@current_class, @current_method, line, @current_file)
191
194
  super name, args, render_path, line
192
195
  end
193
196
 
@@ -8,20 +8,16 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
8
8
 
9
9
  FORMAT_HTML = Sexp.new(:call, Sexp.new(:lvar, :format), :html)
10
10
 
11
- def initialize app_tree, tracker
11
+ def initialize tracker, current_file = nil
12
12
  super(tracker)
13
- @app_tree = app_tree
14
- @current_class = nil
15
- @current_method = nil
16
- @current_module = nil
17
13
  @visibility = :public
18
- @file_name = nil
14
+ @current_file = current_file
19
15
  @concerns = Set.new
20
16
  end
21
17
 
22
18
  #Use this method to process a Controller
23
- def process_controller src, file_name = nil
24
- @file_name = file_name
19
+ def process_controller src, current_file = @current_file
20
+ @current_file = current_file
25
21
  process src
26
22
  end
27
23
 
@@ -35,7 +31,7 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
35
31
  #a real controller, so we can't take this shortcut.
36
32
  if @current_class and @current_class.name.to_s.end_with? "Controller"
37
33
  Brakeman.debug "[Notice] Treating inner class as library: #{name}"
38
- Brakeman::LibraryProcessor.new(@tracker).process_library exp, @file_name
34
+ Brakeman::LibraryProcessor.new(@tracker).process_library exp, @current_file
39
35
  return exp
40
36
  end
41
37
 
@@ -196,8 +192,8 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
196
192
 
197
193
  filter_name = ("fake_filter" + rand.to_s[/\d+$/]).to_sym
198
194
  args = exp.block_call.arglist
199
- args.insert(1, Sexp.new(:lit, filter_name))
200
- before_filter_call = make_call(nil, :before_filter, args)
195
+ args.insert(1, Sexp.new(:lit, filter_name).line(exp.line))
196
+ before_filter_call = make_call(nil, :before_filter, args).line(exp.line)
201
197
 
202
198
  if exp.block_args.length > 1
203
199
  block_variable = exp.block_args[1]
@@ -214,9 +210,9 @@ class Brakeman::ControllerProcessor < Brakeman::BaseProcessor
214
210
  #Build Sexp for filter method
215
211
  body = Sexp.new(:lasgn,
216
212
  block_variable,
217
- Sexp.new(:call, Sexp.new(:const, @current_class.name), :new))
213
+ Sexp.new(:call, Sexp.new(:const, @current_class.name).line(exp.line), :new).line(exp.line)).line(exp.line)
218
214
 
219
- filter_method = Sexp.new(:defn, filter_name, Sexp.new(:args), body).concat(block_inner).line(exp.line)
215
+ filter_method = Sexp.new(:defn, filter_name, Sexp.new(:args).line(exp.line), body).concat(block_inner).line(exp.line)
220
216
 
221
217
  vis = @visibility
222
218
  @visibility = :private
@@ -29,6 +29,14 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
29
29
  @tracker.config.set_rails_version
30
30
  end
31
31
 
32
+ # Known issue: Brakeman does not yet support `gem` calls with multiple
33
+ # "version requirements". Consider the following example from the ruby docs:
34
+ #
35
+ # gem 'rake', '>= 1.1.a', '< 2'
36
+ #
37
+ # We are assuming that `second_arg` (eg. '>= 1.1.a') is the only requirement.
38
+ # Perhaps we should instantiate an array of `::Gem::Requirement`s or even a
39
+ # `::Gem::Dependency` and pass that to `Tracker::Config#add_gem`?
32
40
  def process_call exp
33
41
  if exp.target == nil
34
42
  if exp.method == :gem
@@ -51,8 +59,8 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
51
59
  end
52
60
  end
53
61
  elsif @inside_gemspec and exp.method == :add_dependency
54
- if string? exp.first_arg and string? exp.last_arg
55
- @tracker.config.add_gem exp.first_arg.value, exp.last_arg.value, @gemspec, exp.line
62
+ if string? exp.first_arg and string? exp.second_arg
63
+ @tracker.config.add_gem exp.first_arg.value, exp.second_arg.value, @gemspec, exp.line
56
64
  end
57
65
  end
58
66
 
@@ -2,137 +2,60 @@ require 'brakeman/processors/template_processor'
2
2
 
3
3
  #Processes HAML templates.
4
4
  class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
5
- HAML_FORMAT_METHOD = /format_script_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)_(true|false)/
5
+ HAMLOUT = s(:call, nil, :_hamlout)
6
+ HAML_BUFFER = s(:call, HAMLOUT, :buffer)
6
7
  HAML_HELPERS = s(:colon2, s(:const, :Haml), :Helpers)
8
+ HAML_HELPERS2 = s(:colon2, s(:colon3, :Haml), :Helpers)
7
9
  JAVASCRIPT_FILTER = s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Javascript)
8
10
  COFFEE_FILTER = s(:colon2, s(:colon2, s(:const, :Haml), :Filters), :Coffee)
9
11
 
12
+ def initialize *args
13
+ super
14
+ @javascript = false
15
+ end
16
+
10
17
  #Processes call, looking for template output
11
18
  def process_call exp
12
- target = exp.target
13
- if sexp? target
14
- target = process target
19
+ exp = process_default exp
20
+
21
+ if buffer_append? exp
22
+ output = normalize_output(exp.first_arg)
23
+ res = get_pushed_value(output)
15
24
  end
16
25
 
17
- method = exp.method
18
-
19
- if (call? target and target.method == :_hamlout)
20
- res = case method
21
- when :adjust_tabs, :rstrip!, :attributes #Check attributes, maybe?
22
- ignore
23
- when :options, :buffer
24
- exp
25
- when :open_tag
26
- process_call_args exp
27
- else
28
- arg = exp.first_arg
29
-
30
- if arg
31
- @inside_concat = true
32
- exp.first_arg = process(arg)
33
- out = normalize_output(exp.first_arg)
34
- @inside_concat = false
35
- else
36
- raise "Empty _hamlout.#{method}()?"
37
- end
38
-
39
- if string? out
40
- ignore
41
- else
42
- r = case method.to_s
43
- when "push_text"
44
- build_output_from_push_text(out)
45
- when HAML_FORMAT_METHOD
46
- if $4 == "true"
47
- if string_interp? out
48
- build_output_from_push_text(out, :escaped_output)
49
- else
50
- Sexp.new :format_escaped, out
51
- end
52
- else
53
- if string_interp? out
54
- build_output_from_push_text(out)
55
- else
56
- Sexp.new :format, out
57
- end
58
- end
59
-
60
- else
61
- raise "Unrecognized action on _hamlout: #{method}"
62
- end
63
-
64
- @javascript = false
65
- r
66
- end
67
- end
68
-
69
- res.line(exp.line)
70
- res
71
-
72
- #_hamlout.buffer <<
73
- #This seems to be used rarely, but directly appends args to output buffer.
74
- #Has something to do with values of blocks?
75
- elsif sexp? target and method == :<< and is_buffer_target? target
76
- @inside_concat = true
77
- exp.first_arg = process(exp.first_arg)
78
- out = normalize_output(exp.first_arg)
79
- @inside_concat = false
80
-
81
- if out.node_type == :str #ignore plain strings
82
- ignore
83
- else
84
- add_output out
85
- end
86
- elsif target == nil and method == :render
87
- #Process call to render()
88
- exp.arglist = process exp.arglist
89
- make_render_in_view exp
90
- elsif target == nil and method == :find_and_preserve and exp.first_arg
91
- process exp.first_arg
92
- elsif method == :render_with_options
93
- if target == JAVASCRIPT_FILTER or target == COFFEE_FILTER
94
- @javascript = true
95
- end
26
+ res or exp
27
+ end
96
28
 
97
- process exp.first_arg
98
- else
99
- exp.target = target
100
- exp.arglist = process exp.arglist
101
- exp
102
- end
29
+ # _haml_out.buffer << ...
30
+ def buffer_append? exp
31
+ call? exp and
32
+ exp.target == HAML_BUFFER and
33
+ exp.method == :<<
34
+ end
35
+
36
+ PRESERVE_METHODS = [:find_and_preserve, :preserve]
37
+
38
+ def find_and_preserve? exp
39
+ call? exp and
40
+ PRESERVE_METHODS.include?(exp.method) and
41
+ exp.first_arg
103
42
  end
104
43
 
105
44
  #If inside an output stream, only return the final expression
106
45
  def process_block exp
107
46
  exp = exp.dup
108
47
  exp.shift
109
- if @inside_concat
110
- @inside_concat = false
111
- exp[0..-2].each do |e|
112
- process e
113
- end
114
- @inside_concat = true
115
- process exp[-1]
116
- else
117
- exp.map! do |e|
118
- res = process e
119
- if res.empty?
120
- nil
121
- else
122
- res
123
- end
48
+
49
+ exp.map! do |e|
50
+ res = process e
51
+ if res.empty?
52
+ nil
53
+ else
54
+ res
124
55
  end
125
- Sexp.new(:rlist).concat(exp).compact
126
56
  end
127
- end
128
57
 
129
- #Checks if the buffer is the target in a method call Sexp.
130
- #TODO: Test this
131
- def is_buffer_target? exp
132
- exp.node_type == :call and
133
- node_type? exp.target, :lvar and
134
- exp.target.value == :_hamlout and
135
- exp.method == :buffer
58
+ Sexp.new(:rlist).concat(exp).compact
136
59
  end
137
60
 
138
61
  #HAML likes to put interpolated values into _hamlout.push_text
@@ -153,7 +76,6 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
153
76
  end
154
77
  end
155
78
 
156
- #Gets outputs from values interpolated into _hamlout.push_text
157
79
  def get_pushed_value exp, default = :output
158
80
  return exp unless sexp? exp
159
81
 
@@ -168,24 +90,71 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
168
90
  exp
169
91
  when :str, :ignore, :output, :escaped_output
170
92
  exp
171
- when :block, :rlist, :dstr
172
- exp.map! { |e| get_pushed_value e }
93
+ when :block, :rlist
94
+ exp.map! { |e| get_pushed_value(e, default) }
95
+ when :dstr
96
+ build_output_from_push_text(exp, default)
173
97
  when :if
174
- clauses = [get_pushed_value(exp.then_clause), get_pushed_value(exp.else_clause)].compact
98
+ clauses = [get_pushed_value(exp.then_clause, default), get_pushed_value(exp.else_clause, default)].compact
175
99
 
176
100
  if clauses.length > 1
177
- s(:or, *clauses)
101
+ s(:or, *clauses).line(exp.line)
178
102
  else
179
103
  clauses.first
180
104
  end
181
- else
182
- if call? exp and exp.target == HAML_HELPERS and exp.method == :html_escape
183
- add_escaped_output exp.first_arg
184
- elsif @javascript and call? exp and (exp.method == :j or exp.method == :escape_javascript)
185
- add_escaped_output exp.first_arg
105
+ when :call
106
+ if exp.method == :to_s or exp.method == :strip
107
+ get_pushed_value(exp.target, default)
108
+ elsif haml_helpers? exp.target and exp.method == :html_escape
109
+ get_pushed_value(exp.first_arg, :escaped_output)
110
+ elsif @javascript and (exp.method == :j or exp.method == :escape_javascript) # TODO: Remove - this is not safe
111
+ get_pushed_value(exp.first_arg, :escaped_output)
112
+ elsif find_and_preserve? exp or fix_textareas? exp
113
+ get_pushed_value(exp.first_arg, default)
114
+ elsif raw? exp
115
+ get_pushed_value(exp.first_arg, :output)
116
+ elsif hamlout_attributes? exp
117
+ ignore # ignore _hamlout.attributes calls
118
+ elsif exp.target.nil? and exp.method == :render
119
+ #Process call to render()
120
+ exp.arglist = process exp.arglist
121
+ make_render_in_view exp
122
+ elsif exp.method == :render_with_options
123
+ if exp.target == JAVASCRIPT_FILTER or exp.target == COFFEE_FILTER
124
+ @javascript = true
125
+ end
126
+
127
+ get_pushed_value(exp.first_arg, default)
128
+ @javascript = false
186
129
  else
187
130
  add_output exp, default
188
131
  end
132
+ else
133
+ add_output exp, default
189
134
  end
190
135
  end
136
+
137
+ def haml_helpers? exp
138
+ # Sometimes its Haml::Helpers and
139
+ # sometimes its ::Haml::Helpers
140
+ exp == HAML_HELPERS or
141
+ exp == HAML_HELPERS2
142
+ end
143
+
144
+ def hamlout_attributes? exp
145
+ call? exp and
146
+ exp.target == HAMLOUT and
147
+ exp.method == :attributes
148
+ end
149
+
150
+ def fix_textareas? exp
151
+ call? exp and
152
+ exp.target == HAMLOUT and
153
+ exp.method == :fix_textareas!
154
+ end
155
+
156
+ def raw? exp
157
+ call? exp and
158
+ exp.method == :raw
159
+ end
191
160
  end