json 2.7.4.rc2 → 2.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +13 -0
- data/ext/json/ext/generator/generator.c +35 -15
- data/ext/json/ext/generator/generator.h +1 -12
- data/lib/json/common.rb +6 -1
- data/lib/json/ext/generator/state.rb +5 -5
- data/lib/json/pure/generator.rb +7 -7
- data/lib/json/pure/parser.rb +14 -14
- data/lib/json/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8138305febf8acb1cc4533b5e5b071928167b88f17567cf18d99fc1dcbeef234
|
4
|
+
data.tar.gz: 9648ecf580a9f686cd1fb879efbeb85509c800f13c1372e282298eb713dce740
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/json/pure/generator.rb
CHANGED
@@ -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]
|
248
|
-
@ascii_only = opts[: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
|
|
data/lib/json/pure/parser.rb
CHANGED
@@ -148,25 +148,25 @@ module JSON
|
|
148
148
|
end
|
149
149
|
|
150
150
|
# Unescape characters in strings.
|
151
|
-
UNESCAPE_MAP =
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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(
|
169
|
-
|
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
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
|
+
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-
|
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.
|
88
|
+
rubygems_version: 3.5.11
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: JSON Implementation for Ruby
|