json 2.19.2 → 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 +18 -2
- 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 +48 -34
- 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,9 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
### Unreleased
|
|
4
4
|
|
|
5
|
-
### 2026-
|
|
5
|
+
### 2026-04-19 (2.19.4)
|
|
6
6
|
|
|
7
|
-
* Fix
|
|
7
|
+
* Fix parsing of out of range floats (very large exponents that lead ot either `0.0` or `Inf`).
|
|
8
|
+
|
|
9
|
+
### 2026-03-25 (2.19.3)
|
|
10
|
+
|
|
11
|
+
* Fix handling of unescaped control characters preceeded by a backslash.
|
|
12
|
+
|
|
13
|
+
### 2026-03-18 (2.19.2)
|
|
14
|
+
|
|
15
|
+
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
|
|
8
16
|
|
|
9
17
|
### 2026-03-08 (2.19.1)
|
|
10
18
|
|
|
@@ -24,6 +32,10 @@
|
|
|
24
32
|
|
|
25
33
|
* Add `:allow_control_characters` parser options, to allow JSON strings containing unescaped ASCII control characters (e.g. newlines).
|
|
26
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
|
+
|
|
27
39
|
### 2025-12-04 (2.17.1)
|
|
28
40
|
|
|
29
41
|
* Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned.
|
|
@@ -50,6 +62,10 @@
|
|
|
50
62
|
* Optimized numbers parsing using SWAR (thanks to Scott Myron).
|
|
51
63
|
* Optimized parsing of pretty printed documents using SWAR (thanks to Scott Myron).
|
|
52
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
|
+
|
|
53
69
|
### 2025-10-25 (2.15.2)
|
|
54
70
|
|
|
55
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
|
|
|
@@ -758,7 +770,9 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser
|
|
|
758
770
|
}
|
|
759
771
|
raise_parse_error_at("invalid ASCII control character in string: %s", state, pe - 1);
|
|
760
772
|
}
|
|
761
|
-
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (config->allow_invalid_escape) {
|
|
762
776
|
APPEND_CHAR(*pe);
|
|
763
777
|
} else {
|
|
764
778
|
raise_parse_error_at("invalid escape character in string: %s", state, pe - 1);
|
|
@@ -841,7 +855,7 @@ NOINLINE(static) VALUE json_decode_large_float(const char *start, long len)
|
|
|
841
855
|
/* Ruby JSON optimized float decoder using vendored Ryu algorithm
|
|
842
856
|
* Accepts pre-extracted mantissa and exponent from first-pass validation
|
|
843
857
|
*/
|
|
844
|
-
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,
|
|
845
859
|
const char *start, const char *end)
|
|
846
860
|
{
|
|
847
861
|
if (RB_UNLIKELY(config->decimal_class)) {
|
|
@@ -849,13 +863,21 @@ static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantis
|
|
|
849
863
|
return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
|
|
850
864
|
}
|
|
851
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
|
+
|
|
852
874
|
// Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case)
|
|
853
875
|
// Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308)
|
|
854
876
|
if (RB_UNLIKELY(mantissa_digits > 17 || mantissa_digits + exponent < -307)) {
|
|
855
877
|
return json_decode_large_float(start, end - start);
|
|
856
878
|
}
|
|
857
879
|
|
|
858
|
-
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));
|
|
859
881
|
}
|
|
860
882
|
|
|
861
883
|
static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count)
|
|
@@ -909,9 +931,6 @@ NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE d
|
|
|
909
931
|
cursor_position(state, &line, &column);
|
|
910
932
|
rb_str_concat(message, build_parse_error_message("", state, line, column)) ;
|
|
911
933
|
rb_exc_raise(parse_error_new(message, line, column));
|
|
912
|
-
|
|
913
|
-
raise_parse_error(RSTRING_PTR(message), state);
|
|
914
|
-
RB_GC_GUARD(message);
|
|
915
934
|
}
|
|
916
935
|
|
|
917
936
|
static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, size_t count)
|
|
@@ -948,7 +967,7 @@ static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *
|
|
|
948
967
|
if (RB_UNLIKELY(config->on_load_proc)) {
|
|
949
968
|
value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil);
|
|
950
969
|
}
|
|
951
|
-
rvalue_stack_push(state->stack, value,
|
|
970
|
+
rvalue_stack_push(state->stack, value, state->stack_handle, &state->stack);
|
|
952
971
|
return value;
|
|
953
972
|
}
|
|
954
973
|
|
|
@@ -1133,7 +1152,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
|
|
|
1133
1152
|
const char first_digit = *state->cursor;
|
|
1134
1153
|
|
|
1135
1154
|
// Variables for Ryu optimization - extract digits during parsing
|
|
1136
|
-
|
|
1155
|
+
int64_t exponent = 0;
|
|
1137
1156
|
int decimal_point_pos = -1;
|
|
1138
1157
|
uint64_t mantissa = 0;
|
|
1139
1158
|
|
|
@@ -1177,7 +1196,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
|
|
|
1177
1196
|
raise_parse_error_at("invalid number: %s", state, start);
|
|
1178
1197
|
}
|
|
1179
1198
|
|
|
1180
|
-
exponent = negative_exponent ? -
|
|
1199
|
+
exponent = negative_exponent ? -abs_exponent : abs_exponent;
|
|
1181
1200
|
}
|
|
1182
1201
|
|
|
1183
1202
|
if (integer) {
|
|
@@ -1558,11 +1577,13 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
|
|
|
1558
1577
|
const char *start;
|
|
1559
1578
|
RSTRING_GETMEM(Vsource, start, len);
|
|
1560
1579
|
|
|
1580
|
+
VALUE stack_handle = 0;
|
|
1561
1581
|
JSON_ParserState _state = {
|
|
1562
1582
|
.start = start,
|
|
1563
1583
|
.cursor = start,
|
|
1564
1584
|
.end = start + len,
|
|
1565
1585
|
.stack = &stack,
|
|
1586
|
+
.stack_handle = &stack_handle,
|
|
1566
1587
|
};
|
|
1567
1588
|
JSON_ParserState *state = &_state;
|
|
1568
1589
|
|
|
@@ -1570,8 +1591,8 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
|
|
|
1570
1591
|
|
|
1571
1592
|
// This may be skipped in case of exception, but
|
|
1572
1593
|
// it won't cause a leak.
|
|
1573
|
-
rvalue_stack_eagerly_release(
|
|
1574
|
-
|
|
1594
|
+
rvalue_stack_eagerly_release(stack_handle);
|
|
1595
|
+
RB_GC_GUARD(stack_handle);
|
|
1575
1596
|
json_ensure_eof(state);
|
|
1576
1597
|
|
|
1577
1598
|
return result;
|
|
@@ -1609,26 +1630,19 @@ static void JSON_ParserConfig_mark(void *ptr)
|
|
|
1609
1630
|
rb_gc_mark(config->decimal_class);
|
|
1610
1631
|
}
|
|
1611
1632
|
|
|
1612
|
-
static void JSON_ParserConfig_free(void *ptr)
|
|
1613
|
-
{
|
|
1614
|
-
JSON_ParserConfig *config = ptr;
|
|
1615
|
-
ruby_xfree(config);
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
1633
|
static size_t JSON_ParserConfig_memsize(const void *ptr)
|
|
1619
1634
|
{
|
|
1620
1635
|
return sizeof(JSON_ParserConfig);
|
|
1621
1636
|
}
|
|
1622
1637
|
|
|
1623
1638
|
static const rb_data_type_t JSON_ParserConfig_type = {
|
|
1624
|
-
"JSON::Ext::Parser/ParserConfig",
|
|
1625
|
-
{
|
|
1639
|
+
.wrap_struct_name = "JSON::Ext::Parser/ParserConfig",
|
|
1640
|
+
.function = {
|
|
1626
1641
|
JSON_ParserConfig_mark,
|
|
1627
|
-
|
|
1642
|
+
RUBY_DEFAULT_FREE,
|
|
1628
1643
|
JSON_ParserConfig_memsize,
|
|
1629
1644
|
},
|
|
1630
|
-
|
|
1631
|
-
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,
|
|
1632
1646
|
};
|
|
1633
1647
|
|
|
1634
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: []
|