json 2.19.7 → 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 +4 -4
- data/CHANGES.md +10 -0
- data/README.md +11 -0
- data/ext/json/ext/fbuffer/fbuffer.h +21 -22
- data/ext/json/ext/generator/generator.c +5 -9
- data/ext/json/ext/parser/parser.c +14 -0
- data/lib/json/truffle_ruby/generator.rb +3 -0
- data/lib/json/version.rb +1 -1
- metadata +65 -63
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e5fed66aaa650ac7aaf223c4d8e505a2d6ce3fe72599af4931356ae619f020b
|
|
4
|
+
data.tar.gz: 347004780c7a7568685502ade79f145371a49a213d348a65c99ea8fbffc6eee7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bffdb4cd21e4656a1402a00d95ae890dc75befff379aeef4aad575a7f715a0dbeb87cfef6fefa3cd5235c3302a29fabb510d5db67e527678023cd8a88c34b49
|
|
7
|
+
data.tar.gz: 7e08cfae0c5d404687644528ecfb9438c9ea254f43fd285d116ba1542a4ef78045463b18850324e91ba4d0c735e7d9ed4b583499aadafe7d0bab51dd54a8d086
|
data/CHANGES.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
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
|
+
|
|
5
15
|
### 2026-05-28 (2.19.7)
|
|
6
16
|
|
|
7
17
|
* Fix some more edge cases with out of range floats.
|
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
|
|
40
|
+
static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size)
|
|
41
41
|
{
|
|
42
|
-
|
|
43
|
-
|
|
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
|
|
86
|
+
static void fbuffer_realloc(FBuffer *fb, size_t new_capa)
|
|
83
87
|
{
|
|
84
|
-
if (
|
|
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,
|
|
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,
|
|
95
|
+
REALLOC_N(fb->ptr, char, new_capa);
|
|
92
96
|
}
|
|
93
|
-
fb->capa =
|
|
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
|
|
101
|
-
fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
|
|
102
|
-
} else {
|
|
104
|
+
if (fb->capa != 0) {
|
|
103
105
|
fbuffer_flush(fb);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return;
|
|
106
|
+
if (RB_LIKELY(requested < fb->capa)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
size_t
|
|
112
|
+
size_t new_capa = fb->capa ? fb->capa : fb->initial_length;
|
|
113
|
+
size_t needed_capa = requested + fb->len;
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
fb->capa = fb->initial_length;
|
|
115
|
+
while (new_capa < needed_capa) {
|
|
116
|
+
new_capa *= 2;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
|
|
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)
|
|
@@ -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
|
-
|
|
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,
|
|
@@ -1581,7 +1579,7 @@ static VALUE cState_max_nesting(VALUE self)
|
|
|
1581
1579
|
|
|
1582
1580
|
static long long_config(VALUE num)
|
|
1583
1581
|
{
|
|
1584
|
-
return RTEST(num) ?
|
|
1582
|
+
return RTEST(num) ? NUM2LONG(num) : 0;
|
|
1585
1583
|
}
|
|
1586
1584
|
|
|
1587
1585
|
// depth must never be negative; reject early with a clear error.
|
|
@@ -1866,10 +1864,8 @@ static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io,
|
|
|
1866
1864
|
configure_state(&state, Qfalse, opts);
|
|
1867
1865
|
|
|
1868
1866
|
char stack_buffer[FBUFFER_STACK_SIZE];
|
|
1869
|
-
FBuffer buffer = {
|
|
1870
|
-
|
|
1871
|
-
};
|
|
1872
|
-
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);
|
|
1873
1869
|
|
|
1874
1870
|
struct generate_json_data data = {
|
|
1875
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
|
|
|
@@ -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
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.
|
|
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
|
-
|
|
80
|
-
|
|
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
|
-
|
|
85
|
-
|
|
84
|
+
-
|
|
85
|
+
- ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: "0"
|
|
86
88
|
requirements: []
|
|
87
|
-
rubygems_version: 4.0.
|
|
89
|
+
rubygems_version: 4.1.0.dev
|
|
88
90
|
specification_version: 4
|
|
89
91
|
summary: JSON Implementation for Ruby
|
|
90
92
|
test_files: []
|