json 2.19.0 → 2.19.3

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: 2e0f63481c8ba1c4f76f44a86ac9f1814e82fb396125e41e95efddc8e259fe64
4
- data.tar.gz: a070ae0776f2db0519ec672d3a32be7dee2be2ee10d0bc35c9dde6581ec8c4a8
3
+ metadata.gz: 3182d9103a2ee3b673b923a4789e947a9cddb850f870f7fdb54d93f3bd1a5493
4
+ data.tar.gz: 0ee85345c9e1c99223f9cc3e859e4a7295f40f88461ca0f47059cfcc4e80154c
5
5
  SHA512:
6
- metadata.gz: fc49905c26e2173018856dba7c4ae10ef74f015233b607f977b42ceea5f1d9e511f9ad4a7c22d4aed66e4ef8c60ad23a506d8bb0e053c0155ea2f7eb40a82d06
7
- data.tar.gz: 61c1367d7b91621a34c0fc9fc29802534f14d27c1b9c50ecfa09d68d100fcda840847393063ec4c477437261398c559b93f292d2594bdf1e597c4b5e33959322
6
+ metadata.gz: dedf64066bc4017b977330468b01613ce1d4a78c267b38519b7ef2705368e5d73187b64ca99777afaf900cc5f58523a722833e83c0ee011944bf15b34c33479e
7
+ data.tar.gz: c187fa755e0a7bd2e2ddb74498062a8138ac4882630713e3372886b5648a22a453b1a388174038b2d4144a724e1d44d5b444b190e49e3e7eb2047d8b98eef0a8
data/CHANGES.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ ### 2026-03-25 (2.19.3)
6
+
7
+ * Fix handling of unescaped control characters preceeded by a backslash.
8
+
9
+ ### 2026-03-18 (2.19.2)
10
+
11
+ * Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`.
12
+
13
+ ### 2026-03-08 (2.19.1)
14
+
15
+ * Fix a compiler dependent GC bug introduced in `2.18.0`.
16
+
5
17
  ### 2026-03-06 (2.19.0)
6
18
 
7
19
  * Fix `allow_blank` parsing option to no longer allow invalid types (e.g. `load([], allow_blank: true)` now raise a type error).
@@ -166,6 +166,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
166
166
  RSTRING_GETMEM(str, ptr, len);
167
167
 
168
168
  fbuffer_append(fb, ptr, len);
169
+ RB_GC_GUARD(str);
169
170
  }
170
171
 
171
172
  static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
@@ -182,6 +183,7 @@ static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
182
183
  fbuffer_append_reserved(fb, ptr, len);
183
184
  repeat--;
184
185
  }
186
+ RB_GC_GUARD(str);
185
187
  }
186
188
 
187
189
  static inline void fbuffer_append_char(FBuffer *fb, char newchr)
@@ -402,11 +402,9 @@ static void emit_parse_warning(const char *message, JSON_ParserState *state)
402
402
 
403
403
  #define PARSE_ERROR_FRAGMENT_LEN 32
404
404
 
405
- NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state)
405
+ static VALUE build_parse_error_message(const char *format, JSON_ParserState *state, long line, long column)
406
406
  {
407
407
  unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3];
408
- long line, column;
409
- cursor_position(state, &line, &column);
410
408
 
411
409
  const char *ptr = "EOF";
412
410
  if (state->cursor && state->cursor < state->end) {
@@ -441,11 +439,23 @@ NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *st
441
439
  VALUE msg = rb_sprintf(format, ptr);
442
440
  VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column);
443
441
  RB_GC_GUARD(msg);
442
+ return message;
443
+ }
444
444
 
445
+ static VALUE parse_error_new(VALUE message, long line, long column)
446
+ {
445
447
  VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message);
446
448
  rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line));
447
449
  rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column));
448
- rb_exc_raise(exc);
450
+ return exc;
451
+ }
452
+
453
+ NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state)
454
+ {
455
+ long line, column;
456
+ cursor_position(state, &line, &column);
457
+ VALUE message = build_parse_error_message(format, state, line, column);
458
+ rb_exc_raise(parse_error_new(message, line, column));
449
459
  }
450
460
 
451
461
  NORETURN(static) void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at)
@@ -748,7 +758,9 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser
748
758
  }
749
759
  raise_parse_error_at("invalid ASCII control character in string: %s", state, pe - 1);
750
760
  }
751
- } else if (config->allow_invalid_escape) {
761
+ }
762
+
763
+ if (config->allow_invalid_escape) {
752
764
  APPEND_CHAR(*pe);
753
765
  } else {
754
766
  raise_parse_error_at("invalid escape character in string: %s", state, pe - 1);
@@ -895,6 +907,11 @@ NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE d
895
907
  rb_inspect(duplicate_key)
896
908
  );
897
909
 
910
+ long line, column;
911
+ cursor_position(state, &line, &column);
912
+ rb_str_concat(message, build_parse_error_message("", state, line, column)) ;
913
+ rb_exc_raise(parse_error_new(message, line, column));
914
+
898
915
  raise_parse_error(RSTRING_PTR(message), state);
899
916
  RB_GC_GUARD(message);
900
917
  }
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.0'
4
+ VERSION = '2.19.3'
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.0
4
+ version: 2.19.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank