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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +71 -5
  3. data/README.md +19 -3
  4. data/VERSION +1 -1
  5. data/ext/json/ext/generator/generator.c +132 -23
  6. data/ext/json/ext/generator/generator.h +5 -2
  7. data/ext/json/ext/parser/extconf.rb +26 -0
  8. data/ext/json/ext/parser/parser.c +2979 -1768
  9. data/ext/json/ext/parser/parser.h +6 -1
  10. data/ext/json/ext/parser/parser.rl +128 -38
  11. data/ext/json/extconf.rb +1 -0
  12. data/json.gemspec +0 -0
  13. data/lib/json/add/complex.rb +0 -1
  14. data/lib/json/add/rational.rb +0 -1
  15. data/lib/json/common.rb +370 -123
  16. data/lib/json/pure/generator.rb +29 -9
  17. data/lib/json/pure/parser.rb +23 -5
  18. data/lib/json/version.rb +1 -1
  19. data/lib/json.rb +549 -29
  20. metadata +17 -109
  21. data/.gitignore +0 -18
  22. data/.travis.yml +0 -24
  23. data/Gemfile +0 -14
  24. data/README-json-jruby.md +0 -33
  25. data/Rakefile +0 -413
  26. data/diagrams/.keep +0 -0
  27. data/install.rb +0 -23
  28. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  29. data/java/src/json/ext/Generator.java +0 -466
  30. data/java/src/json/ext/GeneratorMethods.java +0 -231
  31. data/java/src/json/ext/GeneratorService.java +0 -42
  32. data/java/src/json/ext/GeneratorState.java +0 -490
  33. data/java/src/json/ext/OptionsReader.java +0 -113
  34. data/java/src/json/ext/Parser.java +0 -2362
  35. data/java/src/json/ext/Parser.rl +0 -893
  36. data/java/src/json/ext/ParserService.java +0 -34
  37. data/java/src/json/ext/RuntimeInfo.java +0 -116
  38. data/java/src/json/ext/StringDecoder.java +0 -166
  39. data/java/src/json/ext/StringEncoder.java +0 -111
  40. data/java/src/json/ext/Utils.java +0 -88
  41. data/json-java.gemspec +0 -37
  42. data/json_pure.gemspec +0 -38
  43. data/lib/json/ext/.keep +0 -0
  44. data/references/rfc7159.txt +0 -899
  45. data/tests/fixtures/fail10.json +0 -1
  46. data/tests/fixtures/fail11.json +0 -1
  47. data/tests/fixtures/fail12.json +0 -1
  48. data/tests/fixtures/fail13.json +0 -1
  49. data/tests/fixtures/fail14.json +0 -1
  50. data/tests/fixtures/fail18.json +0 -1
  51. data/tests/fixtures/fail19.json +0 -1
  52. data/tests/fixtures/fail2.json +0 -1
  53. data/tests/fixtures/fail20.json +0 -1
  54. data/tests/fixtures/fail21.json +0 -1
  55. data/tests/fixtures/fail22.json +0 -1
  56. data/tests/fixtures/fail23.json +0 -1
  57. data/tests/fixtures/fail24.json +0 -1
  58. data/tests/fixtures/fail25.json +0 -1
  59. data/tests/fixtures/fail27.json +0 -2
  60. data/tests/fixtures/fail28.json +0 -2
  61. data/tests/fixtures/fail3.json +0 -1
  62. data/tests/fixtures/fail4.json +0 -1
  63. data/tests/fixtures/fail5.json +0 -1
  64. data/tests/fixtures/fail6.json +0 -1
  65. data/tests/fixtures/fail7.json +0 -1
  66. data/tests/fixtures/fail8.json +0 -1
  67. data/tests/fixtures/fail9.json +0 -1
  68. data/tests/fixtures/obsolete_fail1.json +0 -1
  69. data/tests/fixtures/pass1.json +0 -56
  70. data/tests/fixtures/pass15.json +0 -1
  71. data/tests/fixtures/pass16.json +0 -1
  72. data/tests/fixtures/pass17.json +0 -1
  73. data/tests/fixtures/pass2.json +0 -1
  74. data/tests/fixtures/pass26.json +0 -1
  75. data/tests/fixtures/pass3.json +0 -6
  76. data/tests/json_addition_test.rb +0 -203
  77. data/tests/json_common_interface_test.rb +0 -126
  78. data/tests/json_encoding_test.rb +0 -107
  79. data/tests/json_ext_parser_test.rb +0 -15
  80. data/tests/json_fixtures_test.rb +0 -32
  81. data/tests/json_generator_test.rb +0 -421
  82. data/tests/json_generic_object_test.rb +0 -82
  83. data/tests/json_parser_test.rb +0 -472
  84. data/tests/json_string_matching_test.rb +0 -38
  85. data/tests/test_helper.rb +0 -17
  86. data/tools/diff.sh +0 -18
  87. data/tools/fuzz.rb +0 -131
  88. data/tools/server.rb +0 -62
@@ -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
- string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
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
- string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
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
- result << state.object_nl
318
- result << state.indent * depth if indent
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 extinding methods if, the String module is
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
@@ -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, horicontal tab, lf, cr
48
+ |[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
49
49
  )+
50
50
  )mx
51
51
 
52
- UNPARSED = Object.new.freeze
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 if a matching class and create_id was found. This
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
- until eos?
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
- until eos?
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
  module JSON
3
3
  # JSON version
4
- VERSION = '2.3.0'
4
+ VERSION = '2.6.2'
5
5
  VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
6
6
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
7
7
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: