brakeman-lib 3.3.1

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 (159) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +872 -0
  3. data/FEATURES +16 -0
  4. data/README.md +169 -0
  5. data/WARNING_TYPES +95 -0
  6. data/bin/brakeman +89 -0
  7. data/lib/brakeman.rb +495 -0
  8. data/lib/brakeman/app_tree.rb +161 -0
  9. data/lib/brakeman/brakeman.rake +17 -0
  10. data/lib/brakeman/call_index.rb +219 -0
  11. data/lib/brakeman/checks.rb +191 -0
  12. data/lib/brakeman/checks/base_check.rb +518 -0
  13. data/lib/brakeman/checks/check_basic_auth.rb +88 -0
  14. data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
  15. data/lib/brakeman/checks/check_content_tag.rb +160 -0
  16. data/lib/brakeman/checks/check_create_with.rb +75 -0
  17. data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
  18. data/lib/brakeman/checks/check_default_routes.rb +86 -0
  19. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  20. data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
  21. data/lib/brakeman/checks/check_digest_dos.rb +38 -0
  22. data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
  23. data/lib/brakeman/checks/check_escape_function.rb +21 -0
  24. data/lib/brakeman/checks/check_evaluation.rb +36 -0
  25. data/lib/brakeman/checks/check_execute.rb +167 -0
  26. data/lib/brakeman/checks/check_file_access.rb +63 -0
  27. data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
  28. data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
  29. data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
  30. data/lib/brakeman/checks/check_header_dos.rb +31 -0
  31. data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
  32. data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
  33. data/lib/brakeman/checks/check_json_encoding.rb +47 -0
  34. data/lib/brakeman/checks/check_json_parsing.rb +107 -0
  35. data/lib/brakeman/checks/check_link_to.rb +132 -0
  36. data/lib/brakeman/checks/check_link_to_href.rb +115 -0
  37. data/lib/brakeman/checks/check_mail_to.rb +49 -0
  38. data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
  39. data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
  40. data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
  41. data/lib/brakeman/checks/check_model_attributes.rb +119 -0
  42. data/lib/brakeman/checks/check_model_serialize.rb +67 -0
  43. data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
  44. data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
  45. data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
  46. data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
  47. data/lib/brakeman/checks/check_redirect.rb +215 -0
  48. data/lib/brakeman/checks/check_regex_dos.rb +69 -0
  49. data/lib/brakeman/checks/check_render.rb +92 -0
  50. data/lib/brakeman/checks/check_render_dos.rb +37 -0
  51. data/lib/brakeman/checks/check_render_inline.rb +54 -0
  52. data/lib/brakeman/checks/check_response_splitting.rb +21 -0
  53. data/lib/brakeman/checks/check_route_dos.rb +42 -0
  54. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
  55. data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
  56. data/lib/brakeman/checks/check_secrets.rb +40 -0
  57. data/lib/brakeman/checks/check_select_tag.rb +60 -0
  58. data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
  59. data/lib/brakeman/checks/check_send.rb +48 -0
  60. data/lib/brakeman/checks/check_send_file.rb +19 -0
  61. data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
  62. data/lib/brakeman/checks/check_session_settings.rb +170 -0
  63. data/lib/brakeman/checks/check_simple_format.rb +59 -0
  64. data/lib/brakeman/checks/check_single_quotes.rb +101 -0
  65. data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
  66. data/lib/brakeman/checks/check_sql.rb +660 -0
  67. data/lib/brakeman/checks/check_sql_cves.rb +101 -0
  68. data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
  69. data/lib/brakeman/checks/check_strip_tags.rb +89 -0
  70. data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
  71. data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -0
  72. data/lib/brakeman/checks/check_translate_bug.rb +45 -0
  73. data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
  74. data/lib/brakeman/checks/check_unscoped_find.rb +41 -0
  75. data/lib/brakeman/checks/check_validation_regex.rb +116 -0
  76. data/lib/brakeman/checks/check_weak_hash.rb +151 -0
  77. data/lib/brakeman/checks/check_without_protection.rb +80 -0
  78. data/lib/brakeman/checks/check_xml_dos.rb +51 -0
  79. data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
  80. data/lib/brakeman/differ.rb +66 -0
  81. data/lib/brakeman/file_parser.rb +50 -0
  82. data/lib/brakeman/format/style.css +133 -0
  83. data/lib/brakeman/options.rb +301 -0
  84. data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
  85. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
  86. data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
  87. data/lib/brakeman/parsers/template_parser.rb +89 -0
  88. data/lib/brakeman/processor.rb +102 -0
  89. data/lib/brakeman/processors/alias_processor.rb +1013 -0
  90. data/lib/brakeman/processors/base_processor.rb +277 -0
  91. data/lib/brakeman/processors/config_processor.rb +14 -0
  92. data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
  93. data/lib/brakeman/processors/controller_processor.rb +326 -0
  94. data/lib/brakeman/processors/erb_template_processor.rb +80 -0
  95. data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
  96. data/lib/brakeman/processors/gem_processor.rb +57 -0
  97. data/lib/brakeman/processors/haml_template_processor.rb +190 -0
  98. data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
  99. data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
  100. data/lib/brakeman/processors/lib/find_call.rb +183 -0
  101. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  102. data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
  103. data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
  104. data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
  105. data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
  106. data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
  107. data/lib/brakeman/processors/lib/render_helper.rb +181 -0
  108. data/lib/brakeman/processors/lib/render_path.rb +107 -0
  109. data/lib/brakeman/processors/lib/route_helper.rb +68 -0
  110. data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
  111. data/lib/brakeman/processors/library_processor.rb +119 -0
  112. data/lib/brakeman/processors/model_processor.rb +191 -0
  113. data/lib/brakeman/processors/output_processor.rb +171 -0
  114. data/lib/brakeman/processors/route_processor.rb +17 -0
  115. data/lib/brakeman/processors/slim_template_processor.rb +107 -0
  116. data/lib/brakeman/processors/template_alias_processor.rb +116 -0
  117. data/lib/brakeman/processors/template_processor.rb +74 -0
  118. data/lib/brakeman/report.rb +78 -0
  119. data/lib/brakeman/report/config/remediation.yml +71 -0
  120. data/lib/brakeman/report/ignore/config.rb +135 -0
  121. data/lib/brakeman/report/ignore/interactive.rb +311 -0
  122. data/lib/brakeman/report/renderer.rb +24 -0
  123. data/lib/brakeman/report/report_base.rb +286 -0
  124. data/lib/brakeman/report/report_codeclimate.rb +70 -0
  125. data/lib/brakeman/report/report_csv.rb +55 -0
  126. data/lib/brakeman/report/report_hash.rb +23 -0
  127. data/lib/brakeman/report/report_html.rb +216 -0
  128. data/lib/brakeman/report/report_json.rb +42 -0
  129. data/lib/brakeman/report/report_markdown.rb +156 -0
  130. data/lib/brakeman/report/report_table.rb +107 -0
  131. data/lib/brakeman/report/report_tabs.rb +17 -0
  132. data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
  133. data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
  134. data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
  135. data/lib/brakeman/report/templates/header.html.erb +58 -0
  136. data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
  137. data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
  138. data/lib/brakeman/report/templates/overview.html.erb +38 -0
  139. data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
  140. data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
  141. data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
  142. data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
  143. data/lib/brakeman/rescanner.rb +483 -0
  144. data/lib/brakeman/scanner.rb +317 -0
  145. data/lib/brakeman/tracker.rb +347 -0
  146. data/lib/brakeman/tracker/collection.rb +93 -0
  147. data/lib/brakeman/tracker/config.rb +101 -0
  148. data/lib/brakeman/tracker/constants.rb +101 -0
  149. data/lib/brakeman/tracker/controller.rb +161 -0
  150. data/lib/brakeman/tracker/library.rb +17 -0
  151. data/lib/brakeman/tracker/model.rb +90 -0
  152. data/lib/brakeman/tracker/template.rb +33 -0
  153. data/lib/brakeman/util.rb +481 -0
  154. data/lib/brakeman/version.rb +3 -0
  155. data/lib/brakeman/warning.rb +255 -0
  156. data/lib/brakeman/warning_codes.rb +111 -0
  157. data/lib/ruby_parser/bm_sexp.rb +610 -0
  158. data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
  159. metadata +362 -0
@@ -0,0 +1,191 @@
1
+ require 'brakeman/processors/base_processor'
2
+ require 'brakeman/tracker/model'
3
+
4
+ #Processes models. Puts results in tracker.models
5
+ class Brakeman::ModelProcessor < Brakeman::BaseProcessor
6
+
7
+ def initialize tracker
8
+ super
9
+ @current_class = nil
10
+ @current_method = nil
11
+ @current_module = nil
12
+ @visibility = :public
13
+ @file_name = nil
14
+ end
15
+
16
+ #Process model source
17
+ def process_model src, file_name = nil
18
+ @file_name = file_name
19
+ process src
20
+ end
21
+
22
+ #s(:class, NAME, PARENT, BODY)
23
+ def process_class exp
24
+ name = class_name(exp.class_name)
25
+ parent = class_name(exp.parent_name)
26
+
27
+ #If inside an inner class we treat it as a library.
28
+ if @current_class
29
+ Brakeman.debug "[Notice] Treating inner class as library: #{name}"
30
+ Brakeman::LibraryProcessor.new(@tracker).process_library exp, @file_name
31
+ return exp
32
+ end
33
+
34
+ if @current_class
35
+ outer_class = @current_class
36
+ name = (outer_class.name.to_s + "::" + name.to_s).to_sym
37
+ end
38
+
39
+ if @current_module
40
+ name = (@current_module.name.to_s + "::" + name.to_s).to_sym
41
+ end
42
+
43
+ if @tracker.models[name]
44
+ @current_class = @tracker.models[name]
45
+ @current_class.add_file @file_name, exp
46
+ else
47
+ @current_class = Brakeman::Model.new name, parent, @file_name, exp, @tracker
48
+ @tracker.models[name] = @current_class
49
+ end
50
+
51
+ exp.body = process_all! exp.body
52
+
53
+ if outer_class
54
+ @current_class = outer_class
55
+ else
56
+ @current_class = nil
57
+ end
58
+
59
+ exp
60
+ end
61
+
62
+ def process_module exp
63
+ name = class_name(exp.class_name)
64
+
65
+ if @current_module
66
+ outer_module = @current_module
67
+ name = (outer_module.name.to_s + "::" + name.to_s).to_sym
68
+ end
69
+
70
+ if @current_class
71
+ name = (@current_class.name.to_s + "::" + name.to_s).to_sym
72
+ end
73
+
74
+ if @tracker.libs[name]
75
+ @current_module = @tracker.libs[name]
76
+ @current_module.add_file @file_name, exp
77
+ else
78
+ @current_module = Brakeman::Model.new name, nil, @file_name, exp, @tracker
79
+ @tracker.libs[name] = @current_module
80
+ end
81
+
82
+ exp.body = process_all! exp.body
83
+
84
+ if outer_module
85
+ @current_module = outer_module
86
+ else
87
+ @current_module = nil
88
+ end
89
+
90
+ exp
91
+ end
92
+
93
+ #Handle calls outside of methods,
94
+ #such as include, attr_accessible, private, etc.
95
+ def process_call exp
96
+ return exp unless @current_class
97
+ return exp if process_call_defn? exp
98
+
99
+ target = exp.target
100
+ if sexp? target
101
+ target = process target
102
+ end
103
+
104
+ method = exp.method
105
+ first_arg = exp.first_arg
106
+
107
+ #Methods called inside class definition
108
+ #like attr_* and other settings
109
+ if @current_method.nil? and target.nil?
110
+ if first_arg.nil?
111
+ case method
112
+ when :private, :protected, :public
113
+ @visibility = method
114
+ when :attr_accessible
115
+ @current_class.set_attr_accessible
116
+ else
117
+ #??
118
+ end
119
+ else
120
+ case method
121
+ when :include
122
+ @current_class.add_include class_name(first_arg) if @current_class
123
+ when :attr_accessible
124
+ @current_class.set_attr_accessible exp
125
+ when :attr_protected
126
+ @current_class.set_attr_protected exp
127
+ else
128
+ if @current_class
129
+ @current_class.add_option method, exp
130
+ end
131
+ end
132
+ end
133
+
134
+ exp
135
+ else
136
+ call = make_call target, method, process_all!(exp.args)
137
+ call.line(exp.line)
138
+ call
139
+ end
140
+ end
141
+
142
+ #Add method definition to tracker
143
+ def process_defn exp
144
+ return exp unless @current_class
145
+ name = exp.method_name
146
+
147
+ @current_method = name
148
+ res = Sexp.new :defn, name, exp.formal_args, *process_all!(exp.body)
149
+ res.line(exp.line)
150
+ @current_method = nil
151
+
152
+ if @current_class
153
+ @current_class.add_method @visibility, name, res, @file_name
154
+ elsif @current_module
155
+ @current_module.add_method @visibility, name, res, @file_name
156
+ end
157
+
158
+ res
159
+ end
160
+
161
+ #Add method definition to tracker
162
+ def process_defs exp
163
+ return exp unless @current_class
164
+ name = exp.method_name
165
+
166
+ if node_type? exp[1], :self
167
+ if @current_class
168
+ target = @current_class.name
169
+ elsif @current_module
170
+ target = @current_module.name
171
+ else
172
+ target = nil
173
+ end
174
+ else
175
+ target = class_name exp[1]
176
+ end
177
+
178
+ @current_method = name
179
+ res = Sexp.new :defs, target, name, exp.formal_args, *process_all!(exp.body)
180
+ res.line(exp.line)
181
+ @current_method = nil
182
+
183
+ if @current_class
184
+ @current_class.add_method @visibility, name, res, @file_name
185
+ elsif @current_module
186
+ @current_module.add_method @visibility, name, res, @file_name
187
+ end
188
+ res
189
+ end
190
+
191
+ end
@@ -0,0 +1,171 @@
1
+ Brakeman.load_brakeman_dependency 'ruby2ruby'
2
+ require 'brakeman/util'
3
+
4
+ #Produces formatted output strings from Sexps.
5
+ #Recommended usage is
6
+ #
7
+ # OutputProcessor.new.format(Sexp.new(:str, "hello"))
8
+ class Brakeman::OutputProcessor < Ruby2Ruby
9
+ include Brakeman::Util
10
+
11
+ #Copies +exp+ and then formats it.
12
+ def format exp
13
+ process(exp.deep_clone) || "[Format Error]"
14
+ end
15
+
16
+ alias process_safely format
17
+
18
+ def process exp
19
+ begin
20
+ super exp if sexp? exp and not exp.empty?
21
+ rescue => e
22
+ Brakeman.debug "While formatting #{exp}: #{e}\n#{e.backtrace.join("\n")}"
23
+ end
24
+ end
25
+
26
+ def process_ignore exp
27
+ exp.clear
28
+ "[ignored]"
29
+ end
30
+
31
+ def process_params exp
32
+ exp.clear
33
+ "params"
34
+ end
35
+
36
+ def process_session exp
37
+ exp.clear
38
+ "session"
39
+ end
40
+
41
+ def process_cookies exp
42
+ exp.clear
43
+ "cookies"
44
+ end
45
+
46
+ def process_rlist exp
47
+ out = exp.map do |e|
48
+ res = process e
49
+ if res == ""
50
+ nil
51
+ else
52
+ res
53
+ end
54
+ end.compact.join("\n")
55
+ exp.clear
56
+ out
57
+ end
58
+
59
+ def process_defn exp
60
+ # Copied from Ruby2Ruby except without the whole
61
+ # "convert methods to attr_*" stuff
62
+ name = exp.shift
63
+ args = process exp.shift
64
+ args = "" if args == "()"
65
+
66
+ exp.shift if exp == s(s(:nil)) # empty it out of a default nil expression
67
+
68
+ body = []
69
+ until exp.empty? do
70
+ body << indent(process(exp.shift))
71
+ end
72
+
73
+ body << indent("# do nothing") if body.empty?
74
+
75
+ body = body.join("\n")
76
+
77
+ return "def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, "\n")
78
+ end
79
+
80
+ def process_iter exp
81
+ call = process exp[0]
82
+ block = process_rlist exp[2..-1]
83
+ out = "#{call} do\n #{block}\n end"
84
+ exp.clear
85
+ out
86
+ end
87
+
88
+ def process_output exp
89
+ out = if exp[0].node_type == :str
90
+ ""
91
+ else
92
+ res = process exp[0]
93
+
94
+ if res == ""
95
+ ""
96
+ else
97
+ "[Output] #{res}"
98
+ end
99
+ end
100
+ exp.clear
101
+ out
102
+ end
103
+
104
+ def process_escaped_output exp
105
+ out = if exp[0].node_type == :str
106
+ ""
107
+ else
108
+ res = process exp[0]
109
+
110
+ if res == ""
111
+ ""
112
+ else
113
+ "[Escaped Output] #{res}"
114
+ end
115
+ end
116
+ exp.clear
117
+ out
118
+ end
119
+
120
+
121
+ def process_format exp
122
+ out = if exp[0].node_type == :str or exp[0].node_type == :ignore
123
+ ""
124
+ else
125
+ res = process exp[0]
126
+
127
+ if res == ""
128
+ ""
129
+ else
130
+ "[Format] #{res}"
131
+ end
132
+ end
133
+ exp.clear
134
+ out
135
+ end
136
+
137
+ def process_format_escaped exp
138
+ out = if exp[0].node_type == :str or exp[0].node_type == :ignore
139
+ ""
140
+ else
141
+ res = process exp[0]
142
+
143
+ if res == ""
144
+ ""
145
+ else
146
+ "[Escaped] #{res}"
147
+ end
148
+ end
149
+ exp.clear
150
+ out
151
+ end
152
+
153
+ def process_const exp
154
+ if exp[0] == Brakeman::Tracker::UNKNOWN_MODEL
155
+ exp.clear
156
+ "(Unresolved Model)"
157
+ else
158
+ out = exp[0].to_s
159
+ exp.clear
160
+ out
161
+ end
162
+ end
163
+
164
+ def process_render exp
165
+ exp[1] = process exp[1] if sexp? exp[1]
166
+ exp[2] = process exp[2] if sexp? exp[2]
167
+ out = "render(#{exp[0]} => #{exp[1]}, #{exp[2]})"
168
+ exp.clear
169
+ out
170
+ end
171
+ end
@@ -0,0 +1,17 @@
1
+ require 'brakeman/processors/base_processor'
2
+ require 'brakeman/processors/alias_processor'
3
+ require 'brakeman/processors/lib/route_helper'
4
+ require 'brakeman/util'
5
+ require 'brakeman/processors/lib/rails3_route_processor.rb'
6
+ require 'brakeman/processors/lib/rails2_route_processor.rb'
7
+ require 'set'
8
+
9
+ class Brakeman::RoutesProcessor
10
+ def self.new tracker
11
+ if tracker.options[:rails3]
12
+ Brakeman::Rails3RoutesProcessor.new tracker
13
+ else
14
+ Brakeman::Rails2RoutesProcessor.new tracker
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,107 @@
1
+ require 'brakeman/processors/template_processor'
2
+ require 'brakeman/processors/lib/render_helper'
3
+
4
+ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
5
+ include Brakeman::RenderHelper
6
+
7
+ SAFE_BUFFER = s(:call, s(:colon2, s(:const, :ActiveSupport), :SafeBuffer), :new)
8
+ OUTPUT_BUFFER = s(:ivar, :@output_buffer)
9
+ TEMPLE_UTILS = s(:colon2, s(:colon3, :Temple), :Utils)
10
+
11
+ def process_call exp
12
+ target = exp.target
13
+ method = exp.method
14
+
15
+ if method == :safe_concat and (target == SAFE_BUFFER or target == OUTPUT_BUFFER)
16
+ arg = normalize_output(exp.first_arg)
17
+
18
+ if is_escaped? arg
19
+ make_escaped_output arg
20
+ elsif string? arg
21
+ ignore
22
+ elsif render? arg
23
+ make_output make_render_in_view arg
24
+ elsif string_interp? arg
25
+ process_inside_interp arg
26
+ elsif node_type? arg, :ignore
27
+ ignore
28
+ else
29
+ make_output arg
30
+ end
31
+ elsif is_escaped? exp
32
+ make_escaped_output exp.first_arg
33
+ elsif target == nil and method == :render
34
+ exp.arglist = process exp.arglist
35
+ make_render_in_view exp
36
+ else
37
+ exp.arglist = process exp.arglist
38
+ exp
39
+ end
40
+ end
41
+
42
+ def make_output exp
43
+ s = Sexp.new :output, exp
44
+ s.line(exp.line)
45
+ @current_template.add_output s
46
+ s
47
+ end
48
+
49
+ def make_escaped_output exp
50
+ s = Sexp.new :escaped_output, exp.first_arg
51
+ s.line(exp.line)
52
+ @current_template.add_output s
53
+ s
54
+ end
55
+
56
+ #Slim likes to interpolate output into strings then pass them to safe_concat.
57
+ #Better to pull those values out directly.
58
+ def process_inside_interp exp
59
+ exp.map! do |e|
60
+ if node_type? e, :evstr
61
+ e.value = process_interp_output e.value
62
+ e
63
+ else
64
+ e
65
+ end
66
+ end
67
+
68
+ exp
69
+ end
70
+
71
+ def process_interp_output exp
72
+ if sexp? exp
73
+ if node_type? exp, :if
74
+ process_interp_output exp.then_clause
75
+ process_interp_output exp.else_clause
76
+ elsif exp == SAFE_BUFFER
77
+ ignore
78
+ elsif render? exp
79
+ make_output make_render_in_view exp
80
+ elsif node_type? :output, :escaped_output
81
+ exp
82
+ elsif is_escaped? exp
83
+ make_escaped_output exp
84
+ else
85
+ make_output exp
86
+ end
87
+ end
88
+ end
89
+
90
+ def is_escaped? exp
91
+ call? exp and
92
+ exp.target == TEMPLE_UTILS and
93
+ (exp.method == :escape_html or exp.method == :escape_html_safe)
94
+ end
95
+
96
+ def render? exp
97
+ call? exp and
98
+ exp.target.nil? and
99
+ exp.method == :render
100
+ end
101
+
102
+ def process_render exp
103
+ #Still confused as to why this is not needed in other template processors
104
+ #but is needed here
105
+ exp
106
+ end
107
+ end