json 2.3.0 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +71 -5
- data/README.md +19 -3
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +132 -23
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/extconf.rb +26 -0
- data/ext/json/ext/parser/parser.c +2979 -1768
- data/ext/json/ext/parser/parser.h +6 -1
- data/ext/json/ext/parser/parser.rl +128 -38
- data/ext/json/extconf.rb +1 -0
- data/json.gemspec +0 -0
- data/lib/json/add/complex.rb +0 -1
- data/lib/json/add/rational.rb +0 -1
- data/lib/json/common.rb +370 -123
- data/lib/json/pure/generator.rb +29 -9
- data/lib/json/pure/parser.rb +23 -5
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +549 -29
- metadata +17 -109
- data/.gitignore +0 -18
- data/.travis.yml +0 -24
- data/Gemfile +0 -14
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -413
- data/diagrams/.keep +0 -0
- data/install.rb +0 -23
- data/java/src/json/ext/ByteListTranscoder.java +0 -166
- data/java/src/json/ext/Generator.java +0 -466
- data/java/src/json/ext/GeneratorMethods.java +0 -231
- data/java/src/json/ext/GeneratorService.java +0 -42
- data/java/src/json/ext/GeneratorState.java +0 -490
- data/java/src/json/ext/OptionsReader.java +0 -113
- data/java/src/json/ext/Parser.java +0 -2362
- data/java/src/json/ext/Parser.rl +0 -893
- data/java/src/json/ext/ParserService.java +0 -34
- data/java/src/json/ext/RuntimeInfo.java +0 -116
- data/java/src/json/ext/StringDecoder.java +0 -166
- data/java/src/json/ext/StringEncoder.java +0 -111
- data/java/src/json/ext/Utils.java +0 -88
- data/json-java.gemspec +0 -37
- data/json_pure.gemspec +0 -38
- data/lib/json/ext/.keep +0 -0
- data/references/rfc7159.txt +0 -899
- data/tests/fixtures/fail10.json +0 -1
- data/tests/fixtures/fail11.json +0 -1
- data/tests/fixtures/fail12.json +0 -1
- data/tests/fixtures/fail13.json +0 -1
- data/tests/fixtures/fail14.json +0 -1
- data/tests/fixtures/fail18.json +0 -1
- data/tests/fixtures/fail19.json +0 -1
- data/tests/fixtures/fail2.json +0 -1
- data/tests/fixtures/fail20.json +0 -1
- data/tests/fixtures/fail21.json +0 -1
- data/tests/fixtures/fail22.json +0 -1
- data/tests/fixtures/fail23.json +0 -1
- data/tests/fixtures/fail24.json +0 -1
- data/tests/fixtures/fail25.json +0 -1
- data/tests/fixtures/fail27.json +0 -2
- data/tests/fixtures/fail28.json +0 -2
- data/tests/fixtures/fail3.json +0 -1
- data/tests/fixtures/fail4.json +0 -1
- data/tests/fixtures/fail5.json +0 -1
- data/tests/fixtures/fail6.json +0 -1
- data/tests/fixtures/fail7.json +0 -1
- data/tests/fixtures/fail8.json +0 -1
- data/tests/fixtures/fail9.json +0 -1
- data/tests/fixtures/obsolete_fail1.json +0 -1
- data/tests/fixtures/pass1.json +0 -56
- data/tests/fixtures/pass15.json +0 -1
- data/tests/fixtures/pass16.json +0 -1
- data/tests/fixtures/pass17.json +0 -1
- data/tests/fixtures/pass2.json +0 -1
- data/tests/fixtures/pass26.json +0 -1
- data/tests/fixtures/pass3.json +0 -6
- data/tests/json_addition_test.rb +0 -203
- data/tests/json_common_interface_test.rb +0 -126
- data/tests/json_encoding_test.rb +0 -107
- data/tests/json_ext_parser_test.rb +0 -15
- data/tests/json_fixtures_test.rb +0 -32
- data/tests/json_generator_test.rb +0 -421
- data/tests/json_generic_object_test.rb +0 -82
- data/tests/json_parser_test.rb +0 -472
- data/tests/json_string_matching_test.rb +0 -38
- data/tests/test_helper.rb +0 -17
- data/tools/diff.sh +0 -18
- data/tools/fuzz.rb +0 -131
- data/tools/server.rb +0 -62
data/lib/json/pure/generator.rb
CHANGED
|
@@ -37,20 +37,26 @@ module JSON
|
|
|
37
37
|
'\\' => '\\\\',
|
|
38
38
|
} # :nodoc:
|
|
39
39
|
|
|
40
|
+
ESCAPE_SLASH_MAP = MAP.merge(
|
|
41
|
+
'/' => '\\/',
|
|
42
|
+
)
|
|
43
|
+
|
|
40
44
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
|
41
45
|
# UTF16 big endian characters as \u????, and return it.
|
|
42
|
-
def utf8_to_json(string) # :nodoc:
|
|
46
|
+
def utf8_to_json(string, escape_slash = false) # :nodoc:
|
|
43
47
|
string = string.dup
|
|
44
48
|
string.force_encoding(::Encoding::ASCII_8BIT)
|
|
45
|
-
|
|
49
|
+
map = escape_slash ? ESCAPE_SLASH_MAP : MAP
|
|
50
|
+
string.gsub!(/[\/"\\\x0-\x1f]/) { map[$&] || $& }
|
|
46
51
|
string.force_encoding(::Encoding::UTF_8)
|
|
47
52
|
string
|
|
48
53
|
end
|
|
49
54
|
|
|
50
|
-
def utf8_to_json_ascii(string) # :nodoc:
|
|
55
|
+
def utf8_to_json_ascii(string, escape_slash = false) # :nodoc:
|
|
51
56
|
string = string.dup
|
|
52
57
|
string.force_encoding(::Encoding::ASCII_8BIT)
|
|
53
|
-
|
|
58
|
+
map = escape_slash ? ESCAPE_SLASH_MAP : MAP
|
|
59
|
+
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
|
54
60
|
string.gsub!(/(
|
|
55
61
|
(?:
|
|
56
62
|
[\xc2-\xdf][\x80-\xbf] |
|
|
@@ -109,6 +115,7 @@ module JSON
|
|
|
109
115
|
# * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
|
110
116
|
# * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
|
111
117
|
# * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
|
118
|
+
# * *escape_slash*: true if forward slash (/) should be escaped (default: false)
|
|
112
119
|
# * *check_circular*: is deprecated now, use the :max_nesting option instead,
|
|
113
120
|
# * *max_nesting*: sets the maximum level of data structure nesting in
|
|
114
121
|
# the generated JSON, max_nesting = 0 if no maximum should be checked.
|
|
@@ -123,6 +130,7 @@ module JSON
|
|
|
123
130
|
@array_nl = ''
|
|
124
131
|
@allow_nan = false
|
|
125
132
|
@ascii_only = false
|
|
133
|
+
@escape_slash = false
|
|
126
134
|
@buffer_initial_length = 1024
|
|
127
135
|
configure opts
|
|
128
136
|
end
|
|
@@ -148,6 +156,10 @@ module JSON
|
|
|
148
156
|
# the generated JSON, max_nesting = 0 if no maximum is checked.
|
|
149
157
|
attr_accessor :max_nesting
|
|
150
158
|
|
|
159
|
+
# If this attribute is set to true, forward slashes will be escaped in
|
|
160
|
+
# all json strings.
|
|
161
|
+
attr_accessor :escape_slash
|
|
162
|
+
|
|
151
163
|
# :stopdoc:
|
|
152
164
|
attr_reader :buffer_initial_length
|
|
153
165
|
|
|
@@ -187,6 +199,11 @@ module JSON
|
|
|
187
199
|
@ascii_only
|
|
188
200
|
end
|
|
189
201
|
|
|
202
|
+
# Returns true, if forward slashes are escaped. Otherwise returns false.
|
|
203
|
+
def escape_slash?
|
|
204
|
+
@escape_slash
|
|
205
|
+
end
|
|
206
|
+
|
|
190
207
|
# Configure this State instance with the Hash _opts_, and return
|
|
191
208
|
# itself.
|
|
192
209
|
def configure(opts)
|
|
@@ -209,6 +226,7 @@ module JSON
|
|
|
209
226
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
|
210
227
|
@depth = opts[:depth] || 0
|
|
211
228
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
|
229
|
+
@escape_slash = !!opts[:escape_slash] if opts.key?(:escape_slash)
|
|
212
230
|
|
|
213
231
|
if !opts.key?(:max_nesting) # defaults to 100
|
|
214
232
|
@max_nesting = 100
|
|
@@ -314,8 +332,10 @@ module JSON
|
|
|
314
332
|
first = false
|
|
315
333
|
}
|
|
316
334
|
depth = state.depth -= 1
|
|
317
|
-
|
|
318
|
-
|
|
335
|
+
unless first
|
|
336
|
+
result << state.object_nl
|
|
337
|
+
result << state.indent * depth if indent
|
|
338
|
+
end
|
|
319
339
|
result << '}'
|
|
320
340
|
result
|
|
321
341
|
end
|
|
@@ -399,13 +419,13 @@ module JSON
|
|
|
399
419
|
string = encode(::Encoding::UTF_8)
|
|
400
420
|
end
|
|
401
421
|
if state.ascii_only?
|
|
402
|
-
'"' << JSON.utf8_to_json_ascii(string) << '"'
|
|
422
|
+
'"' << JSON.utf8_to_json_ascii(string, state.escape_slash) << '"'
|
|
403
423
|
else
|
|
404
|
-
'"' << JSON.utf8_to_json(string) << '"'
|
|
424
|
+
'"' << JSON.utf8_to_json(string, state.escape_slash) << '"'
|
|
405
425
|
end
|
|
406
426
|
end
|
|
407
427
|
|
|
408
|
-
# Module that holds the
|
|
428
|
+
# Module that holds the extending methods if, the String module is
|
|
409
429
|
# included.
|
|
410
430
|
module Extend
|
|
411
431
|
# Raw Strings are JSON Objects (the raw bytes are stored in an
|
data/lib/json/pure/parser.rb
CHANGED
|
@@ -45,11 +45,11 @@ module JSON
|
|
|
45
45
|
/(?=\*/) # single slash before this comment's end
|
|
46
46
|
)*
|
|
47
47
|
\*/ # the End of this comment
|
|
48
|
-
|[ \t\r\n]+ # whitespaces: space,
|
|
48
|
+
|[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
|
|
49
49
|
)+
|
|
50
50
|
)mx
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
UNPARSED = Object.new.freeze
|
|
53
53
|
|
|
54
54
|
# Creates a new JSON::Pure::Parser instance for the string _source_.
|
|
55
55
|
#
|
|
@@ -61,12 +61,14 @@ module JSON
|
|
|
61
61
|
# * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
|
62
62
|
# defiance of RFC 7159 to be parsed by the Parser. This option defaults
|
|
63
63
|
# to false.
|
|
64
|
+
# * *freeze*: If set to true, all parsed objects will be frozen. Parsed
|
|
65
|
+
# string will be deduplicated if possible.
|
|
64
66
|
# * *symbolize_names*: If set to true, returns symbols for the names
|
|
65
67
|
# (keys) in a JSON object. Otherwise strings are returned, which is
|
|
66
68
|
# also the default. It's not possible to use this option in
|
|
67
69
|
# conjunction with the *create_additions* option.
|
|
68
70
|
# * *create_additions*: If set to true, the Parser creates
|
|
69
|
-
# additions when
|
|
71
|
+
# additions when a matching class and create_id are found. This
|
|
70
72
|
# option defaults to false.
|
|
71
73
|
# * *object_class*: Defaults to Hash
|
|
72
74
|
# * *array_class*: Defaults to Array
|
|
@@ -86,6 +88,7 @@ module JSON
|
|
|
86
88
|
end
|
|
87
89
|
@allow_nan = !!opts[:allow_nan]
|
|
88
90
|
@symbolize_names = !!opts[:symbolize_names]
|
|
91
|
+
@freeze = !!opts[:freeze]
|
|
89
92
|
if opts.key?(:create_additions)
|
|
90
93
|
@create_additions = !!opts[:create_additions]
|
|
91
94
|
else
|
|
@@ -120,6 +123,7 @@ module JSON
|
|
|
120
123
|
obj = parse_value
|
|
121
124
|
UNPARSED.equal?(obj) and raise ParserError,
|
|
122
125
|
"source is not valid JSON!"
|
|
126
|
+
obj.freeze if @freeze
|
|
123
127
|
end
|
|
124
128
|
while !eos? && skip(IGNORE) do end
|
|
125
129
|
eos? or raise ParserError, "source is not valid JSON!"
|
|
@@ -161,6 +165,7 @@ module JSON
|
|
|
161
165
|
EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
|
|
162
166
|
end
|
|
163
167
|
|
|
168
|
+
STR_UMINUS = ''.respond_to?(:-@)
|
|
164
169
|
def parse_string
|
|
165
170
|
if scan(STRING)
|
|
166
171
|
return '' if self[1].empty?
|
|
@@ -180,6 +185,15 @@ module JSON
|
|
|
180
185
|
if string.respond_to?(:force_encoding)
|
|
181
186
|
string.force_encoding(::Encoding::UTF_8)
|
|
182
187
|
end
|
|
188
|
+
|
|
189
|
+
if @freeze
|
|
190
|
+
if STR_UMINUS
|
|
191
|
+
string = -string
|
|
192
|
+
else
|
|
193
|
+
string.freeze
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
183
197
|
if @create_additions and @match_string
|
|
184
198
|
for (regexp, klass) in @match_string
|
|
185
199
|
klass.json_creatable? or next
|
|
@@ -242,8 +256,10 @@ module JSON
|
|
|
242
256
|
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
|
243
257
|
result = @array_class.new
|
|
244
258
|
delim = false
|
|
245
|
-
|
|
259
|
+
loop do
|
|
246
260
|
case
|
|
261
|
+
when eos?
|
|
262
|
+
raise ParserError, "unexpected end of string while parsing array"
|
|
247
263
|
when !UNPARSED.equal?(value = parse_value)
|
|
248
264
|
delim = false
|
|
249
265
|
result << value
|
|
@@ -274,8 +290,10 @@ module JSON
|
|
|
274
290
|
@max_nesting.nonzero? && @current_nesting > @max_nesting
|
|
275
291
|
result = @object_class.new
|
|
276
292
|
delim = false
|
|
277
|
-
|
|
293
|
+
loop do
|
|
278
294
|
case
|
|
295
|
+
when eos?
|
|
296
|
+
raise ParserError, "unexpected end of string while parsing object"
|
|
279
297
|
when !UNPARSED.equal?(string = parse_string)
|
|
280
298
|
skip(IGNORE)
|
|
281
299
|
unless scan(PAIR_DELIMITER)
|
data/lib/json/version.rb
CHANGED