Skip to content

Commit c78f722

Browse files
committed
Fix regression where only first backslash/apostrophe was escaped
d152b2d broke pretty much all usage of Erubi on websites because it only escapes the first backslash or apostrophe in the text when escaping. This removes the use of String#[]= to handle escaping, moving to String#gsub! (or gsub in the frozen case).
1 parent ec1f639 commit c78f722

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

CHANGELOG

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
* Support :literal_prefix and :literal_postfix options for how to output literal tags (e.g. <%% code %>) (jaredcwhite) (#26, #27)
88

9-
* Reduce memory allocation during template parsing (fatkodima, jeremyevans) (#25)
10-
119
=== 1.9.0 (2019-09-25)
1210

1311
* Change default :bufvar from 'String.new' to '::String.new' to work with BasicObject (jeremyevans)

lib/erubi.rb

+4-6
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,10 @@ def initialize(input, properties={})
179179
# Add raw text to the template. Modifies argument if argument is mutable as a memory optimization.
180180
def add_text(text)
181181
if text && !text.empty?
182-
include_slash = text.include?('\\')
183-
include_apos = text.include?("'")
184-
if include_slash || include_apos
185-
text = text.dup if text.frozen?
186-
text['\\'] = '\\\\' if include_slash
187-
text["'"] = "\\'" if include_apos
182+
if text.frozen?
183+
text = text.gsub(/['\\]/, '\\\\\&')
184+
else
185+
text.gsub!(/['\\]/, '\\\\\&')
188186
end
189187
@src << " " << @bufvar << " << '" << text << TEXT_END
190188
end

test/test.rb

+43
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,49 @@ def self.quux
121121
END3
122122
end
123123

124+
it "should escape all backslashes and apostrophes in text" do
125+
list = ['&\'<>"2']
126+
check_output(<<END1, <<END2, <<END3){}
127+
<table>
128+
<tbody>' ' \\ \\
129+
<% i = 0
130+
list.each_with_index do |item, i| %>
131+
<tr>
132+
<td><%= i+1 %></td>
133+
<td><%== item %></td>
134+
</tr>
135+
<% end %>
136+
</tbody>
137+
</table>
138+
<%== i+1 %>
139+
END1
140+
_buf = ::String.new; _buf << '<table>
141+
<tbody>\\' \\' \\\\ \\\\
142+
'; i = 0
143+
list.each_with_index do |item, i|
144+
_buf << ' <tr>
145+
<td>'; _buf << ( i+1 ).to_s; _buf << '</td>
146+
<td>'; _buf << ::Erubi.h(( item )); _buf << '</td>
147+
</tr>
148+
'; end
149+
_buf << ' </tbody>
150+
</table>
151+
'; _buf << ::Erubi.h(( i+1 )); _buf << '
152+
';
153+
_buf.to_s
154+
END2
155+
<table>
156+
<tbody>' ' \\ \\
157+
<tr>
158+
<td>1</td>
159+
<td>&amp;&#39;&lt;&gt;&quot;2</td>
160+
</tr>
161+
</tbody>
162+
</table>
163+
1
164+
END3
165+
end
166+
124167
it "should strip only whitespace for <%, <%- and <%# tags" do
125168
check_output(<<END1, <<END2, <<END3){}
126169
<% 1 %>

0 commit comments

Comments
 (0)