Skip to content

Commit d3654c9

Browse files
authored
Fix if and unless statements in <%= %> tags (#28)
* fixed if and unless stmts in escape tags. Fixed formatting in erb transformer file * fixed if and unless stmts in escape tags. Fixed formatting in erb transformer file
1 parent 6856196 commit d3654c9

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

lib/ruby_ast_gen/erb_to_ruby_transformer.rb

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def transform(input)
3030
end
3131

3232
private
33+
3334
def visit(node)
3435
return "" unless node.is_a?(Array)
3536
case node.first
@@ -59,29 +60,62 @@ def visit(node)
5960
if ast.is_a?(::Parser::AST::Node)
6061
case ast.type
6162
when :if
62-
if code.include?(" if ")
63-
call, if_cond = code.split(" if ")
63+
if code.strip.start_with?("if") || code.strip.start_with?("unless")
64+
template_call = if escape_enabled
65+
"joern__template_out_raw"
66+
else
67+
"joern__template_out_escape"
68+
end
69+
70+
if_cond = extract_code_snippet(ast.children[0].location, code)
71+
if_body = extract_code_snippet(ast.children[1].location, code) if ast.children[1]
72+
else_body = extract_code_snippet(ast.children[2].location, code) if ast.children[2]
73+
6474
@output << "if #{if_cond}"
75+
@output << "#{template_call}(#{if_body})" if if_body
76+
@output << "else" if else_body
77+
@output << "#{@output_tmp_var} << #{template_call}(#{else_body})" if else_body
6578
else
66-
call, if_cond = code.split(" unless ")
67-
@output << "unless #{if_cond}"
79+
if code.include?(" if ")
80+
call, if_cond = code.split(" if ")
81+
@output << "if #{if_cond}"
82+
else
83+
call, if_cond = code.split(" unless ")
84+
@output << "unless #{if_cond}"
85+
end
86+
template_call = if escape_enabled
87+
"joern__template_out_raw"
88+
else
89+
"joern__template_out_escape"
90+
end
91+
@output << "#{@output_tmp_var} << #{template_call}(#{call})"
6892
end
69-
template_call = if escape_enabled then "joern__template_out_raw" else "joern__template_out_escape" end
70-
@output << "#{@output_tmp_var} << #{template_call}(#{call})"
7193
@output << "end"
7294
else
73-
template_call = if escape_enabled then "joern__template_out_raw" else "joern__template_out_escape" end
95+
template_call = if escape_enabled then
96+
"joern__template_out_raw"
97+
else
98+
"joern__template_out_escape"
99+
end
74100
@output << "#{@inner_buffer} << #{template_call}(#{code})"
75101
end
76102
end
77103
elsif is_do_block(code)
78104
# Do block with variable found, lower
79105
lower_do_block(code)
80106
elsif @in_do_block
81-
template_call = if escape_enabled then "joern__template_out_raw" else "joern__template_out_escape" end
107+
template_call = if escape_enabled then
108+
"joern__template_out_raw"
109+
else
110+
"joern__template_out_escape"
111+
end
82112
@output << "#{@inner_buffer} << #{template_call}(#{code})"
83113
else
84-
template_call = if escape_enabled then "joern__template_out_raw" else "joern__template_out_escape" end
114+
template_call = if escape_enabled then
115+
"joern__template_out_raw"
116+
else
117+
"joern__template_out_escape"
118+
end
85119
@output << "#{@output_tmp_var} << #{template_call}(#{code})"
86120
end
87121
when :code
@@ -92,7 +126,7 @@ def visit(node)
92126
if is_control_struct_start(stripped_code)
93127
@in_control_block = true
94128
@output << stripped_code
95-
elsif stripped_code.start_with?("end")
129+
elsif stripped_code == "end"
96130
if @in_do_block
97131
@in_do_block = false
98132
@output << "#{@inner_buffer}"
@@ -102,10 +136,10 @@ def visit(node)
102136
@in_control_block = false
103137
@output << "end"
104138
end
139+
elsif is_do_block(code)
140+
lower_do_block(code)
105141
else
106-
if is_do_block(code)
107-
lower_do_block(code)
108-
end
142+
@output << code
109143
end
110144
when :newline
111145
else
@@ -124,12 +158,16 @@ def lambda_incrementor()
124158
end
125159

126160
def current_lambda()
127-
"rails_lambda_#{@current_counter-1}"
161+
"rails_lambda_#{@current_counter - 1}"
128162
end
129163

130164
def flush_static_block()
131165
unless @static_buff.empty?
132-
buffer_to_use = if @in_do_block then @inner_buffer else @output_tmp_var end
166+
buffer_to_use = if @in_do_block then
167+
@inner_buffer
168+
else
169+
@output_tmp_var
170+
end
133171
@output << "#{buffer_to_use} << \"#{@static_buff.join('\n').gsub(/(?<!\\)"/, '')}\""
134172
@static_buff = [] # clear static buffer
135173
end
@@ -162,6 +200,14 @@ def lower_do_block(code)
162200
def is_do_block(code)
163201
code.match(/do\s*(?:\|([^|]*)\|)?/)
164202
end
203+
204+
def extract_code_snippet(location, source_code)
205+
return nil unless location
206+
range = location.expression || location
207+
return nil unless range.is_a?(Parser::Source::Range)
208+
snippet = source_code[range.begin_pos...range.end_pos]
209+
snippet.strip
210+
end
165211
end
166212

167213

0 commit comments

Comments
 (0)