json 2.19.5 → 2.19.6

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: 0bbb85e1521c171ca73ab935cc00899ff3eb7086921a64542a3937fa9589848d
4
- data.tar.gz: 328853f7f164d91522d6791a51cca5ccb3ae418410752a3fb72189bc14c157d5
3
+ metadata.gz: d2f786d8fccfe7906f9ec68f2a8f1cb9b4fb458029b46e3bba7904a6e22e443f
4
+ data.tar.gz: 3fe8d97828cc573a98f4a0ccd88c2dc1fb008437dc115a1cd4d631b7a16f9df1
5
5
  SHA512:
6
- metadata.gz: 326b0621e562eebc66f155cee358ca295dde7584e7f60268a354da3e8a1a02e13bfcd9fef7f9b2f9f2ea196987b07bb9e50578347231f14d9fb0e863ac9445ac
7
- data.tar.gz: 0e9e2ab4c91b5544ac8440613a0fd63aab2f7b7ce5a39f41e786af736e80ca28de8d3388057134dde05ba53f4f150d24aa1a8cde92dac82abbb4104740409631
6
+ metadata.gz: 6a39aec470a7ec7da944a8361ea219352f1216b3a4c4b2de7dd35fc87d4c791286f63b7744349ca4da607c37e53b1fecf450e62ef6cd02d0147eba0fb1edf5c2
7
+ data.tar.gz: 8cd952ae28ad7bc52f92ce49cd5cc6411835e3801a2c5cfc4a4b6d503a4bdb3dea3d726a4c4b2f7a75f0d3ec68f2d948bec52588cda37669c7d80ced0d527bb8
data/CHANGES.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 2026-05-28 (2.19.6)
6
+
7
+ * Cleanly handle overly large `depth` generator argument.
8
+ * Add missing write barrier in `ParserConfig`.
9
+
5
10
  ### 2026-05-04 (2.19.5)
6
11
 
7
12
  * Cap the parser to emit a maximum of 5 deprecation warnings per document. Emitting more is not helpful.
@@ -131,6 +131,15 @@ static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
131
131
  }
132
132
  }
133
133
 
134
+ static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
135
+ {
136
+ size_t result = a * b;
137
+ if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
138
+ rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
139
+ }
140
+ return result;
141
+ }
142
+
134
143
  static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len)
135
144
  {
136
145
  MEMCPY(fb->ptr + fb->len, newstr, char, len);
@@ -175,7 +184,7 @@ static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
175
184
  size_t len;
176
185
  RSTRING_GETMEM(str, ptr, len);
177
186
 
178
- fbuffer_inc_capa(fb, repeat * len);
187
+ fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
179
188
  while (repeat) {
180
189
  #if JSON_DEBUG
181
190
  fb->requested = len;
@@ -1471,9 +1471,22 @@ static VALUE convert_encoding(VALUE source)
1471
1471
  return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
1472
1472
  }
1473
1473
 
1474
+ struct parser_config_init_args {
1475
+ JSON_ParserConfig *config;
1476
+ VALUE self;
1477
+ };
1478
+
1479
+ static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
1480
+ {
1481
+ *dest = val;
1482
+ if (self) RB_OBJ_WRITTEN(self, Qundef, val);
1483
+ }
1484
+
1474
1485
  static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1475
1486
  {
1476
- JSON_ParserConfig *config = (JSON_ParserConfig *)data;
1487
+ struct parser_config_init_args *args = (struct parser_config_init_args *)data;
1488
+ JSON_ParserConfig *config = args->config;
1489
+ VALUE self = args->self;
1477
1490
 
1478
1491
  if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
1479
1492
  else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); }
@@ -1482,15 +1495,15 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1482
1495
  else if (key == sym_allow_invalid_escape) { config->allow_invalid_escape = RTEST(val); }
1483
1496
  else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); }
1484
1497
  else if (key == sym_freeze) { config->freeze = RTEST(val); }
1485
- else if (key == sym_on_load) { config->on_load_proc = RTEST(val) ? val : Qfalse; }
1498
+ else if (key == sym_on_load) { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
1486
1499
  else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; }
1487
1500
  else if (key == sym_decimal_class) {
1488
1501
  if (RTEST(val)) {
1489
1502
  if (rb_respond_to(val, i_try_convert)) {
1490
- config->decimal_class = val;
1503
+ parser_config_wb_write(self, &config->decimal_class, val);
1491
1504
  config->decimal_method_id = i_try_convert;
1492
1505
  } else if (rb_respond_to(val, i_new)) {
1493
- config->decimal_class = val;
1506
+ parser_config_wb_write(self, &config->decimal_class, val);
1494
1507
  config->decimal_method_id = i_new;
1495
1508
  } else if (RB_TYPE_P(val, T_CLASS)) {
1496
1509
  VALUE name = rb_class_name(val);
@@ -1499,7 +1512,7 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1499
1512
  if (last_colon) {
1500
1513
  const char *mod_path_end = last_colon - 1;
1501
1514
  VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1502
- config->decimal_class = rb_path_to_class(mod_path);
1515
+ parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
1503
1516
 
1504
1517
  const char *method_name_beg = last_colon + 1;
1505
1518
  long before_len = method_name_beg - name_cstr;
@@ -1507,7 +1520,7 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1507
1520
  VALUE method_name = rb_str_substr(name, before_len, len);
1508
1521
  config->decimal_method_id = SYM2ID(rb_str_intern(method_name));
1509
1522
  } else {
1510
- config->decimal_class = rb_mKernel;
1523
+ parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
1511
1524
  config->decimal_method_id = SYM2ID(rb_str_intern(name));
1512
1525
  }
1513
1526
  }
@@ -1517,16 +1530,21 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1517
1530
  return ST_CONTINUE;
1518
1531
  }
1519
1532
 
1520
- static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
1533
+ static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
1521
1534
  {
1522
1535
  config->max_nesting = 100;
1523
1536
 
1537
+ struct parser_config_init_args args = {
1538
+ .config = config,
1539
+ .self = self,
1540
+ };
1541
+
1524
1542
  if (!NIL_P(opts)) {
1525
1543
  Check_Type(opts, T_HASH);
1526
1544
  if (RHASH_SIZE(opts) > 0) {
1527
1545
  // We assume in most cases few keys are set so it's faster to go over
1528
1546
  // the provided keys than to check all possible keys.
1529
- rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
1547
+ rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
1530
1548
  }
1531
1549
 
1532
1550
  }
@@ -1560,9 +1578,7 @@ static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
1560
1578
  rb_check_frozen(self);
1561
1579
  GET_PARSER_CONFIG;
1562
1580
 
1563
- parser_config_init(config, opts);
1564
-
1565
- RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
1581
+ parser_config_init(config, opts, self);
1566
1582
 
1567
1583
  return self;
1568
1584
  }
@@ -1624,7 +1640,7 @@ static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
1624
1640
 
1625
1641
  JSON_ParserConfig _config = {0};
1626
1642
  JSON_ParserConfig *config = &_config;
1627
- parser_config_init(config, opts);
1643
+ parser_config_init(config, opts, false);
1628
1644
 
1629
1645
  return cParser_parse(config, Vsource);
1630
1646
  }
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.5'
4
+ VERSION = '2.19.6'
5
5
  end
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.5
4
+ version: 2.19.6
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.6
87
+ rubygems_version: 4.0.10
88
88
  specification_version: 4
89
89
  summary: JSON Implementation for Ruby
90
90
  test_files: []