json 2.13.2-java → 2.14.1-java

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e1146df87fba610f29050546afdc904b565aca136b9e9e5a815ddc9d86f8b6c
4
- data.tar.gz: 0cb8e8662eaa8f5c5e97a694be6b1a2f5d832dd726dbbea6845d8984c7a1cd3d
3
+ metadata.gz: d2e31ae12a6d5034bd9ece1f72e955b04ab82b8ee182cfe12c0746742dcb0c3b
4
+ data.tar.gz: 9fdeb6ef792a44b0ac7889c304d2ea5cec04b6a87717e81398e53492e764b945
5
5
  SHA512:
6
- metadata.gz: 8a5f4c9e18fda421d6366f34abe83705282803817ddb6bc4d52850f99b38a4c71cf3ed47430b76170899e502eb3dd9783a8053f00b44cd35343666eb4c2ddef7
7
- data.tar.gz: 59e76070919e3c5ce9ce323172e2c61e8338b6a2ab5361bcdc63e3e54eb03df92921189dbd8268a194ed4e7a8e3e218b3337af97e174b54a858ceb2b83d3a9a9
6
+ metadata.gz: 964c3d63ff720ff366b714c1cf0449a3ecb5066713f8229085d2ba5df1559f0e858e4ee97337ba0d4aa926eb1b70734c799f5a1f9bad804ae24bb6f4688d8b89
7
+ data.tar.gz: fac0e89fa2d81a0ed82f08c7b70cbb39d319440c95f291f59ae95012d11e940080dc821a3cd19a5f093cae10ef696611e0924b49baf034f90cd39430606a6299
data/CHANGES.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 2025-09-18 (2.14.1)
6
+
7
+ * Fix `IndexOutOfBoundsException` in the JRuby extension when encoding shared strings.
8
+
9
+ ### 2025-09-18 (2.14.0)
10
+
11
+ * Add new `allow_duplicate_key` generator options. By default a warning is now emitted when a duplicated key is encountered.
12
+ In `json 3.0` an error will be raised.
13
+ ```ruby
14
+ >> Warning[:deprecated] = true
15
+ >> puts JSON.generate({ foo: 1, "foo" => 2 })
16
+ (irb):2: warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
17
+ This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
18
+ {"foo":1,"foo":2}
19
+ >> JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
20
+ detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
21
+ ```
22
+ * Fix `JSON.generate` `strict: true` mode to also restrict hash keys.
23
+ * Fix `JSON::Coder` to also invoke block for hash keys that aren't strings nor symbols.
24
+ * Fix `JSON.unsafe_load` usage with proc
25
+ * Fix the parser to more consistently reject invalid UTF-16 surogate pairs.
26
+
5
27
  ### 2025-07-28 (2.13.2)
6
28
 
7
29
  * Improve duplicate key warning and errors to include the key name and point to the right caller.
@@ -44,7 +66,7 @@
44
66
  ### 2025-04-24 (2.11.1)
45
67
 
46
68
  * Add back `JSON.restore`, `JSON.unparse`, `JSON.fast_unparse` and `JSON.pretty_unparse`.
47
- These were deprecated 16 years ago, but never emited warnings, only undocumented, so are
69
+ These were deprecated 16 years ago, but never emitted warnings, only undocumented, so are
48
70
  still used by a few gems.
49
71
 
50
72
  ### 2025-04-24 (2.11.0)
@@ -71,7 +93,7 @@
71
93
  ### 2025-03-12 (2.10.2)
72
94
 
73
95
  * Fix a potential crash in the C extension parser.
74
- * Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` unadvertently changed it.
96
+ * Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` inadvertently changed it.
75
97
  * Ensure document snippets that are included in parser errors don't include truncated multibyte characters.
76
98
  * Ensure parser error snippets are valid UTF-8.
77
99
  * Fix `JSON::GeneratorError#detailed_message` on Ruby < 3.2
@@ -102,7 +124,7 @@
102
124
 
103
125
  ### 2024-11-14 (2.8.2)
104
126
 
105
- * `JSON.load_file` explictly read the file as UTF-8.
127
+ * `JSON.load_file` explicitly read the file as UTF-8.
106
128
 
107
129
  ### 2024-11-06 (2.8.1)
108
130
 
@@ -110,7 +132,7 @@
110
132
 
111
133
  ### 2024-11-06 (2.8.0)
112
134
 
113
- * Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explictly enabled.
135
+ * Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explicitly enabled.
114
136
  * Prefer to use `JSON.unsafe_load(string)` or `JSON.load(string, create_additions: true)`.
115
137
  * Emit a deprecation warning when serializing valid UTF-8 strings encoded in `ASCII_8BIT` aka `BINARY`.
116
138
  * Bump required Ruby version to 2.7.
@@ -118,7 +140,7 @@
118
140
  pre-existing support for comments, make it suitable to parse `jsonc` documents.
119
141
  * Many performance improvements to `JSON.parse` and `JSON.load`, up to `1.7x` faster on real world documents.
120
142
  * Some minor performance improvements to `JSON.dump` and `JSON.generate`.
121
- * `JSON.pretty_generate` no longer include newline inside empty object and arrays.
143
+ * `JSON.pretty_generate` no longer includes newlines inside empty object and arrays.
122
144
 
123
145
  ### 2024-11-04 (2.7.6)
124
146
 
@@ -135,13 +157,13 @@
135
157
  * Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490.
136
158
  This bug would cause some gems with native extension to fail during compilation.
137
159
  * Workaround different versions of `json` and `json_pure` being loaded (not officially supported).
138
- * Make `json_pure` Ractor compatible.
160
+ * Make `json_pure` Ractor compatible.
139
161
 
140
162
  ### 2024-10-24 (2.7.3)
141
163
 
142
164
  * Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster).
143
- * Limit the size of ParserError exception messages, only include up to 32 bytes of the unparseable source.
144
- * Fix json-pure's `Object#to_json` to accept non state arguments
165
+ * Limit the size of ParserError exception messages, only include up to 32 bytes of the unparsable source.
166
+ * Fix json-pure's `Object#to_json` to accept non-state arguments.
145
167
  * Fix multiline comment support in `json-pure`.
146
168
  * Fix `JSON.parse` to no longer mutate the argument encoding when passed an ASCII-8BIT string.
147
169
  * Fix `String#to_json` to raise on invalid encoding in `json-pure`.
@@ -286,6 +308,7 @@
286
308
  ## 2015-09-11 (2.0.0)
287
309
  * Now complies to newest JSON RFC 7159.
288
310
  * Implements compatibility to ruby 2.4 integer unification.
311
+ * Removed support for `quirks_mode` option.
289
312
  * Drops support for old rubies whose life has ended, that is rubies < 2.0.
290
313
  Also see https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/
291
314
  * There were still some mentions of dual GPL licensing in the source, but JSON
data/lib/json/add/core.rb CHANGED
@@ -7,6 +7,7 @@ require 'json/add/date_time'
7
7
  require 'json/add/exception'
8
8
  require 'json/add/range'
9
9
  require 'json/add/regexp'
10
+ require 'json/add/string'
10
11
  require 'json/add/struct'
11
12
  require 'json/add/symbol'
12
13
  require 'json/add/time'
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
3
+ require 'json'
4
+ end
5
+
6
+ class String
7
+ # call-seq: json_create(o)
8
+ #
9
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
10
+ # key "raw"). The Ruby String can be created by this class method.
11
+ def self.json_create(object)
12
+ object["raw"].pack("C*")
13
+ end
14
+
15
+ # call-seq: to_json_raw_object()
16
+ #
17
+ # This method creates a raw object hash, that can be nested into
18
+ # other data structures and will be generated as a raw string. This
19
+ # method should be used, if you want to convert raw strings to JSON
20
+ # instead of UTF-8 strings, e. g. binary data.
21
+ def to_json_raw_object
22
+ {
23
+ JSON.create_id => self.class.name,
24
+ "raw" => unpack("C*"),
25
+ }
26
+ end
27
+
28
+ # call-seq: to_json_raw(*args)
29
+ #
30
+ # This method creates a JSON text from the result of a call to
31
+ # to_json_raw_object of this String.
32
+ def to_json_raw(...)
33
+ to_json_raw_object.to_json(...)
34
+ end
35
+ end
data/lib/json/common.rb CHANGED
@@ -73,7 +73,7 @@ module JSON
73
73
  if opts[:create_additions] != false
74
74
  if class_name = object[JSON.create_id]
75
75
  klass = JSON.deep_const_get(class_name)
76
- if (klass.respond_to?(:json_creatable?) && klass.json_creatable?) || klass.respond_to?(:json_create)
76
+ if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
77
77
  create_additions_warning if create_additions.nil?
78
78
  object = klass.json_create(object)
79
79
  end
@@ -97,7 +97,7 @@ module JSON
97
97
 
98
98
  class << self
99
99
  def deprecation_warning(message, uplevel = 3) # :nodoc:
100
- gem_root = File.expand_path("../../../", __FILE__) + "/"
100
+ gem_root = File.expand_path("..", __dir__) + "/"
101
101
  caller_locations(uplevel, 10).each do |frame|
102
102
  if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
103
103
  uplevel += 1
@@ -186,6 +186,25 @@ module JSON
186
186
 
187
187
  private
188
188
 
189
+ # Called from the extension when a hash has both string and symbol keys
190
+ def on_mixed_keys_hash(hash, do_raise)
191
+ set = {}
192
+ hash.each_key do |key|
193
+ key_str = key.to_s
194
+
195
+ if set[key_str]
196
+ message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
197
+ if do_raise
198
+ raise GeneratorError, message
199
+ else
200
+ deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
201
+ end
202
+ else
203
+ set[key_str] = true
204
+ end
205
+ end
206
+ end
207
+
189
208
  def deprecated_singleton_attr_accessor(*attrs)
190
209
  args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
191
210
  attrs.each do |attr|
@@ -391,7 +410,7 @@ module JSON
391
410
  #
392
411
  # Returns a \String containing the generated \JSON data.
393
412
  #
394
- # See also JSON.fast_generate, JSON.pretty_generate.
413
+ # See also JSON.pretty_generate.
395
414
  #
396
415
  # Argument +obj+ is the Ruby object to be converted to \JSON.
397
416
  #
@@ -643,6 +662,7 @@ module JSON
643
662
  # when Array
644
663
  # obj.map! {|v| deserialize_obj v }
645
664
  # end
665
+ # obj
646
666
  # })
647
667
  # pp ruby
648
668
  # Output:
@@ -684,9 +704,13 @@ module JSON
684
704
  if opts[:allow_blank] && (source.nil? || source.empty?)
685
705
  source = 'null'
686
706
  end
687
- result = parse(source, opts)
688
- recurse_proc(result, &proc) if proc
689
- result
707
+
708
+ if proc
709
+ opts = opts.dup
710
+ opts[:on_load] = proc.to_proc
711
+ end
712
+
713
+ parse(source, opts)
690
714
  end
691
715
 
692
716
  # :call-seq:
@@ -803,6 +827,7 @@ module JSON
803
827
  # when Array
804
828
  # obj.map! {|v| deserialize_obj v }
805
829
  # end
830
+ # obj
806
831
  # })
807
832
  # pp ruby
808
833
  # Output:
@@ -1002,7 +1027,7 @@ module JSON
1002
1027
  # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
1003
1028
  #
1004
1029
  # For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
1005
- # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1030
+ # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1006
1031
  # \JSON counterpart:
1007
1032
  #
1008
1033
  # module MyApp
@@ -8,20 +8,8 @@ module JSON
8
8
  #
9
9
  # Instantiates a new State object, configured by _opts_.
10
10
  #
11
- # _opts_ can have the following keys:
12
- #
13
- # * *indent*: a string used to indent levels (default: ''),
14
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
15
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
16
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
17
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
18
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
19
- # generated, otherwise an exception is thrown, if these values are
20
- # encountered. This options defaults to false.
21
- # * *ascii_only*: true if only ASCII characters should be generated. This
22
- # option defaults to false.
23
- # * *buffer_initial_length*: sets the initial length of the generator's
24
- # internal buffer.
11
+ # Argument +opts+, if given, contains a \Hash of options for the generation.
12
+ # See {Generating Options}[#module-JSON-label-Generating+Options].
25
13
  def initialize(opts = nil)
26
14
  if opts && !opts.empty?
27
15
  configure(opts)
@@ -68,6 +56,11 @@ module JSON
68
56
  buffer_initial_length: buffer_initial_length,
69
57
  }
70
58
 
59
+ allow_duplicate_key = allow_duplicate_key?
60
+ unless allow_duplicate_key.nil?
61
+ result[:allow_duplicate_key] = allow_duplicate_key
62
+ end
63
+
71
64
  instance_variables.each do |iv|
72
65
  iv = iv.to_s[1..-1]
73
66
  result[iv.to_sym] = self[iv]
Binary file
Binary file
@@ -52,14 +52,6 @@ module JSON
52
52
  table
53
53
  end
54
54
 
55
- def [](name)
56
- __send__(name)
57
- end unless method_defined?(:[])
58
-
59
- def []=(name, value)
60
- __send__("#{name}=", value)
61
- end unless method_defined?(:[]=)
62
-
63
55
  def |(other)
64
56
  self.class[other.to_hash.merge(to_hash)]
65
57
  end
@@ -271,6 +271,12 @@ module JSON
271
271
  false
272
272
  end
273
273
 
274
+ if opts.key?(:allow_duplicate_key)
275
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
276
+ else
277
+ @allow_duplicate_key = nil # nil is deprecation
278
+ end
279
+
274
280
  @strict = !!opts[:strict] if opts.key?(:strict)
275
281
 
276
282
  if !opts.key?(:max_nesting) # defaults to 100
@@ -284,6 +290,10 @@ module JSON
284
290
  end
285
291
  alias merge configure
286
292
 
293
+ def allow_duplicate_key? # :nodoc:
294
+ @allow_duplicate_key
295
+ end
296
+
287
297
  # Returns the configuration instance variables as a hash, that can be
288
298
  # passed to the configure method.
289
299
  def to_h
@@ -292,6 +302,11 @@ module JSON
292
302
  iv = iv.to_s[1..-1]
293
303
  result[iv.to_sym] = self[iv]
294
304
  end
305
+
306
+ if result[:allow_duplicate_key].nil?
307
+ result.delete(:allow_duplicate_key)
308
+ end
309
+
295
310
  result
296
311
  end
297
312
 
@@ -330,8 +345,17 @@ module JSON
330
345
  when Hash
331
346
  buf << '{'
332
347
  first = true
348
+ key_type = nil
333
349
  obj.each_pair do |k,v|
334
- buf << ',' unless first
350
+ if first
351
+ key_type = k.class
352
+ else
353
+ if key_type && !@allow_duplicate_key && key_type != k.class
354
+ key_type = nil # stop checking
355
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
356
+ end
357
+ buf << ','
358
+ end
335
359
 
336
360
  key_str = k.to_s
337
361
  if key_str.class == String
@@ -471,11 +495,30 @@ module JSON
471
495
  delim = ",#{state.object_nl}"
472
496
  result = +"{#{state.object_nl}"
473
497
  first = true
498
+ key_type = nil
474
499
  indent = !state.object_nl.empty?
475
500
  each { |key, value|
476
- result << delim unless first
501
+ if first
502
+ key_type = key.class
503
+ else
504
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
505
+ key_type = nil # stop checking
506
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
507
+ end
508
+ result << delim
509
+ end
477
510
  result << state.indent * depth if indent
478
511
 
512
+ if state.strict? && !(Symbol === key || String === key)
513
+ if state.as_json
514
+ key = state.as_json.call(key)
515
+ end
516
+
517
+ unless Symbol === key || String === key
518
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", value)
519
+ end
520
+ end
521
+
479
522
  key_str = key.to_s
480
523
  if key_str.is_a?(String)
481
524
  key_json = key_str.to_json(state)
@@ -635,39 +678,6 @@ module JSON
635
678
  rescue Encoding::UndefinedConversionError => error
636
679
  raise ::JSON::GeneratorError.new(error.message, self)
637
680
  end
638
-
639
- # Module that holds the extending methods if, the String module is
640
- # included.
641
- module Extend
642
- # Raw Strings are JSON Objects (the raw bytes are stored in an
643
- # array for the key "raw"). The Ruby String can be created by this
644
- # module method.
645
- def json_create(o)
646
- o['raw'].pack('C*')
647
- end
648
- end
649
-
650
- # Extends _modul_ with the String::Extend module.
651
- def self.included(modul)
652
- modul.extend Extend
653
- end
654
-
655
- # This method creates a raw object hash, that can be nested into
656
- # other data structures and will be unparsed as a raw string. This
657
- # method should be used, if you want to convert raw strings to JSON
658
- # instead of UTF-8 strings, e. g. binary data.
659
- def to_json_raw_object
660
- {
661
- JSON.create_id => self.class.name,
662
- 'raw' => self.unpack('C*'),
663
- }
664
- end
665
-
666
- # This method creates a JSON text from the result of
667
- # a call to to_json_raw_object of this String.
668
- def to_json_raw(*args)
669
- to_json_raw_object.to_json(*args)
670
- end
671
681
  end
672
682
 
673
683
  module TrueClass
data/lib/json/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.13.2'
4
+ VERSION = '2.14.1'
5
5
  end
data/lib/json.rb CHANGED
@@ -133,7 +133,7 @@ require 'json/common'
133
133
  # When not specified:
134
134
  # # The last value is used and a deprecation warning emitted.
135
135
  # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
136
- # # waring: detected duplicate keys in JSON object.
136
+ # # warning: detected duplicate keys in JSON object.
137
137
  # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
138
138
  #
139
139
  # When set to `+true+`
@@ -307,6 +307,25 @@ require 'json/common'
307
307
  #
308
308
  # ---
309
309
  #
310
+ # Option +allow_duplicate_key+ (boolean) specifies whether
311
+ # hashes with duplicate keys should be allowed or produce an error.
312
+ # defaults to emit a deprecation warning.
313
+ #
314
+ # With the default, (not set):
315
+ # Warning[:deprecated] = true
316
+ # JSON.generate({ foo: 1, "foo" => 2 })
317
+ # # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
318
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
319
+ # # => '{"foo":1,"foo":2}'
320
+ #
321
+ # With <tt>false</tt>
322
+ # JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
323
+ # # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
324
+ #
325
+ # In version 3.0, <tt>false</tt> will become the default.
326
+ #
327
+ # ---
328
+ #
310
329
  # Option +max_nesting+ (\Integer) specifies the maximum nesting depth
311
330
  # in +obj+; defaults to +100+.
312
331
  #
@@ -384,6 +403,9 @@ require 'json/common'
384
403
  #
385
404
  # == \JSON Additions
386
405
  #
406
+ # Note that JSON Additions must only be used with trusted data, and is
407
+ # deprecated.
408
+ #
387
409
  # When you "round trip" a non-\String object from Ruby to \JSON and back,
388
410
  # you have a new \String, instead of the object you began with:
389
411
  # ruby0 = Range.new(0, 2)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.2
4
+ version: 2.14.1
5
5
  platform: java
6
6
  authors:
7
7
  - Daniel Luz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-28 00:00:00.000000000 Z
11
+ date: 2025-09-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A JSON implementation as a JRuby extension.
14
14
  email: dev+ruby@mernen.com
@@ -35,6 +35,7 @@ files:
35
35
  - lib/json/add/rational.rb
36
36
  - lib/json/add/regexp.rb
37
37
  - lib/json/add/set.rb
38
+ - lib/json/add/string.rb
38
39
  - lib/json/add/struct.rb
39
40
  - lib/json/add/symbol.rb
40
41
  - lib/json/add/time.rb