json 2.19.3 → 2.19.4
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 +4 -4
- data/CHANGES.md +13 -1
- data/ext/json/ext/generator/extconf.rb +2 -0
- data/ext/json/ext/generator/generator.c +4 -11
- data/ext/json/ext/json.h +11 -0
- data/ext/json/ext/parser/extconf.rb +4 -0
- data/ext/json/ext/parser/parser.c +45 -33
- data/lib/json/truffle_ruby/generator.rb +8 -8
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48a111e63867f6bb2c0cb1b2740a898f3102bc07ac196136e26ca9b68f510f89
|
|
4
|
+
data.tar.gz: 2f760d8afae80555c483afaaa8bead26f045d26c394cc07843a85deaff7fdd40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6387b2c483c8f4d7ed304f33a3553a2fde78c04efeff7ae32a1e952380df92d6df87b543c22832907b007f758f09bd2f80ef4db0b5753e46fdf73f0e264e9e02
|
|
7
|
+
data.tar.gz: c3c855b9e460768f83516914580c10854ea2b28ee73976e311ce55a0d2265576f65a23c41cccc47c7443d79883658962d1cf923880685d555b3af1ba0ebcb056
|
data/CHANGES.md
CHANGED
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
### Unreleased
|
|
4
4
|
|
|
5
|
+
### 2026-04-19 (2.19.4)
|
|
6
|
+
|
|
7
|
+
* Fix parsing of out of range floats (very large exponents that lead ot either `0.0` or `Inf`).
|
|
8
|
+
|
|
5
9
|
### 2026-03-25 (2.19.3)
|
|
6
10
|
|
|
7
11
|
* Fix handling of unescaped control characters preceeded by a backslash.
|
|
8
12
|
|
|
9
13
|
### 2026-03-18 (2.19.2)
|
|
10
14
|
|
|
11
|
-
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`.
|
|
15
|
+
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
|
|
12
16
|
|
|
13
17
|
### 2026-03-08 (2.19.1)
|
|
14
18
|
|
|
@@ -28,6 +32,10 @@
|
|
|
28
32
|
|
|
29
33
|
* Add `:allow_control_characters` parser options, to allow JSON strings containing unescaped ASCII control characters (e.g. newlines).
|
|
30
34
|
|
|
35
|
+
### 2026-03-18 (2.17.1.2) - Security Backport
|
|
36
|
+
|
|
37
|
+
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
|
|
38
|
+
|
|
31
39
|
### 2025-12-04 (2.17.1)
|
|
32
40
|
|
|
33
41
|
* Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned.
|
|
@@ -54,6 +62,10 @@
|
|
|
54
62
|
* Optimized numbers parsing using SWAR (thanks to Scott Myron).
|
|
55
63
|
* Optimized parsing of pretty printed documents using SWAR (thanks to Scott Myron).
|
|
56
64
|
|
|
65
|
+
### 2026-03-18 (2.15.2.1) - Security Backport
|
|
66
|
+
|
|
67
|
+
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
|
|
68
|
+
|
|
57
69
|
### 2025-10-25 (2.15.2)
|
|
58
70
|
|
|
59
71
|
* Fix `JSON::Coder` to have one dedicated depth counter per invocation.
|
|
@@ -5,6 +5,8 @@ if RUBY_ENGINE == 'truffleruby'
|
|
|
5
5
|
File.write('Makefile', dummy_makefile("").join)
|
|
6
6
|
else
|
|
7
7
|
append_cflags("-std=c99")
|
|
8
|
+
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
|
|
9
|
+
|
|
8
10
|
$defs << "-DJSON_GENERATOR"
|
|
9
11
|
$defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0"
|
|
10
12
|
|
|
@@ -722,27 +722,20 @@ static void State_compact(void *ptr)
|
|
|
722
722
|
state->as_json = rb_gc_location(state->as_json);
|
|
723
723
|
}
|
|
724
724
|
|
|
725
|
-
static void State_free(void *ptr)
|
|
726
|
-
{
|
|
727
|
-
JSON_Generator_State *state = ptr;
|
|
728
|
-
ruby_xfree(state);
|
|
729
|
-
}
|
|
730
|
-
|
|
731
725
|
static size_t State_memsize(const void *ptr)
|
|
732
726
|
{
|
|
733
727
|
return sizeof(JSON_Generator_State);
|
|
734
728
|
}
|
|
735
729
|
|
|
736
730
|
static const rb_data_type_t JSON_Generator_State_type = {
|
|
737
|
-
"JSON/Generator/State",
|
|
738
|
-
{
|
|
731
|
+
.wrap_struct_name = "JSON/Generator/State",
|
|
732
|
+
.function = {
|
|
739
733
|
.dmark = State_mark,
|
|
740
|
-
.dfree =
|
|
734
|
+
.dfree = RUBY_DEFAULT_FREE,
|
|
741
735
|
.dsize = State_memsize,
|
|
742
736
|
.dcompact = State_compact,
|
|
743
737
|
},
|
|
744
|
-
|
|
745
|
-
RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
738
|
+
.flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE,
|
|
746
739
|
};
|
|
747
740
|
|
|
748
741
|
static void state_init(JSON_Generator_State *state)
|
data/ext/json/ext/json.h
CHANGED
|
@@ -54,6 +54,17 @@ typedef unsigned char _Bool;
|
|
|
54
54
|
# define RUBY_TYPED_FROZEN_SHAREABLE 0
|
|
55
55
|
#endif
|
|
56
56
|
|
|
57
|
+
#ifdef RUBY_TYPED_EMBEDDABLE
|
|
58
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
59
|
+
#else
|
|
60
|
+
# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE
|
|
61
|
+
# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE
|
|
62
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
63
|
+
# else
|
|
64
|
+
# define RUBY_TYPED_EMBEDDABLE 0
|
|
65
|
+
# endif
|
|
66
|
+
#endif
|
|
67
|
+
|
|
57
68
|
#ifndef NORETURN
|
|
58
69
|
#if defined(__has_attribute) && __has_attribute(noreturn)
|
|
59
70
|
#define NORETURN(x) __attribute__((noreturn)) x
|
|
@@ -7,6 +7,10 @@ have_func("rb_str_to_interned_str", "ruby.h") # RUBY_VERSION >= 3.0
|
|
|
7
7
|
have_func("rb_hash_new_capa", "ruby.h") # RUBY_VERSION >= 3.2
|
|
8
8
|
have_func("rb_hash_bulk_insert", "ruby.h") # Missing on TruffleRuby
|
|
9
9
|
|
|
10
|
+
if RUBY_ENGINE == "ruby"
|
|
11
|
+
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
append_cflags("-std=c99")
|
|
11
15
|
|
|
12
16
|
if enable_config('parser-use-simd', default=!ENV["JSON_DISABLE_SIMD"])
|
|
@@ -241,17 +241,27 @@ static void rvalue_stack_mark(void *ptr)
|
|
|
241
241
|
{
|
|
242
242
|
rvalue_stack *stack = (rvalue_stack *)ptr;
|
|
243
243
|
long index;
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
if (stack && stack->ptr) {
|
|
245
|
+
for (index = 0; index < stack->head; index++) {
|
|
246
|
+
rb_gc_mark(stack->ptr[index]);
|
|
247
|
+
}
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
|
|
251
|
+
static void rvalue_stack_free_buffer(rvalue_stack *stack)
|
|
252
|
+
{
|
|
253
|
+
ruby_xfree(stack->ptr);
|
|
254
|
+
stack->ptr = NULL;
|
|
255
|
+
}
|
|
256
|
+
|
|
249
257
|
static void rvalue_stack_free(void *ptr)
|
|
250
258
|
{
|
|
251
259
|
rvalue_stack *stack = (rvalue_stack *)ptr;
|
|
252
260
|
if (stack) {
|
|
253
|
-
|
|
261
|
+
rvalue_stack_free_buffer(stack);
|
|
262
|
+
#ifndef HAVE_RUBY_TYPED_EMBEDDABLE
|
|
254
263
|
ruby_xfree(stack);
|
|
264
|
+
#endif
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
267
|
|
|
@@ -262,14 +272,13 @@ static size_t rvalue_stack_memsize(const void *ptr)
|
|
|
262
272
|
}
|
|
263
273
|
|
|
264
274
|
static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
|
|
265
|
-
"JSON::Ext::Parser/rvalue_stack",
|
|
266
|
-
{
|
|
275
|
+
.wrap_struct_name = "JSON::Ext::Parser/rvalue_stack",
|
|
276
|
+
.function = {
|
|
267
277
|
.dmark = rvalue_stack_mark,
|
|
268
278
|
.dfree = rvalue_stack_free,
|
|
269
279
|
.dsize = rvalue_stack_memsize,
|
|
270
280
|
},
|
|
271
|
-
|
|
272
|
-
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
281
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE,
|
|
273
282
|
};
|
|
274
283
|
|
|
275
284
|
static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref)
|
|
@@ -291,8 +300,12 @@ static void rvalue_stack_eagerly_release(VALUE handle)
|
|
|
291
300
|
if (handle) {
|
|
292
301
|
rvalue_stack *stack;
|
|
293
302
|
TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
|
|
294
|
-
|
|
303
|
+
#ifdef HAVE_RUBY_TYPED_EMBEDDABLE
|
|
304
|
+
rvalue_stack_free_buffer(stack);
|
|
305
|
+
#else
|
|
295
306
|
rvalue_stack_free(stack);
|
|
307
|
+
RTYPEDDATA_DATA(handle) = NULL;
|
|
308
|
+
#endif
|
|
296
309
|
}
|
|
297
310
|
}
|
|
298
311
|
|
|
@@ -343,7 +356,7 @@ typedef struct JSON_ParserStruct {
|
|
|
343
356
|
} JSON_ParserConfig;
|
|
344
357
|
|
|
345
358
|
typedef struct JSON_ParserStateStruct {
|
|
346
|
-
VALUE stack_handle;
|
|
359
|
+
VALUE *stack_handle;
|
|
347
360
|
const char *start;
|
|
348
361
|
const char *cursor;
|
|
349
362
|
const char *end;
|
|
@@ -436,9 +449,8 @@ static VALUE build_parse_error_message(const char *format, JSON_ParserState *sta
|
|
|
436
449
|
}
|
|
437
450
|
}
|
|
438
451
|
|
|
439
|
-
VALUE
|
|
440
|
-
|
|
441
|
-
RB_GC_GUARD(msg);
|
|
452
|
+
VALUE message = rb_enc_sprintf(enc_utf8, format, ptr);
|
|
453
|
+
rb_str_catf(message, " at line %ld column %ld", line, column);
|
|
442
454
|
return message;
|
|
443
455
|
}
|
|
444
456
|
|
|
@@ -843,7 +855,7 @@ NOINLINE(static) VALUE json_decode_large_float(const char *start, long len)
|
|
|
843
855
|
/* Ruby JSON optimized float decoder using vendored Ryu algorithm
|
|
844
856
|
* Accepts pre-extracted mantissa and exponent from first-pass validation
|
|
845
857
|
*/
|
|
846
|
-
static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits,
|
|
858
|
+
static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int64_t exponent, bool negative,
|
|
847
859
|
const char *start, const char *end)
|
|
848
860
|
{
|
|
849
861
|
if (RB_UNLIKELY(config->decimal_class)) {
|
|
@@ -851,13 +863,21 @@ static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantis
|
|
|
851
863
|
return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
|
|
852
864
|
}
|
|
853
865
|
|
|
866
|
+
if (RB_UNLIKELY(exponent > INT32_MAX)) {
|
|
867
|
+
return negative ? CMinusInfinity : CInfinity;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (RB_UNLIKELY(exponent < INT32_MIN)) {
|
|
871
|
+
return rb_float_new(negative ? -0.0 : 0.0);
|
|
872
|
+
}
|
|
873
|
+
|
|
854
874
|
// Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case)
|
|
855
875
|
// Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308)
|
|
856
876
|
if (RB_UNLIKELY(mantissa_digits > 17 || mantissa_digits + exponent < -307)) {
|
|
857
877
|
return json_decode_large_float(start, end - start);
|
|
858
878
|
}
|
|
859
879
|
|
|
860
|
-
return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, exponent, negative));
|
|
880
|
+
return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, (int32_t)exponent, negative));
|
|
861
881
|
}
|
|
862
882
|
|
|
863
883
|
static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count)
|
|
@@ -911,9 +931,6 @@ NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE d
|
|
|
911
931
|
cursor_position(state, &line, &column);
|
|
912
932
|
rb_str_concat(message, build_parse_error_message("", state, line, column)) ;
|
|
913
933
|
rb_exc_raise(parse_error_new(message, line, column));
|
|
914
|
-
|
|
915
|
-
raise_parse_error(RSTRING_PTR(message), state);
|
|
916
|
-
RB_GC_GUARD(message);
|
|
917
934
|
}
|
|
918
935
|
|
|
919
936
|
static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, size_t count)
|
|
@@ -950,7 +967,7 @@ static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *
|
|
|
950
967
|
if (RB_UNLIKELY(config->on_load_proc)) {
|
|
951
968
|
value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil);
|
|
952
969
|
}
|
|
953
|
-
rvalue_stack_push(state->stack, value,
|
|
970
|
+
rvalue_stack_push(state->stack, value, state->stack_handle, &state->stack);
|
|
954
971
|
return value;
|
|
955
972
|
}
|
|
956
973
|
|
|
@@ -1135,7 +1152,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
|
|
|
1135
1152
|
const char first_digit = *state->cursor;
|
|
1136
1153
|
|
|
1137
1154
|
// Variables for Ryu optimization - extract digits during parsing
|
|
1138
|
-
|
|
1155
|
+
int64_t exponent = 0;
|
|
1139
1156
|
int decimal_point_pos = -1;
|
|
1140
1157
|
uint64_t mantissa = 0;
|
|
1141
1158
|
|
|
@@ -1179,7 +1196,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
|
|
|
1179
1196
|
raise_parse_error_at("invalid number: %s", state, start);
|
|
1180
1197
|
}
|
|
1181
1198
|
|
|
1182
|
-
exponent = negative_exponent ? -
|
|
1199
|
+
exponent = negative_exponent ? -abs_exponent : abs_exponent;
|
|
1183
1200
|
}
|
|
1184
1201
|
|
|
1185
1202
|
if (integer) {
|
|
@@ -1560,11 +1577,13 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
|
|
|
1560
1577
|
const char *start;
|
|
1561
1578
|
RSTRING_GETMEM(Vsource, start, len);
|
|
1562
1579
|
|
|
1580
|
+
VALUE stack_handle = 0;
|
|
1563
1581
|
JSON_ParserState _state = {
|
|
1564
1582
|
.start = start,
|
|
1565
1583
|
.cursor = start,
|
|
1566
1584
|
.end = start + len,
|
|
1567
1585
|
.stack = &stack,
|
|
1586
|
+
.stack_handle = &stack_handle,
|
|
1568
1587
|
};
|
|
1569
1588
|
JSON_ParserState *state = &_state;
|
|
1570
1589
|
|
|
@@ -1572,8 +1591,8 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
|
|
|
1572
1591
|
|
|
1573
1592
|
// This may be skipped in case of exception, but
|
|
1574
1593
|
// it won't cause a leak.
|
|
1575
|
-
rvalue_stack_eagerly_release(
|
|
1576
|
-
|
|
1594
|
+
rvalue_stack_eagerly_release(stack_handle);
|
|
1595
|
+
RB_GC_GUARD(stack_handle);
|
|
1577
1596
|
json_ensure_eof(state);
|
|
1578
1597
|
|
|
1579
1598
|
return result;
|
|
@@ -1611,26 +1630,19 @@ static void JSON_ParserConfig_mark(void *ptr)
|
|
|
1611
1630
|
rb_gc_mark(config->decimal_class);
|
|
1612
1631
|
}
|
|
1613
1632
|
|
|
1614
|
-
static void JSON_ParserConfig_free(void *ptr)
|
|
1615
|
-
{
|
|
1616
|
-
JSON_ParserConfig *config = ptr;
|
|
1617
|
-
ruby_xfree(config);
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
1633
|
static size_t JSON_ParserConfig_memsize(const void *ptr)
|
|
1621
1634
|
{
|
|
1622
1635
|
return sizeof(JSON_ParserConfig);
|
|
1623
1636
|
}
|
|
1624
1637
|
|
|
1625
1638
|
static const rb_data_type_t JSON_ParserConfig_type = {
|
|
1626
|
-
"JSON::Ext::Parser/ParserConfig",
|
|
1627
|
-
{
|
|
1639
|
+
.wrap_struct_name = "JSON::Ext::Parser/ParserConfig",
|
|
1640
|
+
.function = {
|
|
1628
1641
|
JSON_ParserConfig_mark,
|
|
1629
|
-
|
|
1642
|
+
RUBY_DEFAULT_FREE,
|
|
1630
1643
|
JSON_ParserConfig_memsize,
|
|
1631
1644
|
},
|
|
1632
|
-
|
|
1633
|
-
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
1645
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE,
|
|
1634
1646
|
};
|
|
1635
1647
|
|
|
1636
1648
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
|
@@ -48,7 +48,7 @@ module JSON
|
|
|
48
48
|
SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
|
|
49
49
|
|
|
50
50
|
def self.native_type?(value) # :nodoc:
|
|
51
|
-
(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
|
51
|
+
(false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def self.native_key?(key) # :nodoc:
|
|
@@ -517,11 +517,11 @@ module JSON
|
|
|
517
517
|
|
|
518
518
|
if empty?
|
|
519
519
|
state.depth -= 1
|
|
520
|
-
return '{}'
|
|
520
|
+
return +'{}'
|
|
521
521
|
end
|
|
522
522
|
|
|
523
523
|
delim = ",#{state.object_nl}"
|
|
524
|
-
result =
|
|
524
|
+
result = "{#{state.object_nl}"
|
|
525
525
|
first = true
|
|
526
526
|
key_type = nil
|
|
527
527
|
indent = !state.object_nl.empty?
|
|
@@ -558,7 +558,7 @@ module JSON
|
|
|
558
558
|
raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
|
|
559
559
|
end
|
|
560
560
|
|
|
561
|
-
result =
|
|
561
|
+
result = "#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
562
562
|
if state.strict? && !Generator.native_type?(value)
|
|
563
563
|
if state.as_json
|
|
564
564
|
value = state.as_json.call(value, false)
|
|
@@ -609,7 +609,7 @@ module JSON
|
|
|
609
609
|
|
|
610
610
|
if empty?
|
|
611
611
|
state.depth -= 1
|
|
612
|
-
return '[]'
|
|
612
|
+
return +'[]'
|
|
613
613
|
end
|
|
614
614
|
|
|
615
615
|
result = '['.dup
|
|
@@ -734,17 +734,17 @@ module JSON
|
|
|
734
734
|
|
|
735
735
|
module TrueClass
|
|
736
736
|
# Returns a JSON string for true: 'true'.
|
|
737
|
-
def to_json(*) 'true' end
|
|
737
|
+
def to_json(*) +'true' end
|
|
738
738
|
end
|
|
739
739
|
|
|
740
740
|
module FalseClass
|
|
741
741
|
# Returns a JSON string for false: 'false'.
|
|
742
|
-
def to_json(*) 'false' end
|
|
742
|
+
def to_json(*) +'false' end
|
|
743
743
|
end
|
|
744
744
|
|
|
745
745
|
module NilClass
|
|
746
746
|
# Returns a JSON string for nil: 'null'.
|
|
747
|
-
def to_json(*) 'null' end
|
|
747
|
+
def to_json(*) +'null' end
|
|
748
748
|
end
|
|
749
749
|
end
|
|
750
750
|
end
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
|
@@ -335,8 +335,8 @@ require 'json/common'
|
|
|
335
335
|
# JSON.generate(JSON::MinusInfinity)
|
|
336
336
|
#
|
|
337
337
|
# Allow:
|
|
338
|
-
# ruby = [Float::
|
|
339
|
-
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
|
|
338
|
+
# ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity]
|
|
339
|
+
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
|
|
340
340
|
#
|
|
341
341
|
# ---
|
|
342
342
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.19.
|
|
4
|
+
version: 2.19.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
85
|
version: '0'
|
|
86
86
|
requirements: []
|
|
87
|
-
rubygems_version: 4.0.
|
|
87
|
+
rubygems_version: 4.0.6
|
|
88
88
|
specification_version: 4
|
|
89
89
|
summary: JSON Implementation for Ruby
|
|
90
90
|
test_files: []
|