json 2.19.3 → 2.19.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: 3182d9103a2ee3b673b923a4789e947a9cddb850f870f7fdb54d93f3bd1a5493
4
- data.tar.gz: 0ee85345c9e1c99223f9cc3e859e4a7295f40f88461ca0f47059cfcc4e80154c
3
+ metadata.gz: 0bbb85e1521c171ca73ab935cc00899ff3eb7086921a64542a3937fa9589848d
4
+ data.tar.gz: 328853f7f164d91522d6791a51cca5ccb3ae418410752a3fb72189bc14c157d5
5
5
  SHA512:
6
- metadata.gz: dedf64066bc4017b977330468b01613ce1d4a78c267b38519b7ef2705368e5d73187b64ca99777afaf900cc5f58523a722833e83c0ee011944bf15b34c33479e
7
- data.tar.gz: c187fa755e0a7bd2e2ddb74498062a8138ac4882630713e3372886b5648a22a453b1a388174038b2d4144a724e1d44d5b444b190e49e3e7eb2047d8b98eef0a8
6
+ metadata.gz: 326b0621e562eebc66f155cee358ca295dde7584e7f60268a354da3e8a1a02e13bfcd9fef7f9b2f9f2ea196987b07bb9e50578347231f14d9fb0e863ac9445ac
7
+ data.tar.gz: 0e9e2ab4c91b5544ac8440613a0fd63aab2f7b7ce5a39f41e786af736e80ca28de8d3388057134dde05ba53f4f150d24aa1a8cde92dac82abbb4104740409631
data/CHANGES.md CHANGED
@@ -2,13 +2,21 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 2026-05-04 (2.19.5)
6
+
7
+ * Cap the parser to emit a maximum of 5 deprecation warnings per document. Emitting more is not helpful.
8
+
9
+ ### 2026-04-19 (2.19.4)
10
+
11
+ * Fix parsing of out of range floats (very large exponents that lead to either `0.0` or `Inf`).
12
+
5
13
  ### 2026-03-25 (2.19.3)
6
14
 
7
15
  * Fix handling of unescaped control characters preceeded by a backslash.
8
16
 
9
17
  ### 2026-03-18 (2.19.2)
10
18
 
11
- * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`.
19
+ * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
12
20
 
13
21
  ### 2026-03-08 (2.19.1)
14
22
 
@@ -28,6 +36,10 @@
28
36
 
29
37
  * Add `:allow_control_characters` parser options, to allow JSON strings containing unescaped ASCII control characters (e.g. newlines).
30
38
 
39
+ ### 2026-03-18 (2.17.1.2) - Security Backport
40
+
41
+ * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
42
+
31
43
  ### 2025-12-04 (2.17.1)
32
44
 
33
45
  * Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned.
@@ -54,6 +66,10 @@
54
66
  * Optimized numbers parsing using SWAR (thanks to Scott Myron).
55
67
  * Optimized parsing of pretty printed documents using SWAR (thanks to Scott Myron).
56
68
 
69
+ ### 2026-03-18 (2.15.2.1) - Security Backport
70
+
71
+ * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
72
+
57
73
  ### 2025-10-25 (2.15.2)
58
74
 
59
75
  * 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 = State_free,
734
+ .dfree = RUBY_DEFAULT_FREE,
741
735
  .dsize = State_memsize,
742
736
  .dcompact = State_compact,
743
737
  },
744
- 0, 0,
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)
@@ -826,9 +819,17 @@ static VALUE encode_json_string_rescue(VALUE str, VALUE exception)
826
819
  return Qundef;
827
820
  }
828
821
 
822
+ static inline int json_str_coderange(VALUE str) {
823
+ int coderange = RB_ENC_CODERANGE(str);
824
+ if (coderange == RUBY_ENC_CODERANGE_UNKNOWN) {
825
+ coderange = rb_enc_str_coderange(str);
826
+ }
827
+ return coderange;
828
+ }
829
+
829
830
  static inline bool valid_json_string_p(VALUE str)
830
831
  {
831
- int coderange = rb_enc_str_coderange(str);
832
+ int coderange = json_str_coderange(str);
832
833
 
833
834
  if (RB_LIKELY(coderange == ENC_CODERANGE_7BIT)) {
834
835
  return true;
@@ -841,12 +842,8 @@ static inline bool valid_json_string_p(VALUE str)
841
842
  return false;
842
843
  }
843
844
 
844
- static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key)
845
+ NOINLINE(static) VALUE convert_invalid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key)
845
846
  {
846
- if (RB_LIKELY(valid_json_string_p(str))) {
847
- return str;
848
- }
849
-
850
847
  if (!as_json_called && data->state->strict && RTEST(data->state->as_json)) {
851
848
  VALUE coerced_str = json_call_as_json(data->state, str, Qfalse);
852
849
  if (coerced_str != str) {
@@ -882,6 +879,16 @@ static inline VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE
882
879
  return rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str);
883
880
  }
884
881
 
882
+ ALWAYS_INLINE(static) VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key)
883
+ {
884
+ if (RB_LIKELY(valid_json_string_p(str))) {
885
+ return str;
886
+ }
887
+ else {
888
+ return convert_invalid_encoding(data, str, as_json_called, is_key);
889
+ }
890
+ }
891
+
885
892
  static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj)
886
893
  {
887
894
  fbuffer_append_char(buffer, '"');
@@ -900,7 +907,7 @@ static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data
900
907
  search.chunk_end = NULL;
901
908
  #endif /* HAVE_SIMD */
902
909
 
903
- switch (rb_enc_str_coderange(obj)) {
910
+ switch (json_str_coderange(obj)) {
904
911
  case ENC_CODERANGE_7BIT:
905
912
  case ENC_CODERANGE_VALID:
906
913
  if (RB_UNLIKELY(data->state->ascii_only)) {
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
- for (index = 0; index < stack->head; index++) {
245
- rb_gc_mark(stack->ptr[index]);
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
- ruby_xfree(stack->ptr);
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
- 0, 0,
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
- RTYPEDDATA_DATA(handle) = NULL;
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;
@@ -351,6 +364,7 @@ typedef struct JSON_ParserStateStruct {
351
364
  rvalue_cache name_cache;
352
365
  int in_array;
353
366
  int current_nesting;
367
+ unsigned int emitted_deprecations;
354
368
  } JSON_ParserState;
355
369
 
356
370
  static inline size_t rest(JSON_ParserState *state) {
@@ -436,9 +450,8 @@ static VALUE build_parse_error_message(const char *format, JSON_ParserState *sta
436
450
  }
437
451
  }
438
452
 
439
- VALUE msg = rb_sprintf(format, ptr);
440
- VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column);
441
- RB_GC_GUARD(msg);
453
+ VALUE message = rb_enc_sprintf(enc_utf8, format, ptr);
454
+ rb_str_catf(message, " at line %ld column %ld", line, column);
442
455
  return message;
443
456
  }
444
457
 
@@ -843,7 +856,7 @@ NOINLINE(static) VALUE json_decode_large_float(const char *start, long len)
843
856
  /* Ruby JSON optimized float decoder using vendored Ryu algorithm
844
857
  * Accepts pre-extracted mantissa and exponent from first-pass validation
845
858
  */
846
- static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int32_t exponent, bool negative,
859
+ static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int64_t exponent, bool negative,
847
860
  const char *start, const char *end)
848
861
  {
849
862
  if (RB_UNLIKELY(config->decimal_class)) {
@@ -851,13 +864,21 @@ static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantis
851
864
  return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text);
852
865
  }
853
866
 
867
+ if (RB_UNLIKELY(exponent > INT32_MAX)) {
868
+ return negative ? CMinusInfinity : CInfinity;
869
+ }
870
+
871
+ if (RB_UNLIKELY(exponent < INT32_MIN)) {
872
+ return rb_float_new(negative ? -0.0 : 0.0);
873
+ }
874
+
854
875
  // Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case)
855
876
  // Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308)
856
877
  if (RB_UNLIKELY(mantissa_digits > 17 || mantissa_digits + exponent < -307)) {
857
878
  return json_decode_large_float(start, end - start);
858
879
  }
859
880
 
860
- return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, exponent, negative));
881
+ return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, (int32_t)exponent, negative));
861
882
  }
862
883
 
863
884
  static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count)
@@ -911,9 +932,6 @@ NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE d
911
932
  cursor_position(state, &line, &column);
912
933
  rb_str_concat(message, build_parse_error_message("", state, line, column)) ;
913
934
  rb_exc_raise(parse_error_new(message, line, column));
914
-
915
- raise_parse_error(RSTRING_PTR(message), state);
916
- RB_GC_GUARD(message);
917
935
  }
918
936
 
919
937
  static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, size_t count)
@@ -928,7 +946,12 @@ static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfi
928
946
  case JSON_IGNORE:
929
947
  break;
930
948
  case JSON_DEPRECATED:
931
- emit_duplicate_key_warning(state, json_find_duplicated_key(count, pairs));
949
+ // Only emit the first few deprecations to avoid spamming.
950
+ if (state->emitted_deprecations < 5) {
951
+ emit_duplicate_key_warning(state, json_find_duplicated_key(count, pairs));
952
+ state->emitted_deprecations++;
953
+ }
954
+
932
955
  break;
933
956
  case JSON_RAISE:
934
957
  raise_duplicate_key_error(state, json_find_duplicated_key(count, pairs));
@@ -950,7 +973,7 @@ static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *
950
973
  if (RB_UNLIKELY(config->on_load_proc)) {
951
974
  value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil);
952
975
  }
953
- rvalue_stack_push(state->stack, value, &state->stack_handle, &state->stack);
976
+ rvalue_stack_push(state->stack, value, state->stack_handle, &state->stack);
954
977
  return value;
955
978
  }
956
979
 
@@ -1135,7 +1158,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
1135
1158
  const char first_digit = *state->cursor;
1136
1159
 
1137
1160
  // Variables for Ryu optimization - extract digits during parsing
1138
- int32_t exponent = 0;
1161
+ int64_t exponent = 0;
1139
1162
  int decimal_point_pos = -1;
1140
1163
  uint64_t mantissa = 0;
1141
1164
 
@@ -1179,7 +1202,7 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
1179
1202
  raise_parse_error_at("invalid number: %s", state, start);
1180
1203
  }
1181
1204
 
1182
- exponent = negative_exponent ? -((int32_t)abs_exponent) : ((int32_t)abs_exponent);
1205
+ exponent = negative_exponent ? -abs_exponent : abs_exponent;
1183
1206
  }
1184
1207
 
1185
1208
  if (integer) {
@@ -1560,11 +1583,13 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1560
1583
  const char *start;
1561
1584
  RSTRING_GETMEM(Vsource, start, len);
1562
1585
 
1586
+ VALUE stack_handle = 0;
1563
1587
  JSON_ParserState _state = {
1564
1588
  .start = start,
1565
1589
  .cursor = start,
1566
1590
  .end = start + len,
1567
1591
  .stack = &stack,
1592
+ .stack_handle = &stack_handle,
1568
1593
  };
1569
1594
  JSON_ParserState *state = &_state;
1570
1595
 
@@ -1572,8 +1597,8 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1572
1597
 
1573
1598
  // This may be skipped in case of exception, but
1574
1599
  // it won't cause a leak.
1575
- rvalue_stack_eagerly_release(state->stack_handle);
1576
-
1600
+ rvalue_stack_eagerly_release(stack_handle);
1601
+ RB_GC_GUARD(stack_handle);
1577
1602
  json_ensure_eof(state);
1578
1603
 
1579
1604
  return result;
@@ -1611,26 +1636,19 @@ static void JSON_ParserConfig_mark(void *ptr)
1611
1636
  rb_gc_mark(config->decimal_class);
1612
1637
  }
1613
1638
 
1614
- static void JSON_ParserConfig_free(void *ptr)
1615
- {
1616
- JSON_ParserConfig *config = ptr;
1617
- ruby_xfree(config);
1618
- }
1619
-
1620
1639
  static size_t JSON_ParserConfig_memsize(const void *ptr)
1621
1640
  {
1622
1641
  return sizeof(JSON_ParserConfig);
1623
1642
  }
1624
1643
 
1625
1644
  static const rb_data_type_t JSON_ParserConfig_type = {
1626
- "JSON::Ext::Parser/ParserConfig",
1627
- {
1645
+ .wrap_struct_name = "JSON::Ext::Parser/ParserConfig",
1646
+ .function = {
1628
1647
  JSON_ParserConfig_mark,
1629
- JSON_ParserConfig_free,
1648
+ RUBY_DEFAULT_FREE,
1630
1649
  JSON_ParserConfig_memsize,
1631
1650
  },
1632
- 0, 0,
1633
- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
1651
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE,
1634
1652
  };
1635
1653
 
1636
1654
  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 = +"{#{state.object_nl}"
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 = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.19.3'
4
+ VERSION = '2.19.5'
5
5
  end
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::NaN, Float::Infinity, Float::MinusInfinity]
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.3
4
+ version: 2.19.5
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.3
87
+ rubygems_version: 4.0.6
88
88
  specification_version: 4
89
89
  summary: JSON Implementation for Ruby
90
90
  test_files: []