json 2.7.5 → 2.7.6

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: 8138305febf8acb1cc4533b5e5b071928167b88f17567cf18d99fc1dcbeef234
4
- data.tar.gz: 9648ecf580a9f686cd1fb879efbeb85509c800f13c1372e282298eb713dce740
3
+ metadata.gz: 065f3d9d7ea71adff1e29821c3cac1ebcab3ab3fa8ffc5254d4977c61b998fd4
4
+ data.tar.gz: d0ec44d829e429395f42191ac8bf91e6be4498e3c4bba37eb7fdf3ad1cfce80f
5
5
  SHA512:
6
- metadata.gz: 6a34f95616a3ac364d06004e8b2049c36b760206553e2596993af96cf295755019c083f2e1a51b931829dc199c2ebc919dfbac2079be9c7198b8ed03ae999df6
7
- data.tar.gz: fbd73f6e5fa24dd5406556a0dba0ad8cb7d3c704700d29322eded2a2bc6405a16dd12d7cadd6792153970b7dfbbf013dddf70d626ae05609c57a76c4401de950
6
+ metadata.gz: 59f4e6204591c6fa2204e30ae4e663f5d5f6d89cfc44a26174da1a17cd720cd6594ad047b98933295a33f793b89e97c7952095bedda1d25f378b7a99ead84b04
7
+ data.tar.gz: 7438175fc69f92a7aa2a13b7599b417111562d9edfd94987dec4f94c37e5f2b152a6025d2f6ed2d49d246f0b0e3fe53a71038c9c59e7f826e8d3c2e09e40994a
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changes
2
2
 
3
+ ### 2024-11-04 (2.7.6)
4
+
5
+ * Fix a regression in JSON.generate when dealing with Hash keys that are string subclasses, call `to_json` on them.
6
+
3
7
  ### 2024-10-25 (2.7.5)
4
8
 
5
9
  * Fix a memory leak when `#to_json` methods raise an exception.
@@ -36,6 +36,10 @@ static VALUE fbuffer_to_s(FBuffer *fb);
36
36
  #define RB_UNLIKELY(expr) expr
37
37
  #endif
38
38
 
39
+ #ifndef RB_LIKELY
40
+ #define RB_LIKELY(expr) expr
41
+ #endif
42
+
39
43
  static FBuffer *fbuffer_alloc(unsigned long initial_length)
40
44
  {
41
45
  FBuffer *fb;
@@ -668,7 +668,11 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
668
668
  VALUE key_to_s;
669
669
  switch(rb_type(key)) {
670
670
  case T_STRING:
671
- key_to_s = key;
671
+ if (RB_LIKELY(RBASIC_CLASS(key) == rb_cString)) {
672
+ key_to_s = key;
673
+ } else {
674
+ key_to_s = rb_funcall(key, i_to_s, 0);
675
+ }
672
676
  break;
673
677
  case T_SYMBOL:
674
678
  key_to_s = rb_sym2str(key);
@@ -678,7 +682,11 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
678
682
  break;
679
683
  }
680
684
 
681
- generate_json_string(buffer, Vstate, state, key_to_s);
685
+ if (RB_LIKELY(RBASIC_CLASS(key_to_s) == rb_cString)) {
686
+ generate_json_string(buffer, Vstate, state, key_to_s);
687
+ } else {
688
+ generate_json(buffer, Vstate, state, key_to_s);
689
+ }
682
690
  if (RB_UNLIKELY(state->space_before)) fbuffer_append(buffer, state->space_before, state->space_before_len);
683
691
  fbuffer_append_char(buffer, ':');
684
692
  if (RB_UNLIKELY(state->space)) fbuffer_append(buffer, state->space, state->space_len);
@@ -301,19 +301,30 @@ module JSON
301
301
 
302
302
  # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
303
303
  private def generate_json(obj, buf)
304
- case obj
305
- when Hash
304
+ klass = obj.class
305
+ if klass == Hash
306
306
  buf << '{'
307
307
  first = true
308
308
  obj.each_pair do |k,v|
309
309
  buf << ',' unless first
310
- fast_serialize_string(k.to_s, buf)
310
+
311
+ key_str = k.to_s
312
+ if key_str.is_a?(::String)
313
+ if key_str.class == ::String
314
+ fast_serialize_string(key_str, buf)
315
+ else
316
+ generate_json(key_str, buf)
317
+ end
318
+ else
319
+ raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String"
320
+ end
321
+
311
322
  buf << ':'
312
323
  generate_json(v, buf)
313
324
  first = false
314
325
  end
315
326
  buf << '}'
316
- when Array
327
+ elsif klass == Array
317
328
  buf << '['
318
329
  first = true
319
330
  obj.each do |e|
@@ -322,9 +333,9 @@ module JSON
322
333
  first = false
323
334
  end
324
335
  buf << ']'
325
- when String
336
+ elsif klass == String
326
337
  fast_serialize_string(obj, buf)
327
- when Integer
338
+ elsif klass == Integer
328
339
  buf << obj.to_s
329
340
  else
330
341
  # Note: Float is handled this way since Float#to_s is slow anyway
@@ -414,7 +425,15 @@ module JSON
414
425
  each { |key, value|
415
426
  result << delim unless first
416
427
  result << state.indent * depth if indent
417
- result = +"#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
428
+
429
+ key_str = key.to_s
430
+ key_json = if key_str.is_a?(::String)
431
+ key_str = key_str.to_json(state)
432
+ else
433
+ raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
434
+ end
435
+
436
+ result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
418
437
  if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
419
438
  raise GeneratorError, "#{value.class} not allowed in JSON"
420
439
  elsif value.respond_to?(:to_json)
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.7.5'
4
+ VERSION = '2.7.6'
5
5
  end
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.7.5
4
+ version: 2.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-30 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a JSON implementation as a Ruby extension in C.
14
14
  email: flori@ping.de