Skip to content

Commit ac33f7f

Browse files
committed
Added escaper for </ in string variables
1 parent 61db654 commit ac33f7f

File tree

4 files changed

+40
-43
lines changed

4 files changed

+40
-43
lines changed

lib/gon.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'action_view'
55
require 'action_controller'
66
require 'gon/helpers'
7+
require 'gon/escaper'
78
if defined?(Rabl)
89
require 'gon/rabl'
910
end

lib/gon/escaper.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module Gon
2+
module Escaper
3+
class << self
4+
5+
GON_JS_ESCAPE_MAP = {
6+
'</' => '<\/'
7+
}
8+
9+
def escape(javascript)
10+
if javascript
11+
result = javascript.gsub(/(<\/)/u) {|match| GON_JS_ESCAPE_MAP[match] }
12+
javascript.html_safe? ? result.html_safe : result
13+
else
14+
''
15+
end
16+
end
17+
18+
end
19+
end
20+
end

lib/gon/helpers.rb

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ def self.included base
66
end
77

88
module InstanceMethods
9+
910
def include_gon(options = {})
1011
if Gon.request_env && Gon.all_variables.present? && Gon.request == request.object_id
1112
data = Gon.all_variables
@@ -21,67 +22,35 @@ def include_gon(options = {})
2122
script << namespace + '.' + key.to_s + '=' + val.to_json + ';'
2223
end
2324
end
24-
script = start + escape_javascript(script) + '</script>'
25+
script = start + Gon.escape(script) + '</script>'
2526
script.html_safe
2627
else
2728
""
2829
end
2930
end
3031

31-
unless self.respond_to? :escape_javascript
32-
# Just add helper from rails 3-2-stable
33-
34-
JS_ESCAPE_MAP = {
35-
'\\' => '\\\\',
36-
'</' => '<\/',
37-
"\r\n" => '\n',
38-
"\n" => '\n',
39-
"\r" => '\n',
40-
'"' => '\\"',
41-
"'" => "\\'"
42-
}
43-
44-
if "ruby".encoding_aware?
45-
JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
46-
else
47-
JS_ESCAPE_MAP["\342\200\250"] = '&#x2028;'
48-
end
49-
50-
# Escapes carriage returns and single and double quotes for JavaScript segments.
51-
#
52-
# Also available through the alias j(). This is particularly helpful in JavaScript responses, like:
53-
#
54-
# $('some_element').replaceWith('<%=j render 'some/element_template' %>');
55-
def escape_javascript(javascript)
56-
if javascript
57-
result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
58-
javascript.html_safe? ? result.html_safe : result
59-
else
60-
''
61-
end
62-
end
63-
64-
alias_method :j, :escape_javascript
65-
end
6632
end
6733
end
6834

6935
module GonHelpers
36+
7037
def self.included base
7138
base.send(:include, InstanceMethods)
7239
end
7340

7441
module InstanceMethods
42+
7543
def gon
7644
if !Gon.request_env || Gon.request != request.object_id
7745
Gon.request = request.object_id
7846
Gon.request_env = request.env
7947
end
8048
Gon
8149
end
50+
8251
end
83-
end
8452

53+
end
8554
end
8655

8756
ActionView::Base.send :include, Gon::Helpers

spec/gon/gon_spec.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,24 @@
3737
end
3838

3939
it 'outputs correct js with an integer' do
40-
Gon.int = 1
41-
@base.include_gon.should == "<script>window.gon = {};" +
42-
"gon.int=1;" +
43-
"</script>"
40+
Gon.int = 1
41+
@base.include_gon.should == '<script>window.gon = {};' +
42+
'gon.int=1;' +
43+
'</script>'
4444
end
4545

4646
it 'outputs correct js with a string' do
4747
Gon.str = %q(a'b"c)
4848
@base.include_gon.should == '<script>window.gon = {};' +
49-
%q(gon.str="a'b\"c";) +
50-
'</script>'
49+
%q(gon.str="a'b\"c";) +
50+
'</script>'
51+
end
52+
53+
it 'outputs correct js with a script string' do
54+
Gon.str = %q(</script><script>alert('!')</script>)
55+
@base.include_gon.should == '<script>window.gon = {};' +
56+
%q(gon.str="<\\/script><script>alert('!')<\\/script>";) +
57+
'</script>'
5158
end
5259

5360
end

0 commit comments

Comments
 (0)