json 2.7.4.rc2 → 2.7.5

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: ece06287b0082ae4ee021f7ac2c889b1ac17705eeb099713c4cc1cb9f81c311f
4
- data.tar.gz: be8843f180f122ea54b09c1c4cfc6f73a30dae5331e113d6868aa094180ac1f1
3
+ metadata.gz: 8138305febf8acb1cc4533b5e5b071928167b88f17567cf18d99fc1dcbeef234
4
+ data.tar.gz: 9648ecf580a9f686cd1fb879efbeb85509c800f13c1372e282298eb713dce740
5
5
  SHA512:
6
- metadata.gz: 8c547bfaddc079ca0d9309861d9fb44f8e447a9a04b538d87e7879aa3160bd9e7728ca800252f4f01e9eec02305d6a3736deab0de0bf3176d873e071ca510c0e
7
- data.tar.gz: 0f3dd6c721b0cb64154caf51f02bef90955a5377bcf01d44bcc2e8268771fa27186dd8d29485a027128cab386b1e7ab8f243c5c9799befebfbbc98730d2147aa
6
+ metadata.gz: 6a34f95616a3ac364d06004e8b2049c36b760206553e2596993af96cf295755019c083f2e1a51b931829dc199c2ebc919dfbac2079be9c7198b8ed03ae999df6
7
+ data.tar.gz: fbd73f6e5fa24dd5406556a0dba0ad8cb7d3c704700d29322eded2a2bc6405a16dd12d7cadd6792153970b7dfbbf013dddf70d626ae05609c57a76c4401de950
data/CHANGES.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changes
2
2
 
3
+ ### 2024-10-25 (2.7.5)
4
+
5
+ * Fix a memory leak when `#to_json` methods raise an exception.
6
+ * Gracefully handle formatting configs being set to `nil` instead of `""`.
7
+ * Workaround another issue caused by conflicting versions of both `json_pure` and `json` being loaded.
8
+
9
+ ### 2024-10-25 (2.7.4)
10
+
11
+ * Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490.
12
+ This bug would cause some gems with native extension to fail during compilation.
13
+ * Workaround different versions of `json` and `json_pure` being loaded (not officially supported).
14
+ * Make `json_pure` Ractor compatible.
15
+
3
16
  ### 2024-10-24 (2.7.3)
4
17
 
5
18
  * Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster).
@@ -403,7 +403,9 @@ static char *fstrndup(const char *ptr, unsigned long len) {
403
403
  */
404
404
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
405
405
  {
406
- GENERATE_JSON(object);
406
+ rb_check_arity(argc, 0, 1);
407
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
408
+ return cState_partial_generate(Vstate, self, generate_json_object);
407
409
  }
408
410
 
409
411
  /*
@@ -415,7 +417,9 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
415
417
  * produced JSON string output further.
416
418
  */
417
419
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
418
- GENERATE_JSON(array);
420
+ rb_check_arity(argc, 0, 1);
421
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
422
+ return cState_partial_generate(Vstate, self, generate_json_array);
419
423
  }
420
424
 
421
425
  #ifdef RUBY_INTEGER_UNIFICATION
@@ -426,7 +430,9 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
426
430
  */
427
431
  static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
428
432
  {
429
- GENERATE_JSON(integer);
433
+ rb_check_arity(argc, 0, 1);
434
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
435
+ return cState_partial_generate(Vstate, self, generate_json_integer);
430
436
  }
431
437
 
432
438
  #else
@@ -437,7 +443,9 @@ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
437
443
  */
438
444
  static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
439
445
  {
440
- GENERATE_JSON(fixnum);
446
+ rb_check_arity(argc, 0, 1);
447
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
448
+ return cState_partial_generate(Vstate, self, generate_json_fixnum);
441
449
  }
442
450
 
443
451
  /*
@@ -447,7 +455,9 @@ static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self)
447
455
  */
448
456
  static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
449
457
  {
450
- GENERATE_JSON(bignum);
458
+ rb_check_arity(argc, 0, 1);
459
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
460
+ return cState_partial_generate(Vstate, self, generate_json_bignum);
451
461
  }
452
462
  #endif
453
463
 
@@ -458,7 +468,9 @@ static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self)
458
468
  */
459
469
  static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
460
470
  {
461
- GENERATE_JSON(float);
471
+ rb_check_arity(argc, 0, 1);
472
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
473
+ return cState_partial_generate(Vstate, self, generate_json_float);
462
474
  }
463
475
 
464
476
  /*
@@ -481,7 +493,9 @@ static VALUE mString_included_s(VALUE self, VALUE modul) {
481
493
  */
482
494
  static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
483
495
  {
484
- GENERATE_JSON(string);
496
+ rb_check_arity(argc, 0, 1);
497
+ VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil);
498
+ return cState_partial_generate(Vstate, self, generate_json_string);
485
499
  }
486
500
 
487
501
  /*
@@ -536,7 +550,8 @@ static VALUE mString_Extend_json_create(VALUE self, VALUE o)
536
550
  */
537
551
  static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
538
552
  {
539
- GENERATE_JSON(true);
553
+ rb_check_arity(argc, 0, 1);
554
+ return rb_utf8_str_new("true", 4);
540
555
  }
541
556
 
542
557
  /*
@@ -546,7 +561,8 @@ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self)
546
561
  */
547
562
  static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
548
563
  {
549
- GENERATE_JSON(false);
564
+ rb_check_arity(argc, 0, 1);
565
+ return rb_utf8_str_new("false", 5);
550
566
  }
551
567
 
552
568
  /*
@@ -556,7 +572,8 @@ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self)
556
572
  */
557
573
  static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
558
574
  {
559
- GENERATE_JSON(null);
575
+ rb_check_arity(argc, 0, 1);
576
+ return rb_utf8_str_new("null", 4);
560
577
  }
561
578
 
562
579
  /*
@@ -573,7 +590,7 @@ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self)
573
590
  rb_scan_args(argc, argv, "01", &state);
574
591
  Check_Type(string, T_STRING);
575
592
  state = cState_from_state_s(cState, state);
576
- return cState_partial_generate(state, string);
593
+ return cState_partial_generate(state, string, generate_json_string);
577
594
  }
578
595
 
579
596
  static void State_free(void *ptr)
@@ -826,6 +843,7 @@ static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_
826
843
  generate_json_bignum(buffer, Vstate, state, obj);
827
844
  }
828
845
  #endif
846
+
829
847
  static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
830
848
  {
831
849
  double value = RFLOAT_VALUE(obj);
@@ -911,13 +929,14 @@ struct generate_json_data {
911
929
  VALUE vstate;
912
930
  JSON_Generator_State *state;
913
931
  VALUE obj;
932
+ void (*func)(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
914
933
  };
915
934
 
916
935
  static VALUE generate_json_try(VALUE d)
917
936
  {
918
937
  struct generate_json_data *data = (struct generate_json_data *)d;
919
938
 
920
- generate_json(data->buffer, data->vstate, data->state, data->obj);
939
+ data->func(data->buffer, data->vstate, data->state, data->obj);
921
940
 
922
941
  return Qnil;
923
942
  }
@@ -932,7 +951,7 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
932
951
  return Qundef;
933
952
  }
934
953
 
935
- static VALUE cState_partial_generate(VALUE self, VALUE obj)
954
+ static VALUE cState_partial_generate(VALUE self, VALUE obj, void (*func)(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj))
936
955
  {
937
956
  FBuffer *buffer = cState_prepare_buffer(self);
938
957
  GET_STATE(self);
@@ -941,7 +960,8 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj)
941
960
  .buffer = buffer,
942
961
  .vstate = self,
943
962
  .state = state,
944
- .obj = obj
963
+ .obj = obj,
964
+ .func = func
945
965
  };
946
966
  rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data);
947
967
 
@@ -957,7 +977,7 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj)
957
977
  */
958
978
  static VALUE cState_generate(VALUE self, VALUE obj)
959
979
  {
960
- VALUE result = cState_partial_generate(self, obj);
980
+ VALUE result = cState_partial_generate(self, obj, generate_json);
961
981
  GET_STATE(self);
962
982
  (void)state;
963
983
  return result;
@@ -54,17 +54,6 @@ typedef struct JSON_Generator_StateStruct {
54
54
  JSON_Generator_State *state; \
55
55
  GET_STATE_TO(self, state)
56
56
 
57
- #define GENERATE_JSON(type) \
58
- FBuffer *buffer; \
59
- VALUE Vstate; \
60
- JSON_Generator_State *state; \
61
- \
62
- rb_scan_args(argc, argv, "01", &Vstate); \
63
- Vstate = cState_from_state_s(cState, Vstate); \
64
- TypedData_Get_Struct(Vstate, JSON_Generator_State, &JSON_Generator_State_type, state); \
65
- buffer = cState_prepare_buffer(Vstate); \
66
- generate_json_##type(buffer, Vstate, state, self); \
67
- return fbuffer_to_s(buffer)
68
57
 
69
58
  static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
70
59
  static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self);
@@ -99,7 +88,7 @@ static void generate_json_integer(FBuffer *buffer, VALUE Vstate, JSON_Generator_
99
88
  static void generate_json_fixnum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
100
89
  static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
101
90
  static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj);
102
- static VALUE cState_partial_generate(VALUE self, VALUE obj);
91
+ static VALUE cState_partial_generate(VALUE self, VALUE obj, void (*func)(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj));
103
92
  static VALUE cState_generate(VALUE self, VALUE obj);
104
93
  static VALUE cState_from_state_s(VALUE self, VALUE opts);
105
94
  static VALUE cState_indent(VALUE self);
data/lib/json/common.rb CHANGED
@@ -219,7 +219,12 @@ module JSON
219
219
  if opts.nil?
220
220
  Parser.new(source).parse
221
221
  else
222
- Parser.new(source, opts).parse
222
+ # NB: The ** shouldn't be required, but we have to deal with
223
+ # different versions of the `json` and `json_pure` gems being
224
+ # loaded concurrently.
225
+ # Prior to 2.7.3, `JSON::Ext::Parser` would only take kwargs.
226
+ # Ref: https://github.com/ruby/json/issues/650
227
+ Parser.new(source, **opts).parse
223
228
  end
224
229
  end
225
230
 
@@ -46,15 +46,15 @@ module JSON
46
46
  opts.each do |key, value|
47
47
  case key
48
48
  when :indent
49
- self.indent = value
49
+ self.indent = value || ''
50
50
  when :space
51
- self.space = value
51
+ self.space = value || ''
52
52
  when :space_before
53
- self.space_before = value
53
+ self.space_before = value || ''
54
54
  when :array_nl
55
- self.array_nl = value
55
+ self.array_nl = value || ''
56
56
  when :object_nl
57
- self.object_nl = value
57
+ self.object_nl = value || ''
58
58
  when :max_nesting
59
59
  self.max_nesting = value || 0
60
60
  when :depth
@@ -239,13 +239,13 @@ module JSON
239
239
  end
240
240
 
241
241
  # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json
242
- @indent = opts[:indent] if opts.key?(:indent)
243
- @space = opts[:space] if opts.key?(:space)
244
- @space_before = opts[:space_before] if opts.key?(:space_before)
245
- @object_nl = opts[:object_nl] if opts.key?(:object_nl)
246
- @array_nl = opts[:array_nl] if opts.key?(:array_nl)
247
- @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
248
- @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
242
+ @indent = opts[:indent] || '' if opts.key?(:indent)
243
+ @space = opts[:space] || '' if opts.key?(:space)
244
+ @space_before = opts[:space_before] || '' if opts.key?(:space_before)
245
+ @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
246
+ @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
247
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
248
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
249
249
  @depth = opts[:depth] || 0
250
250
  @buffer_initial_length ||= opts[:buffer_initial_length]
251
251
 
@@ -148,25 +148,25 @@ module JSON
148
148
  end
149
149
 
150
150
  # Unescape characters in strings.
151
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
152
- UNESCAPE_MAP.update({
153
- ?" => '"',
154
- ?\\ => '\\',
155
- ?/ => '/',
156
- ?b => "\b",
157
- ?f => "\f",
158
- ?n => "\n",
159
- ?r => "\r",
160
- ?t => "\t",
161
- ?u => nil,
162
- })
151
+ UNESCAPE_MAP = {
152
+ '"' => '"',
153
+ '\\' => '\\',
154
+ '/' => '/',
155
+ 'b' => "\b",
156
+ 'f' => "\f",
157
+ 'n' => "\n",
158
+ 'r' => "\r",
159
+ 't' => "\t",
160
+ 'u' => nil,
161
+ }.freeze
163
162
 
164
163
  STR_UMINUS = ''.respond_to?(:-@)
165
164
  def parse_string
166
165
  if scan(STRING)
167
166
  return '' if self[1].empty?
168
- string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
169
- if u = UNESCAPE_MAP[$&[1]]
167
+ string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
168
+ k = $&[1]
169
+ if u = UNESCAPE_MAP.fetch(k) { k.chr }
170
170
  u
171
171
  else # \uXXXX
172
172
  bytes = ''.b
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.4.rc2'
4
+ VERSION = '2.7.5'
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.4.rc2
4
+ version: 2.7.5
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-25 00:00:00.000000000 Z
11
+ date: 2024-10-30 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
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
85
  - !ruby/object:Gem::Version
86
86
  version: '0'
87
87
  requirements: []
88
- rubygems_version: 3.5.17
88
+ rubygems_version: 3.5.11
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: JSON Implementation for Ruby