json 2.19.5 → 2.19.9

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: 5e5fed66aaa650ac7aaf223c4d8e505a2d6ce3fe72599af4931356ae619f020b
4
+ data.tar.gz: 347004780c7a7568685502ade79f145371a49a213d348a65c99ea8fbffc6eee7
5
5
  SHA512:
6
- metadata.gz: 326b0621e562eebc66f155cee358ca295dde7584e7f60268a354da3e8a1a02e13bfcd9fef7f9b2f9f2ea196987b07bb9e50578347231f14d9fb0e863ac9445ac
7
- data.tar.gz: 0e9e2ab4c91b5544ac8440613a0fd63aab2f7b7ce5a39f41e786af736e80ca28de8d3388057134dde05ba53f4f150d24aa1a8cde92dac82abbb4104740409631
6
+ metadata.gz: 0bffdb4cd21e4656a1402a00d95ae890dc75befff379aeef4aad575a7f715a0dbeb87cfef6fefa3cd5235c3302a29fabb510d5db67e527678023cd8a88c34b49
7
+ data.tar.gz: 7e08cfae0c5d404687644528ecfb9438c9ea254f43fd285d116ba1542a4ef78045463b18850324e91ba4d0c735e7d9ed4b583499aadafe7d0bab51dd54a8d086
data/CHANGES.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 2026-06-11 (2.19.9)
6
+
7
+ * Fix buffer overflow that could lead to a crash when writing JSON directly into an IO
8
+ with `JSON.generate(object, io)`. [CVE-PENDING].
9
+
10
+ ### 2026-06-03 (2.19.8)
11
+
12
+ * Fix 1-byte buffer overread on EOS errors.
13
+ * Handle invalid types passed as `max_nesting` option.
14
+
15
+ ### 2026-05-28 (2.19.7)
16
+
17
+ * Fix some more edge cases with out of range floats.
18
+ * Ensure the string provided to `JSON.parse` can't be mutated during parsing.
19
+ * Add missing write barriers in `State#dup`.
20
+ * Further validate generator `depth` config.
21
+
22
+ ### 2026-05-28 (2.19.6)
23
+
24
+ * Cleanly handle overly large `depth` generator argument.
25
+ * Add missing write barrier in `ParserConfig`.
26
+
5
27
  ### 2026-05-04 (2.19.5)
6
28
 
7
29
  * Cap the parser to emit a maximum of 5 deprecation warnings per document. Emitting more is not helpful.
data/README.md CHANGED
@@ -249,6 +249,17 @@ There are also the methods `Kernel#j` for generate, and `Kernel#jj` for
249
249
  `pretty_generate` output to the console, that work analogous to Core Ruby's `p` and
250
250
  the `pp` library's `pp` methods.
251
251
 
252
+ ## Security
253
+
254
+ When parsing or serializing untrusted input, parser and generator options should never be user controlled.
255
+
256
+ ```ruby
257
+ # Dangerous, DO NOT DO THIS.
258
+ JSON.generate(params[:data], params[:options])
259
+ ```
260
+
261
+ Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes.
262
+
252
263
  ## Development
253
264
 
254
265
  ### Prerequisites
@@ -37,13 +37,17 @@ static void fbuffer_append_long(FBuffer *fb, long number);
37
37
  static inline void fbuffer_append_char(FBuffer *fb, char newchr);
38
38
  static VALUE fbuffer_finalize(FBuffer *fb);
39
39
 
40
- static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
40
+ static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
41
41
  {
42
- fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
43
- if (stack_buffer) {
42
+ if (RTEST(io)) {
43
+ JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED);
44
+ fb->io = io;
45
+ fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE;
46
+ } else {
44
47
  fb->type = FBUFFER_STACK_ALLOCATED;
45
48
  fb->ptr = stack_buffer;
46
49
  fb->capa = stack_buffer_size;
50
+ fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
47
51
  }
48
52
  #if JSON_DEBUG
49
53
  fb->requested = 0;
@@ -79,45 +83,40 @@ static void fbuffer_flush(FBuffer *fb)
79
83
  fbuffer_clear(fb);
80
84
  }
81
85
 
82
- static void fbuffer_realloc(FBuffer *fb, size_t required)
86
+ static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
83
87
  {
84
- if (required > fb->capa) {
88
+ if (new_capa > fb->capa) {
85
89
  if (fb->type == FBUFFER_STACK_ALLOCATED) {
86
90
  const char *old_buffer = fb->ptr;
87
- fb->ptr = ALLOC_N(char, required);
91
+ fb->ptr = ALLOC_N(char, new_capa);
88
92
  fb->type = FBUFFER_HEAP_ALLOCATED;
89
93
  MEMCPY(fb->ptr, old_buffer, char, fb->len);
90
94
  } else {
91
- REALLOC_N(fb->ptr, char, required);
95
+ REALLOC_N(fb->ptr, char, new_capa);
92
96
  }
93
- fb->capa = required;
97
+ fb->capa = new_capa;
94
98
  }
95
99
  }
96
100
 
97
101
  static void fbuffer_do_inc_capa(FBuffer *fb, size_t requested)
98
102
  {
99
103
  if (RB_UNLIKELY(fb->io)) {
100
- if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
101
- fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
102
- } else {
104
+ if (fb->capa != 0) {
103
105
  fbuffer_flush(fb);
104
- }
105
-
106
- if (RB_LIKELY(requested < fb->capa)) {
107
- return;
106
+ if (RB_LIKELY(requested < fb->capa)) {
107
+ return;
108
+ }
108
109
  }
109
110
  }
110
111
 
111
- size_t required;
112
+ size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
113
+ size_t needed_capa = requested + fb->len;
112
114
 
113
- if (RB_UNLIKELY(!fb->ptr)) {
114
- fb->ptr = ALLOC_N(char, fb->initial_length);
115
- fb->capa = fb->initial_length;
115
+ while (new_capa < needed_capa) {
116
+ new_capa *= 2;
116
117
  }
117
118
 
118
- for (required = fb->capa; requested > required - fb->len; required <<= 1);
119
-
120
- fbuffer_realloc(fb, required);
119
+ fbuffer_realloc(fb, new_capa);
121
120
  }
122
121
 
123
122
  static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
@@ -131,6 +130,15 @@ static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
131
130
  }
132
131
  }
133
132
 
133
+ static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b)
134
+ {
135
+ size_t result = a * b;
136
+ if (RB_UNLIKELY(a != 0 && (result / a) != b)) {
137
+ rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated");
138
+ }
139
+ return result;
140
+ }
141
+
134
142
  static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len)
135
143
  {
136
144
  MEMCPY(fb->ptr + fb->len, newstr, char, len);
@@ -175,7 +183,7 @@ static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
175
183
  size_t len;
176
184
  RSTRING_GETMEM(str, ptr, len);
177
185
 
178
- fbuffer_inc_capa(fb, repeat * len);
186
+ fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len));
179
187
  while (repeat) {
180
188
  #if JSON_DEBUG
181
189
  fb->requested = len;
@@ -1304,10 +1304,8 @@ static inline VALUE cState_partial_generate(VALUE self, VALUE obj, generator_fun
1304
1304
  GET_STATE(self);
1305
1305
 
1306
1306
  char stack_buffer[FBUFFER_STACK_SIZE];
1307
- FBuffer buffer = {
1308
- .io = RTEST(io) ? io : Qfalse,
1309
- };
1310
- fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
1307
+ FBuffer buffer = { 0 };
1308
+ fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
1311
1309
 
1312
1310
  struct generate_json_data data = {
1313
1311
  .buffer = &buffer,
@@ -1367,12 +1365,14 @@ static VALUE cState_init_copy(VALUE obj, VALUE orig)
1367
1365
  if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State");
1368
1366
 
1369
1367
  MEMCPY(objState, origState, JSON_Generator_State, 1);
1370
- objState->indent = origState->indent;
1371
- objState->space = origState->space;
1372
- objState->space_before = origState->space_before;
1373
- objState->object_nl = origState->object_nl;
1374
- objState->array_nl = origState->array_nl;
1375
- objState->as_json = origState->as_json;
1368
+
1369
+ RB_OBJ_WRITTEN(obj, Qundef, objState->indent);
1370
+ RB_OBJ_WRITTEN(obj, Qundef, objState->space);
1371
+ RB_OBJ_WRITTEN(obj, Qundef, objState->space_before);
1372
+ RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl);
1373
+ RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl);
1374
+ RB_OBJ_WRITTEN(obj, Qundef, objState->as_json);
1375
+
1376
1376
  return obj;
1377
1377
  }
1378
1378
 
@@ -1579,7 +1579,7 @@ static VALUE cState_max_nesting(VALUE self)
1579
1579
 
1580
1580
  static long long_config(VALUE num)
1581
1581
  {
1582
- return RTEST(num) ? FIX2LONG(num) : 0;
1582
+ return RTEST(num) ? NUM2LONG(num) : 0;
1583
1583
  }
1584
1584
 
1585
1585
  // depth must never be negative; reject early with a clear error.
@@ -1590,6 +1590,9 @@ static long depth_config(VALUE num)
1590
1590
  if (RB_UNLIKELY(d < 0)) {
1591
1591
  rb_raise(rb_eArgError, "depth must be >= 0 (got %ld)", d);
1592
1592
  }
1593
+ if (RB_UNLIKELY(d > INT_MAX)) {
1594
+ rb_raise(rb_eArgError, "depth is too large (got %ld)", d);
1595
+ }
1593
1596
  return d;
1594
1597
  }
1595
1598
 
@@ -1861,10 +1864,8 @@ static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io,
1861
1864
  configure_state(&state, Qfalse, opts);
1862
1865
 
1863
1866
  char stack_buffer[FBUFFER_STACK_SIZE];
1864
- FBuffer buffer = {
1865
- .io = RTEST(io) ? io : Qfalse,
1866
- };
1867
- fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
1867
+ FBuffer buffer = { 0 };
1868
+ fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE);
1868
1869
 
1869
1870
  struct generate_json_data data = {
1870
1871
  .buffer = &buffer,
@@ -385,6 +385,13 @@ static inline char peek(JSON_ParserState *state)
385
385
 
386
386
  static void cursor_position(JSON_ParserState *state, long *line_out, long *column_out)
387
387
  {
388
+ JSON_ASSERT(state->cursor <= state->end);
389
+
390
+ // Redundant but helpful for hardening
391
+ if (RB_UNLIKELY(state->cursor > state->end)) {
392
+ state->cursor = state->end;
393
+ }
394
+
388
395
  const char *cursor = state->cursor;
389
396
  long column = 0;
390
397
  long line = 1;
@@ -1022,6 +1029,13 @@ ALWAYS_INLINE(static) bool string_scan(JSON_ParserState *state)
1022
1029
  }
1023
1030
  state->cursor++;
1024
1031
  }
1032
+
1033
+ // If the string ended with an unterminated escape sequence, we might
1034
+ // have gone past the end.
1035
+ if (RB_UNLIKELY(state->cursor > state->end)) {
1036
+ state->cursor = state->end;
1037
+ }
1038
+
1025
1039
  return false;
1026
1040
  }
1027
1041
 
@@ -1202,7 +1216,11 @@ static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig
1202
1216
  raise_parse_error_at("invalid number: %s", state, start);
1203
1217
  }
1204
1218
 
1205
- exponent = negative_exponent ? -abs_exponent : abs_exponent;
1219
+ if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) {
1220
+ exponent = negative_exponent ? INT64_MIN : INT64_MAX;
1221
+ } else {
1222
+ exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent;
1223
+ }
1206
1224
  }
1207
1225
 
1208
1226
  if (integer) {
@@ -1457,23 +1475,39 @@ static void json_ensure_eof(JSON_ParserState *state)
1457
1475
 
1458
1476
  static VALUE convert_encoding(VALUE source)
1459
1477
  {
1460
- int encindex = RB_ENCODING_GET(source);
1478
+ StringValue(source);
1479
+ int encindex = RB_ENCODING_GET(source);
1480
+
1481
+ if (RB_LIKELY(encindex == utf8_encindex)) {
1482
+ return source;
1483
+ }
1484
+
1485
+ if (encindex == binary_encindex) {
1486
+ // For historical reason, we silently reinterpret binary strings as UTF-8
1487
+ return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
1488
+ }
1461
1489
 
1462
- if (RB_LIKELY(encindex == utf8_encindex)) {
1490
+ source = rb_funcall(source, i_encode, 1, Encoding_UTF_8);
1491
+ StringValue(source);
1463
1492
  return source;
1464
- }
1493
+ }
1465
1494
 
1466
- if (encindex == binary_encindex) {
1467
- // For historical reason, we silently reinterpret binary strings as UTF-8
1468
- return rb_enc_associate_index(rb_str_dup(source), utf8_encindex);
1469
- }
1495
+ struct parser_config_init_args {
1496
+ JSON_ParserConfig *config;
1497
+ VALUE self;
1498
+ };
1470
1499
 
1471
- return rb_funcall(source, i_encode, 1, Encoding_UTF_8);
1500
+ static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val)
1501
+ {
1502
+ *dest = val;
1503
+ if (self) RB_OBJ_WRITTEN(self, Qundef, val);
1472
1504
  }
1473
1505
 
1474
1506
  static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1475
1507
  {
1476
- JSON_ParserConfig *config = (JSON_ParserConfig *)data;
1508
+ struct parser_config_init_args *args = (struct parser_config_init_args *)data;
1509
+ JSON_ParserConfig *config = args->config;
1510
+ VALUE self = args->self;
1477
1511
 
1478
1512
  if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
1479
1513
  else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); }
@@ -1482,15 +1516,15 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1482
1516
  else if (key == sym_allow_invalid_escape) { config->allow_invalid_escape = RTEST(val); }
1483
1517
  else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); }
1484
1518
  else if (key == sym_freeze) { config->freeze = RTEST(val); }
1485
- else if (key == sym_on_load) { config->on_load_proc = RTEST(val) ? val : Qfalse; }
1519
+ else if (key == sym_on_load) { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
1486
1520
  else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; }
1487
1521
  else if (key == sym_decimal_class) {
1488
1522
  if (RTEST(val)) {
1489
1523
  if (rb_respond_to(val, i_try_convert)) {
1490
- config->decimal_class = val;
1524
+ parser_config_wb_write(self, &config->decimal_class, val);
1491
1525
  config->decimal_method_id = i_try_convert;
1492
1526
  } else if (rb_respond_to(val, i_new)) {
1493
- config->decimal_class = val;
1527
+ parser_config_wb_write(self, &config->decimal_class, val);
1494
1528
  config->decimal_method_id = i_new;
1495
1529
  } else if (RB_TYPE_P(val, T_CLASS)) {
1496
1530
  VALUE name = rb_class_name(val);
@@ -1499,7 +1533,7 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1499
1533
  if (last_colon) {
1500
1534
  const char *mod_path_end = last_colon - 1;
1501
1535
  VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
1502
- config->decimal_class = rb_path_to_class(mod_path);
1536
+ parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path));
1503
1537
 
1504
1538
  const char *method_name_beg = last_colon + 1;
1505
1539
  long before_len = method_name_beg - name_cstr;
@@ -1507,7 +1541,7 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1507
1541
  VALUE method_name = rb_str_substr(name, before_len, len);
1508
1542
  config->decimal_method_id = SYM2ID(rb_str_intern(method_name));
1509
1543
  } else {
1510
- config->decimal_class = rb_mKernel;
1544
+ parser_config_wb_write(self, &config->decimal_class, rb_mKernel);
1511
1545
  config->decimal_method_id = SYM2ID(rb_str_intern(name));
1512
1546
  }
1513
1547
  }
@@ -1517,16 +1551,21 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
1517
1551
  return ST_CONTINUE;
1518
1552
  }
1519
1553
 
1520
- static void parser_config_init(JSON_ParserConfig *config, VALUE opts)
1554
+ static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self)
1521
1555
  {
1522
1556
  config->max_nesting = 100;
1523
1557
 
1558
+ struct parser_config_init_args args = {
1559
+ .config = config,
1560
+ .self = self,
1561
+ };
1562
+
1524
1563
  if (!NIL_P(opts)) {
1525
1564
  Check_Type(opts, T_HASH);
1526
1565
  if (RHASH_SIZE(opts) > 0) {
1527
1566
  // We assume in most cases few keys are set so it's faster to go over
1528
1567
  // the provided keys than to check all possible keys.
1529
- rb_hash_foreach(opts, parser_config_init_i, (VALUE)config);
1568
+ rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args);
1530
1569
  }
1531
1570
 
1532
1571
  }
@@ -1560,17 +1599,21 @@ static VALUE cParserConfig_initialize(VALUE self, VALUE opts)
1560
1599
  rb_check_frozen(self);
1561
1600
  GET_PARSER_CONFIG;
1562
1601
 
1563
- parser_config_init(config, opts);
1564
-
1565
- RB_OBJ_WRITTEN(self, Qundef, config->decimal_class);
1602
+ parser_config_init(config, opts, self);
1566
1603
 
1567
1604
  return self;
1568
1605
  }
1569
1606
 
1570
- static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1607
+ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src)
1571
1608
  {
1572
- Vsource = convert_encoding(StringValue(Vsource));
1573
- StringValue(Vsource);
1609
+ VALUE Vsource = convert_encoding(src);
1610
+
1611
+ // Ensure the string isn't mutated under us.
1612
+ // The classic API to use is `rb_str_locktmp`, but then we'd
1613
+ // need to use `rb_protect` to make sure we always unlock.
1614
+ if (Vsource == src) {
1615
+ Vsource = rb_str_new_frozen(Vsource);
1616
+ }
1574
1617
 
1575
1618
  VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA];
1576
1619
  rvalue_stack stack = {
@@ -1581,6 +1624,7 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1581
1624
 
1582
1625
  long len;
1583
1626
  const char *start;
1627
+
1584
1628
  RSTRING_GETMEM(Vsource, start, len);
1585
1629
 
1586
1630
  VALUE stack_handle = 0;
@@ -1599,6 +1643,7 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
1599
1643
  // it won't cause a leak.
1600
1644
  rvalue_stack_eagerly_release(stack_handle);
1601
1645
  RB_GC_GUARD(stack_handle);
1646
+ RB_GC_GUARD(Vsource);
1602
1647
  json_ensure_eof(state);
1603
1648
 
1604
1649
  return result;
@@ -1619,12 +1664,9 @@ static VALUE cParserConfig_parse(VALUE self, VALUE Vsource)
1619
1664
 
1620
1665
  static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts)
1621
1666
  {
1622
- Vsource = convert_encoding(StringValue(Vsource));
1623
- StringValue(Vsource);
1624
-
1625
1667
  JSON_ParserConfig _config = {0};
1626
1668
  JSON_ParserConfig *config = &_config;
1627
- parser_config_init(config, opts);
1669
+ parser_config_init(config, opts, false);
1628
1670
 
1629
1671
  return cParser_parse(config, Vsource);
1630
1672
  }
@@ -307,6 +307,9 @@ module JSON
307
307
  if !opts.key?(:max_nesting) # defaults to 100
308
308
  @max_nesting = 100
309
309
  elsif opts[:max_nesting]
310
+ unless opts[:max_nesting].is_a?(Integer)
311
+ raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
312
+ end
310
313
  @max_nesting = opts[:max_nesting]
311
314
  else
312
315
  @max_nesting = 0
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.9'
5
5
  end
metadata CHANGED
@@ -1,10 +1,10 @@
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.9
5
5
  platform: ruby
6
6
  authors:
7
- - Florian Frank
7
+ - Florian Frank
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -13,78 +13,80 @@ description: This is a JSON implementation as a Ruby extension in C.
13
13
  email: flori@ping.de
14
14
  executables: []
15
15
  extensions:
16
- - ext/json/ext/generator/extconf.rb
17
- - ext/json/ext/parser/extconf.rb
16
+ - ext/json/ext/generator/extconf.rb
17
+ - ext/json/ext/parser/extconf.rb
18
18
  extra_rdoc_files:
19
- - README.md
19
+ - README.md
20
20
  files:
21
- - BSDL
22
- - CHANGES.md
23
- - COPYING
24
- - LEGAL
25
- - README.md
26
- - ext/json/ext/fbuffer/fbuffer.h
27
- - ext/json/ext/generator/extconf.rb
28
- - ext/json/ext/generator/generator.c
29
- - ext/json/ext/json.h
30
- - ext/json/ext/parser/extconf.rb
31
- - ext/json/ext/parser/parser.c
32
- - ext/json/ext/simd/conf.rb
33
- - ext/json/ext/simd/simd.h
34
- - ext/json/ext/vendor/fpconv.c
35
- - ext/json/ext/vendor/jeaiii-ltoa.h
36
- - ext/json/ext/vendor/ryu.h
37
- - json.gemspec
38
- - lib/json.rb
39
- - lib/json/add/bigdecimal.rb
40
- - lib/json/add/complex.rb
41
- - lib/json/add/core.rb
42
- - lib/json/add/date.rb
43
- - lib/json/add/date_time.rb
44
- - lib/json/add/exception.rb
45
- - lib/json/add/ostruct.rb
46
- - lib/json/add/range.rb
47
- - lib/json/add/rational.rb
48
- - lib/json/add/regexp.rb
49
- - lib/json/add/set.rb
50
- - lib/json/add/string.rb
51
- - lib/json/add/struct.rb
52
- - lib/json/add/symbol.rb
53
- - lib/json/add/time.rb
54
- - lib/json/common.rb
55
- - lib/json/ext.rb
56
- - lib/json/ext/generator/state.rb
57
- - lib/json/generic_object.rb
58
- - lib/json/truffle_ruby/generator.rb
59
- - lib/json/version.rb
60
- homepage: https://github.com/ruby/json
21
+ - BSDL
22
+ - CHANGES.md
23
+ - COPYING
24
+ - LEGAL
25
+ - README.md
26
+ - ext/json/ext/fbuffer/fbuffer.h
27
+ - ext/json/ext/generator/extconf.rb
28
+ - ext/json/ext/generator/generator.c
29
+ - ext/json/ext/json.h
30
+ - ext/json/ext/parser/extconf.rb
31
+ - ext/json/ext/parser/parser.c
32
+ - ext/json/ext/simd/conf.rb
33
+ - ext/json/ext/simd/simd.h
34
+ - ext/json/ext/vendor/fpconv.c
35
+ - ext/json/ext/vendor/jeaiii-ltoa.h
36
+ - ext/json/ext/vendor/ryu.h
37
+ - json.gemspec
38
+ - lib/json.rb
39
+ - lib/json/add/bigdecimal.rb
40
+ - lib/json/add/complex.rb
41
+ - lib/json/add/core.rb
42
+ - lib/json/add/date.rb
43
+ - lib/json/add/date_time.rb
44
+ - lib/json/add/exception.rb
45
+ - lib/json/add/ostruct.rb
46
+ - lib/json/add/range.rb
47
+ - lib/json/add/rational.rb
48
+ - lib/json/add/regexp.rb
49
+ - lib/json/add/set.rb
50
+ - lib/json/add/string.rb
51
+ - lib/json/add/struct.rb
52
+ - lib/json/add/symbol.rb
53
+ - lib/json/add/time.rb
54
+ - lib/json/common.rb
55
+ - lib/json/ext.rb
56
+ - lib/json/ext/generator/state.rb
57
+ - lib/json/generic_object.rb
58
+ - lib/json/truffle_ruby/generator.rb
59
+ - lib/json/version.rb
60
+ homepage: "https://github.com/ruby/json"
61
61
  licenses:
62
- - Ruby
62
+ - Ruby
63
63
  metadata:
64
- bug_tracker_uri: https://github.com/ruby/json/issues
65
- changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
66
- documentation_uri: https://docs.ruby-lang.org/en/master/JSON.html
67
- homepage_uri: https://github.com/ruby/json
68
- source_code_uri: https://github.com/ruby/json
64
+ bug_tracker_uri: "https://github.com/ruby/json/issues"
65
+ changelog_uri: "https://github.com/ruby/json/blob/master/CHANGES.md"
66
+ documentation_uri: "https://docs.ruby-lang.org/en/master/JSON.html"
67
+ homepage_uri: "https://github.com/ruby/json"
68
+ source_code_uri: "https://github.com/ruby/json"
69
69
  rdoc_options:
70
- - "--title"
71
- - JSON implementation for Ruby
72
- - "--main"
73
- - README.md
70
+ - "--title"
71
+ - JSON implementation for Ruby
72
+ - "--main"
73
+ - README.md
74
74
  require_paths:
75
- - lib
75
+ - lib
76
76
  required_ruby_version: !ruby/object:Gem::Requirement
77
77
  requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: '2.7'
78
+ -
79
+ - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "2.7"
81
82
  required_rubygems_version: !ruby/object:Gem::Requirement
82
83
  requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- version: '0'
84
+ -
85
+ - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
86
88
  requirements: []
87
- rubygems_version: 4.0.6
89
+ rubygems_version: 4.1.0.dev
88
90
  specification_version: 4
89
91
  summary: JSON Implementation for Ruby
90
92
  test_files: []