@@ -30,6 +30,20 @@ def encode(value, options = nil)
30
30
end
31
31
32
32
module Encoding # :nodoc:
33
+ U2028 = -"\u2028 " . b
34
+ U2029 = -"\u2029 " . b
35
+
36
+ ESCAPED_CHARS = {
37
+ U2028 => '\u2028' . b ,
38
+ U2029 => '\u2029' . b ,
39
+ ">" . b => '\u003e' . b ,
40
+ "<" . b => '\u003c' . b ,
41
+ "&" . b => '\u0026' . b ,
42
+ }
43
+
44
+ ESCAPE_REGEX_WITH_HTML_ENTITIES = Regexp . union ( *ESCAPED_CHARS . keys )
45
+ ESCAPE_REGEX_WITHOUT_HTML_ENTITIES = Regexp . union ( U2028 , U2029 )
46
+
33
47
class JSONGemEncoder # :nodoc:
34
48
attr_reader :options
35
49
@@ -47,14 +61,13 @@ def encode(value)
47
61
# Rails does more escaping than the JSON gem natively does (we
48
62
# escape \u2028 and \u2029 and optionally >, <, & to work around
49
63
# certain browser problems).
64
+ json . force_encoding ( ::Encoding ::BINARY )
50
65
if @options . fetch ( :escape_html_entities , Encoding . escape_html_entities_in_json )
51
- json . gsub! ( ">" , '\u003e' )
52
- json . gsub! ( "<" , '\u003c' )
53
- json . gsub! ( "&" , '\u0026' )
66
+ json . gsub! ( ESCAPE_REGEX_WITH_HTML_ENTITIES , ESCAPED_CHARS )
67
+ else
68
+ json . gsub! ( ESCAPE_REGEX_WITHOUT_HTML_ENTITIES , ESCAPED_CHARS )
54
69
end
55
- json . gsub! ( "\u2028 " , '\u2028' )
56
- json . gsub! ( "\u2029 " , '\u2029' )
57
- json
70
+ json . force_encoding ( ::Encoding ::UTF_8 )
58
71
end
59
72
60
73
private
@@ -130,14 +143,13 @@ def encode(value)
130
143
# Rails does more escaping than the JSON gem natively does (we
131
144
# escape \u2028 and \u2029 and optionally >, <, & to work around
132
145
# certain browser problems).
146
+ json . force_encoding ( ::Encoding ::BINARY )
133
147
if @options . fetch ( :escape_html_entities , Encoding . escape_html_entities_in_json )
134
- json . gsub! ( ">" , '\u003e' )
135
- json . gsub! ( "<" , '\u003c' )
136
- json . gsub! ( "&" , '\u0026' )
148
+ json . gsub! ( ESCAPE_REGEX_WITH_HTML_ENTITIES , ESCAPED_CHARS )
149
+ else
150
+ json . gsub! ( ESCAPE_REGEX_WITHOUT_HTML_ENTITIES , ESCAPED_CHARS )
137
151
end
138
- json . gsub! ( "\u2028 " , '\u2028' )
139
- json . gsub! ( "\u2029 " , '\u2029' )
140
- json
152
+ json . force_encoding ( ::Encoding ::UTF_8 )
141
153
end
142
154
end
143
155
end
0 commit comments