Skip to content

Commit 8042d98

Browse files
asteriteRX14
authored andcommittedSep 21, 2017
Let HTML.escape only escape &<>"' (#5012)
1 parent 02fca17 commit 8042d98

File tree

2 files changed

+19
-40
lines changed

2 files changed

+19
-40
lines changed
 

‎spec/std/html_spec.cr

+2-14
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,9 @@ describe "HTML" do
1010
end
1111

1212
it "escapes dangerous characters from a string" do
13-
str = HTML.escape("< & >")
13+
str = HTML.escape("< & > ' \"")
1414

15-
str.should eq("&lt; &amp; &gt;")
16-
end
17-
18-
it "escapes javascript example from a string" do
19-
str = HTML.escape("<script>alert('You are being hacked')</script>")
20-
21-
str.should eq("&lt;script&gt;alert&#40;&#39;You are being hacked&#39;&#41;&lt;/script&gt;")
22-
end
23-
24-
it "escapes nonbreakable space but not normal space" do
25-
str = HTML.escape("nbsp space ")
26-
27-
str.should eq("nbsp&nbsp;space ")
15+
str.should eq("&lt; &amp; &gt; &#39; &quot;")
2816
end
2917
end
3018

‎src/html.cr

+17-26
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
1-
# Handles encoding and decoding of HTML entities.
1+
# Provides HTML escaping and unescaping methods.
22
module HTML
3-
SUBSTITUTIONS = {
4-
'!' => "&#33;",
5-
'"' => "&quot;",
6-
'$' => "&#36;",
7-
'%' => "&#37;",
8-
'&' => "&amp;",
9-
'\'' => "&#39;",
10-
'(' => "&#40;",
11-
')' => "&#41;",
12-
'=' => "&#61;",
13-
'>' => "&gt;",
14-
'<' => "&lt;",
15-
'+' => "&#43;",
16-
'@' => "&#64;",
17-
'[' => "&#91;",
18-
']' => "&#93;",
19-
'`' => "&#96;",
20-
'{' => "&#123;",
21-
'}' => "&#125;",
22-
'\u{a0}' => "&nbsp;",
3+
private SUBSTITUTIONS = {
4+
'&' => "&amp;",
5+
'<' => "&lt;",
6+
'>' => "&gt;",
7+
'"' => "&quot;",
8+
'\'' => "&#39;",
239
}
2410

25-
# Encodes a string with HTML entity substitutions.
11+
# Escapes special characters in HTML, namely
12+
# `&`, `<`, `>`, `"` and `'`.
2613
#
2714
# ```
2815
# require "html"
@@ -33,25 +20,29 @@ module HTML
3320
string.gsub(SUBSTITUTIONS)
3421
end
3522

36-
# Encodes a string to HTML, but writes to the `IO` instance provided.
23+
# Same as `escape(string)` but ouputs the result to
24+
# the given *io*.
3725
#
3826
# ```
3927
# io = IO::Memory.new
4028
# HTML.escape("Crystal & You", io) # => nil
4129
# io.to_s # => "Crystal &amp; You"
4230
# ```
43-
def self.escape(string : String, io : IO)
31+
def self.escape(string : String, io : IO) : Nil
4432
string.each_char do |char|
4533
io << SUBSTITUTIONS.fetch(char, char)
4634
end
4735
end
4836

49-
# Decodes a string that contains HTML entities.
37+
# Returns a string where some named and all numeric character references
38+
# (e.g. &gt;, &#62;, &x3e;) in *string* are replaced with the corresponding
39+
# unicode characters. Only these named entities are replaced:
40+
# apos, amp, quot, gt, lt and nbsp.
5041
#
5142
# ```
5243
# HTML.unescape("Crystal &amp; You") # => "Crystal & You"
5344
# ```
54-
def self.unescape(string : String)
45+
def self.unescape(string : String) : String
5546
return string unless string.includes? '&'
5647

5748
string.gsub(/&(apos|amp|quot|gt|lt|nbsp|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do |string, _match|

0 commit comments

Comments
 (0)