json 2.15.1 → 2.15.2.1
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 +9 -0
- data/ext/json/ext/generator/generator.c +34 -5
- data/ext/json/ext/parser/parser.c +19 -7
- data/lib/json/truffle_ruby/generator.rb +5 -1
- data/lib/json/version.rb +1 -1
- 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: e0a73f62257d521165faeb372eafe66beb01fe47b4790256840f4316aa762510
|
|
4
|
+
data.tar.gz: 135d0b30fd72cd54b91b84050fe86a67b1aaf909f2024f5a545288cfbe3a2088
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d51c8d7de86d2581845d73638053da3f7c5aea014da4a960630fd78bba234647e37b301dec74f93069cc584d7f2495a394dc4a5d5514f543dee195413a863ebf
|
|
7
|
+
data.tar.gz: 3a871434b7427979f6c860e7ec33772ff61ddd0d272ac40de51fc887a14f50e65653d70b8276b2b535870a20801d7e6c2068b6f5bfb68293fc0e0de3a82aa729
|
data/CHANGES.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
### Unreleased
|
|
4
4
|
|
|
5
|
+
### 2026-03-18 (2.15.2.1)
|
|
6
|
+
|
|
7
|
+
* Fix a format string injection vulnerability in JSON.parse(doc, allow_duplicate_key: false).
|
|
8
|
+
|
|
9
|
+
### 2025-10-25 (2.15.2)
|
|
10
|
+
|
|
11
|
+
* Fix `JSON::Coder` to have one dedicated depth counter per invocation.
|
|
12
|
+
After encountering a circular reference in `JSON::Coder#dump`, any further `#dump` call would raise `JSON::NestingError`.
|
|
13
|
+
|
|
5
14
|
### 2025-10-07 (2.15.1)
|
|
6
15
|
|
|
7
16
|
* Fix incorrect escaping in the JRuby extension when encoding shared strings.
|
|
@@ -1124,7 +1124,7 @@ static inline long increase_depth(struct generate_json_data *data)
|
|
|
1124
1124
|
JSON_Generator_State *state = data->state;
|
|
1125
1125
|
long depth = ++state->depth;
|
|
1126
1126
|
if (RB_UNLIKELY(depth > state->max_nesting && state->max_nesting)) {
|
|
1127
|
-
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
|
1127
|
+
rb_raise(eNestingError, "nesting of %ld is too deep. Did you try to serialize objects with circular references?", --state->depth);
|
|
1128
1128
|
}
|
|
1129
1129
|
return depth;
|
|
1130
1130
|
}
|
|
@@ -1491,10 +1491,39 @@ static VALUE cState_generate(int argc, VALUE *argv, VALUE self)
|
|
|
1491
1491
|
rb_check_arity(argc, 1, 2);
|
|
1492
1492
|
VALUE obj = argv[0];
|
|
1493
1493
|
VALUE io = argc > 1 ? argv[1] : Qnil;
|
|
1494
|
-
|
|
1494
|
+
return cState_partial_generate(self, obj, generate_json, io);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
static VALUE cState_generate_new(int argc, VALUE *argv, VALUE self)
|
|
1498
|
+
{
|
|
1499
|
+
rb_check_arity(argc, 1, 2);
|
|
1500
|
+
VALUE obj = argv[0];
|
|
1501
|
+
VALUE io = argc > 1 ? argv[1] : Qnil;
|
|
1502
|
+
|
|
1495
1503
|
GET_STATE(self);
|
|
1496
|
-
|
|
1497
|
-
|
|
1504
|
+
|
|
1505
|
+
JSON_Generator_State new_state;
|
|
1506
|
+
MEMCPY(&new_state, state, JSON_Generator_State, 1);
|
|
1507
|
+
|
|
1508
|
+
// FIXME: depth shouldn't be part of JSON_Generator_State, as that prevents it from being used concurrently.
|
|
1509
|
+
new_state.depth = 0;
|
|
1510
|
+
|
|
1511
|
+
char stack_buffer[FBUFFER_STACK_SIZE];
|
|
1512
|
+
FBuffer buffer = {
|
|
1513
|
+
.io = RTEST(io) ? io : Qfalse,
|
|
1514
|
+
};
|
|
1515
|
+
fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE);
|
|
1516
|
+
|
|
1517
|
+
struct generate_json_data data = {
|
|
1518
|
+
.buffer = &buffer,
|
|
1519
|
+
.vstate = Qfalse,
|
|
1520
|
+
.state = &new_state,
|
|
1521
|
+
.obj = obj,
|
|
1522
|
+
.func = generate_json
|
|
1523
|
+
};
|
|
1524
|
+
rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data);
|
|
1525
|
+
|
|
1526
|
+
return fbuffer_finalize(&buffer);
|
|
1498
1527
|
}
|
|
1499
1528
|
|
|
1500
1529
|
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
|
|
@@ -2072,7 +2101,7 @@ void Init_generator(void)
|
|
|
2072
2101
|
rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
|
|
2073
2102
|
rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
|
|
2074
2103
|
rb_define_method(cState, "generate", cState_generate, -1);
|
|
2075
|
-
|
|
2104
|
+
rb_define_method(cState, "generate_new", cState_generate_new, -1); // :nodoc:
|
|
2076
2105
|
|
|
2077
2106
|
rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0);
|
|
2078
2107
|
|
|
@@ -428,14 +428,9 @@ static void emit_parse_warning(const char *message, JSON_ParserState *state)
|
|
|
428
428
|
|
|
429
429
|
#define PARSE_ERROR_FRAGMENT_LEN 32
|
|
430
430
|
|
|
431
|
-
|
|
432
|
-
RBIMPL_ATTR_NORETURN()
|
|
433
|
-
#endif
|
|
434
|
-
static void raise_parse_error(const char *format, JSON_ParserState *state)
|
|
431
|
+
static VALUE build_parse_error_message(const char *format, JSON_ParserState *state, long line, long column)
|
|
435
432
|
{
|
|
436
433
|
unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3];
|
|
437
|
-
long line, column;
|
|
438
|
-
cursor_position(state, &line, &column);
|
|
439
434
|
|
|
440
435
|
const char *ptr = "EOF";
|
|
441
436
|
if (state->cursor && state->cursor < state->end) {
|
|
@@ -470,11 +465,23 @@ static void raise_parse_error(const char *format, JSON_ParserState *state)
|
|
|
470
465
|
VALUE msg = rb_sprintf(format, ptr);
|
|
471
466
|
VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column);
|
|
472
467
|
RB_GC_GUARD(msg);
|
|
468
|
+
return message;
|
|
469
|
+
}
|
|
473
470
|
|
|
471
|
+
static VALUE parse_error_new(VALUE message, long line, long column)
|
|
472
|
+
{
|
|
474
473
|
VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message);
|
|
475
474
|
rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line));
|
|
476
475
|
rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column));
|
|
477
|
-
|
|
476
|
+
return exc;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state)
|
|
480
|
+
{
|
|
481
|
+
long line, column;
|
|
482
|
+
cursor_position(state, &line, &column);
|
|
483
|
+
VALUE message = build_parse_error_message(format, state, line, column);
|
|
484
|
+
rb_exc_raise(parse_error_new(message, line, column));
|
|
478
485
|
}
|
|
479
486
|
|
|
480
487
|
#ifdef RBIMPL_ATTR_NORETURN
|
|
@@ -875,6 +882,11 @@ static void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_k
|
|
|
875
882
|
rb_inspect(duplicate_key)
|
|
876
883
|
);
|
|
877
884
|
|
|
885
|
+
long line, column;
|
|
886
|
+
cursor_position(state, &line, &column);
|
|
887
|
+
rb_str_concat(message, build_parse_error_message("", state, line, column)) ;
|
|
888
|
+
rb_exc_raise(parse_error_new(message, line, column));
|
|
889
|
+
|
|
878
890
|
raise_parse_error(RSTRING_PTR(message), state);
|
|
879
891
|
RB_GC_GUARD(message);
|
|
880
892
|
}
|
|
@@ -212,7 +212,7 @@ module JSON
|
|
|
212
212
|
return if @max_nesting.zero?
|
|
213
213
|
current_nesting = depth + 1
|
|
214
214
|
current_nesting > @max_nesting and
|
|
215
|
-
raise NestingError, "nesting of #{current_nesting} is too deep"
|
|
215
|
+
raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
# Returns true, if circular data structures are checked,
|
|
@@ -347,6 +347,10 @@ module JSON
|
|
|
347
347
|
dup.generate(obj, anIO)
|
|
348
348
|
end
|
|
349
349
|
|
|
350
|
+
private def initialize_copy(_orig)
|
|
351
|
+
@depth = 0
|
|
352
|
+
end
|
|
353
|
+
|
|
350
354
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
|
351
355
|
private def generate_json(obj, buf)
|
|
352
356
|
case obj
|
data/lib/json/version.rb
CHANGED
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.15.1
|
|
4
|
+
version: 2.15.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: '0'
|
|
84
84
|
requirements: []
|
|
85
|
-
rubygems_version:
|
|
85
|
+
rubygems_version: 4.0.3
|
|
86
86
|
specification_version: 4
|
|
87
87
|
summary: JSON Implementation for Ruby
|
|
88
88
|
test_files: []
|