Skip to content

Commit

Permalink
Fix escaping in erubi/capture_end, the setting was previously inverted (
Browse files Browse the repository at this point in the history
Fixes #10)

This wasn't caught previously because the tests are parameterized
and it wasn't obvious what the settings was.  The code was based
on the default erubi code which uses xor, but a positive xor leads
to unescaped output in the default code, but previously lead to
escaped output in capture_end.

While here, add a couple non-parameterized capture_end tests to make
the expected behavior obvious, as well as a parameterized test for
using a loop inside a method that gets injected into a <%|= and
<%|== block.
  • Loading branch information
jeremyevans committed Oct 4, 2017
1 parent 0fc0bcf commit d944709
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
@@ -1,3 +1,7 @@
=== master

* Fix escaping in erubi/capture_end, the setting was previously inverted (jeremyevans) (#10)

=== 1.6.1 (2017-06-27)

* Fix usage on newer versions of JRuby 9.1 (jeremyevans)
Expand Down
2 changes: 1 addition & 1 deletion lib/erubi/capture_end.rb
Expand Up @@ -28,7 +28,7 @@ def handle(indicator, code, tailch, rspace, lspace)
when '|=', '|=='
rspace = nil if tailch && !tailch.empty?
add_text(lspace) if lspace
escape_capture = ((indicator == '|=') ^ @escape_capture)
escape_capture = !((indicator == '|=') ^ @escape_capture)
src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
add_text(rspace) if rspace
when '|'
Expand Down
78 changes: 71 additions & 7 deletions test/test.rb
Expand Up @@ -64,6 +64,16 @@ def self.baz
@a << 'd'
@a * 2
end
def self.quux
@a << "a"
3.times do |i|
@a << "c#{i}"
yield i
@a << "d#{i}"
end
@a << "b"
@a.upcase
end
end

it "should handle no options" do
Expand Down Expand Up @@ -159,6 +169,22 @@ def self.baz
@a.must_equal 'bar'
end

it "should have <%|= with CaptureEndEngine not escape by default" do
eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>').src).must_equal '&'
eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape=>false).src).must_equal '&'
eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape_capture=>false).src).must_equal '&'
eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape=>true).src).must_equal '&amp;'
eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape_capture=>true).src).must_equal '&amp;'
end

it "should have <%|== with CaptureEndEngine escape by default" do
eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>').src).must_equal '&amp;'
eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape=>true).src).must_equal '&'
eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape_capture=>true).src).must_equal '&'
eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape=>false).src).must_equal '&amp;'
eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape_capture=>false).src).must_equal '&amp;'
end

[['', false], ['=', true]].each do |ind, escape|
it "should allow <%|=#{ind} and <%| for capturing with CaptureEndEngine with :escape_capture => #{escape} and :escape => #{!escape}" do
@options[:bufvar] = '@a'
Expand All @@ -178,7 +204,7 @@ def self.baz
END1
#{'__erubi = ::Erubi;' unless escape}@a = String.new; @a << '<table>
<tbody>
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{!escape ? '__erubi' : '::Erubi'}.h(( bar do @a << '
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do @a << '
'; @a << ' <b>'; @a << #{!escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
'; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' </tbody>
Expand All @@ -189,7 +215,7 @@ def self.baz
<table>
<tbody>
A
&lt;B&gt;&amp;AMP;&lt;/B&gt;
<B>&AMP;</B>
B
</tbody>
</table>
Expand All @@ -214,7 +240,7 @@ def self.baz
END1
#{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
<tbody>
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do @a << '
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( bar do @a << '
'; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
'; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' </tbody>
Expand All @@ -225,13 +251,51 @@ def self.baz
<table>
<tbody>
A
<B>&AMP;</B>
&lt;B&gt;&amp;AMP;&lt;/B&gt;
B
</tbody>
</table>
END3
end

it "should handle loops in <%|=#{ind} and <%| for capturing with CaptureEndEngine when with :escape => #{escape}" do
@options[:bufvar] = '@a'
@options[:escape] = escape
@options[:engine] = ::Erubi::CaptureEndEngine
setup_bar
check_output(<<END1, <<END2, <<END3){}
<table>
<tbody>
<%|=#{ind} quux do |i| %>
<b><%=#{ind} "\#{i}&" %></b>
<%| end %>
</tbody>
</table>
END1
#{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
<tbody>
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( quux do |i| @a << '
'; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( "\#{i}&" )); @a << '</b>
'; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' </tbody>
</table>
';
@a.to_s
END2
<table>
<tbody>
AC0
&lt;B&gt;0&amp;AMP;&lt;/B&gt;
D0C1
&lt;B&gt;1&amp;AMP;&lt;/B&gt;
D1C2
&lt;B&gt;2&amp;AMP;&lt;/B&gt;
D2B
</tbody>
</table>
END3
end

it "should allow <%|=#{ind} and <%| for nested capturing with CaptureEndEngine when with :escape => #{escape}" do
@options[:bufvar] = '@a'
@options[:escape] = escape
Expand All @@ -249,9 +313,9 @@ def self.baz
END1
#{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
<tbody>
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do @a << '
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( bar do @a << '
'; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( baz do @a << 'e'; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( baz do @a << 'e'; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
'; @a << ' </tbody>
</table>
Expand All @@ -261,7 +325,7 @@ def self.baz
<table>
<tbody>
A
<B>&AMP;</B>
&lt;B&gt;&amp;AMP;&lt;/B&gt;
CEDCED
B
</tbody>
Expand Down

0 comments on commit d944709

Please sign in to comment.