Skip to content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Jan 6, 2026

Update the json gem using bundle update --conservative.

RubyGems.org: https://rubygems.org/gems/json/versions/2.14.0

Homepage: https://github.com/ruby/json

Changelog: https://github.com/ruby/json/blob/master/CHANGES.md

Releases:

@dentarg dentarg marked this pull request as ready for review January 6, 2026 12:03
@github-actions
Copy link
Contributor Author

github-actions bot commented Jan 6, 2026

@github-actions
Copy link
Contributor Author

github-actions bot commented Jan 6, 2026

gem compare json 2.13.2 2.14.0

Compared versions: ["2.13.2", "2.14.0"]
  DIFFERENT date:
    2.13.2: 2025-07-28 00:00:00 UTC
    2.14.0: 1980-01-02 00:00:00 UTC
  DIFFERENT require_paths:
    2.13.2: ["/opt/hostedtoolcache/Ruby/4.0.0/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.13.2", "lib"]
    2.14.0: ["/opt/hostedtoolcache/Ruby/4.0.0/x64/lib/ruby/gems/4.0.0/extensions/x86_64-linux/4.0.0/json-2.14.0", "lib"]
  DIFFERENT rubygems_version:
    2.13.2: 3.6.2
    2.14.0: 3.6.9
  DIFFERENT version:
    2.13.2: 2.13.2
    2.14.0: 2.14.0
  DIFFERENT files:
    2.13.2->2.14.0:
      * Added:
            lib/json/add/string.rb +35/-0
      * Changed:
            CHANGES.md +25/-8
            ext/json/ext/fbuffer/fbuffer.h +31/-5
            ext/json/ext/generator/generator.c +87/-88
            ext/json/ext/parser/parser.c +9/-4
            lib/json.rb +23/-1
            lib/json/add/core.rb +1/-0
            lib/json/common.rb +32/-7
            lib/json/ext/generator/state.rb +7/-14
            lib/json/generic_object.rb +0/-8
            lib/json/truffle_ruby/generator.rb +45/-35
            lib/json/version.rb +1/-1

@github-actions
Copy link
Contributor Author

github-actions bot commented Jan 6, 2026

gem compare --diff json 2.13.2 2.14.0

Compared versions: ["2.13.2", "2.14.0"]
  DIFFERENT files:
    2.13.2->2.14.0:
      * Added:
        lib/json/add/string.rb
                --- /tmp/20260106-520-hy9nxi	2026-01-06 12:04:04.723336719 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/add/string.rb	2026-01-06 12:04:04.722336722 +0000
                @@ -0,0 +1,35 @@
                +# frozen_string_literal: true
                +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
                +  require 'json'
                +end
                +
                +class String
                +  # call-seq: json_create(o)
                +  #
                +  # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
                +  # key "raw"). The Ruby String can be created by this class method.
                +  def self.json_create(object)
                +    object["raw"].pack("C*")
                +  end
                +
                +  # call-seq: to_json_raw_object()
                +  #
                +  # This method creates a raw object hash, that can be nested into
                +  # other data structures and will be generated as a raw string. This
                +  # method should be used, if you want to convert raw strings to JSON
                +  # instead of UTF-8 strings, e. g. binary data.
                +  def to_json_raw_object
                +    {
                +      JSON.create_id => self.class.name,
                +      "raw" => unpack("C*"),
                +    }
                +  end
                +
                +  # call-seq: to_json_raw(*args)
                +  #
                +  # This method creates a JSON text from the result of a call to
                +  # to_json_raw_object of this String.
                +  def to_json_raw(...)
                +    to_json_raw_object.to_json(...)
                +  end
                +end
      * Changed:
        CHANGES.md
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/CHANGES.md	2026-01-06 12:04:04.712336749 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/CHANGES.md	2026-01-06 12:04:04.718336733 +0000
                @@ -4,0 +5,16 @@
                +* Add new `allow_duplicate_key` generator options. By default a warning is now emitted when a duplicated key is encountered.
                +  In `json 3.0` an error will be raised.
                +  ```ruby
                +  >> Warning[:deprecated] = true
                +  >> puts JSON.generate({ foo: 1, "foo" => 2 })
                +  (irb):2: warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
                +  This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
                +  {"foo":1,"foo":2}
                +  >> JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
                +  detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
                +  ```
                +* Fix `JSON.generate` `strict: true` mode to also restrict hash keys.
                +* Fix `JSON::Coder` to also invoke block for hash keys that aren't strings nor symbols.
                +* Fix `JSON.unsafe_load` usage with proc
                +* Fix the parser to more consistently reject invalid UTF-16 surogate pairs. 
                +
                @@ -47 +63 @@
                -  These were deprecated 16 years ago, but never emited warnings, only undocumented, so are
                +  These were deprecated 16 years ago, but never emitted warnings, only undocumented, so are
                @@ -74 +90 @@
                -* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` unadvertently changed it.
                +* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` inadvertently changed it.
                @@ -105 +121 @@
                -* `JSON.load_file` explictly read the file as UTF-8.
                +* `JSON.load_file` explicitly read the file as UTF-8.
                @@ -113 +129 @@
                -* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explictly enabled.
                +* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explicitly enabled.
                @@ -121 +137 @@
                -* `JSON.pretty_generate` no longer include newline inside empty object and arrays. 
                +* `JSON.pretty_generate` no longer includes newlines inside empty object and arrays.
                @@ -138 +154 @@
                -* Make `json_pure` Ractor compatible. 
                +* Make `json_pure` Ractor compatible.
                @@ -143,2 +159,2 @@
                -* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparseable source.
                -* Fix json-pure's `Object#to_json` to accept non state arguments 
                +* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparsable source.
                +* Fix json-pure's `Object#to_json` to accept non-state arguments.
                @@ -288,0 +305 @@
                +  * Removed support for `quirks_mode` option.
        ext/json/ext/fbuffer/fbuffer.h
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/ext/json/ext/fbuffer/fbuffer.h	2026-01-06 12:04:04.713336747 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/ext/json/ext/fbuffer/fbuffer.h	2026-01-06 12:04:04.719336730 +0000
                @@ -26,0 +27,8 @@
                +#ifndef NOINLINE
                +#if defined(__has_attribute) && __has_attribute(noinline)
                +#define NOINLINE() __attribute__((noinline))
                +#else
                +#define NOINLINE()
                +#endif
                +#endif
                +
                @@ -172 +180,7 @@
                -static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
                +static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, unsigned long len)
                +{
                +    MEMCPY(fb->ptr + fb->len, newstr, char, len);
                +    fbuffer_consumed(fb, len);
                +}
                +
                +static inline void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
                @@ -176,2 +190 @@
                -        MEMCPY(fb->ptr + fb->len, newstr, char, len);
                -        fbuffer_consumed(fb, len);
                +        fbuffer_append_reserved(fb, newstr, len);
                @@ -200,2 +212,0 @@
                -    RB_GC_GUARD(str);
                -
                @@ -202,0 +214,15 @@
                +}
                +
                +static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
                +{
                +    const char *newstr = StringValuePtr(str);
                +    unsigned long len = RSTRING_LEN(str);
                +
                +    fbuffer_inc_capa(fb, repeat * len);
                +    while (repeat) {
                +#ifdef JSON_DEBUG
                +        fb->requested = len;
                +#endif
                +        fbuffer_append_reserved(fb, newstr, len);
                +        repeat--;
                +    }
        ext/json/ext/generator/generator.c
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/ext/json/ext/generator/generator.c	2026-01-06 12:04:04.713336747 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/ext/json/ext/generator/generator.c	2026-01-06 12:04:04.719336730 +0000
                @@ -11,0 +12,6 @@
                +enum duplicate_key_action {
                +    JSON_DEPRECATED = 0,
                +    JSON_IGNORE,
                +    JSON_RAISE,
                +};
                +
                @@ -23,0 +30,2 @@
                +    enum duplicate_key_action on_duplicate_key;
                +
                @@ -34 +42 @@
                -static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8;
                +static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_UTF_8;
                @@ -37 +45 @@
                -static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan,
                +static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, sym_allow_duplicate_key,
                @@ -140,2 +148,2 @@
                -    // For back-to-back characters that need to be escaped, specifcally for the SIMD code paths, this method
                -    // will be called just before calling escape_UTF8_char_basic. There will be no characers to append for the
                +    // For back-to-back characters that need to be escaped, specifically for the SIMD code paths, this method
                +    // will be called just before calling escape_UTF8_char_basic. There will be no characters to append for the
                @@ -839,12 +846,0 @@
                - * call-seq: String.included(modul)
                - *
                - * Extends _modul_ with the String::Extend module.
                - */
                -static VALUE mString_included_s(VALUE self, VALUE modul)
                -{
                -    VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
                -    rb_call_super(1, &modul);
                -    return result;
                -}
                -
                -/*
                @@ -865,45 +860,0 @@
                - * call-seq: to_json_raw_object()
                - *
                - * This method creates a raw object hash, that can be nested into
                - * other data structures and will be generated as a raw string. This
                - * method should be used, if you want to convert raw strings to JSON
                - * instead of UTF-8 strings, e. g. binary data.
                - */
                -static VALUE mString_to_json_raw_object(VALUE self)
                -{
                -    VALUE ary;
                -    VALUE result = rb_hash_new();
                -    rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
                -    ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
                -    rb_hash_aset(result, rb_utf8_str_new_lit("raw"), ary);
                -    return result;
                -}
                -
                -/*
                - * call-seq: to_json_raw(*args)
                - *
                - * This method creates a JSON text from the result of a call to
                - * to_json_raw_object of this String.
                - */
                -static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
                -{
                -    VALUE obj = mString_to_json_raw_object(self);
                -    Check_Type(obj, T_HASH);
                -    return mHash_to_json(argc, argv, obj);
                -}
                -
                -/*
                - * call-seq: json_create(o)
                - *
                - * Raw Strings are JSON Objects (the raw bytes are stored in an array for the
                - * key "raw"). The Ruby String can be created by this module method.
                - */
                -static VALUE mString_Extend_json_create(VALUE self, VALUE o)
                -{
                -    VALUE ary;
                -    Check_Type(o, T_HASH);
                -    ary = rb_hash_aref(o, rb_str_new2("raw"));
                -    return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
                -}
                -
                -/*
                @@ -1046,0 +998 @@
                +    VALUE hash;
                @@ -1048 +1000,3 @@
                -    int iter;
                +    int first_key_type;
                +    bool first;
                +    bool mixed_keys_encountered;
                @@ -1065,0 +1020,16 @@
                +NOINLINE()
                +static void
                +json_inspect_hash_with_mixed_keys(struct hash_foreach_arg *arg)
                +{
                +    if (arg->mixed_keys_encountered) {
                +        return;
                +    }
                +    arg->mixed_keys_encountered = true;
                +
                +    JSON_Generator_State *state = arg->data->state;
                +    if (state->on_duplicate_key != JSON_IGNORE) {
                +        VALUE do_raise = state->on_duplicate_key == JSON_RAISE ? Qtrue : Qfalse;
                +        rb_funcall(mJSON, rb_intern("on_mixed_keys_hash"), 2, arg->hash, do_raise);
                +    }
                +}
                +
                @@ -1076 +1046,9 @@
                -    int j;
                +    int key_type = rb_type(key);
                +
                +    if (arg->first) {
                +        arg->first = false;
                +        arg->first_key_type = key_type;
                +    }
                +    else {
                +        fbuffer_append_char(buffer, ',');
                +    }
                @@ -1078 +1055,0 @@
                -    if (arg->iter > 0) fbuffer_append_char(buffer, ',');
                @@ -1083,3 +1060 @@
                -        for (j = 0; j < depth; j++) {
                -            fbuffer_append_str(buffer, data->state->indent);
                -        }
                +        fbuffer_append_str_repeat(buffer, data->state->indent, depth);
                @@ -1089 +1064,4 @@
                -    switch (rb_type(key)) {
                +    bool as_json_called = false;
                +
                +  start:
                +    switch (key_type) {
                @@ -1090,0 +1069,4 @@
                +            if (RB_UNLIKELY(arg->first_key_type != T_STRING)) {
                +                json_inspect_hash_with_mixed_keys(arg);
                +            }
                +
                @@ -1097,0 +1080,4 @@
                +            if (RB_UNLIKELY(arg->first_key_type != T_SYMBOL)) {
                +                json_inspect_hash_with_mixed_keys(arg);
                +            }
                +
                @@ -1100,0 +1087,10 @@
                +            if (data->state->strict) {
                +                if (RTEST(data->state->as_json) && !as_json_called) {
                +                    key = rb_proc_call_with_block(data->state->as_json, 1, &key, Qnil);
                +                    key_type = rb_type(key);
                +                    as_json_called = true;
                +                    goto start;
                +                } else {
                +                    raise_generator_error(key, "%"PRIsVALUE" not allowed as object key in JSON", CLASS_OF(key));
                +                }
                +            }
                @@ -1115 +1110,0 @@
                -    arg->iter++;
                @@ -1131 +1125,0 @@
                -    int j;
                @@ -1142,0 +1137 @@
                +        .hash = obj,
                @@ -1144 +1139 @@
                -        .iter = 0,
                +        .first = true,
                @@ -1152,3 +1147 @@
                -            for (j = 0; j < depth; j++) {
                -                fbuffer_append_str(buffer, data->state->indent);
                -            }
                +            fbuffer_append_str_repeat(buffer, data->state->indent, depth);
                @@ -1162 +1154,0 @@
                -    int i, j;
                @@ -1173 +1165 @@
                -    for (i = 0; i < RARRAY_LEN(obj); i++) {
                +    for (int i = 0; i < RARRAY_LEN(obj); i++) {
                @@ -1179,3 +1171 @@
                -            for (j = 0; j < depth; j++) {
                -                fbuffer_append_str(buffer, data->state->indent);
                -            }
                +            fbuffer_append_str_repeat(buffer, data->state->indent, depth);
                @@ -1189,3 +1179 @@
                -            for (j = 0; j < depth; j++) {
                -                fbuffer_append_str(buffer, data->state->indent);
                -            }
                +            fbuffer_append_str_repeat(buffer, data->state->indent, depth);
                @@ -1852,0 +1841,13 @@
                +static VALUE cState_allow_duplicate_key_p(VALUE self)
                +{
                +    GET_STATE(self);
                +    switch (state->on_duplicate_key) {
                +        case JSON_IGNORE:
                +            return Qtrue;
                +        case JSON_DEPRECATED:
                +            return Qnil;
                +        default:
                +            return Qfalse;
                +    }
                +}
                +
                @@ -1941,0 +1943 @@
                +    else if (key == sym_allow_duplicate_key)   { state->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; }
                @@ -2066,0 +2069,2 @@
                +    rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0);
                +
                @@ -2094 +2097,0 @@
                -    rb_define_singleton_method(mString, "included", mString_included_s, 1);
                @@ -2096,5 +2098,0 @@
                -    rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1);
                -    rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0);
                -
                -    mString_Extend = rb_define_module_under(mString, "Extend");
                -    rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1);
                @@ -2136,0 +2135 @@
                +    sym_allow_duplicate_key = ID2SYM(rb_intern("allow_duplicate_key"));
        ext/json/ext/parser/parser.c
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/ext/json/ext/parser/parser.c	2026-01-06 12:04:04.714336744 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/ext/json/ext/parser/parser.c	2026-01-06 12:04:04.719336730 +0000
                @@ -715,0 +716,5 @@
                +
                +                            if ((sur & 0xFC00) != 0xDC00) {
                +                                raise_parse_error_at("invalid surrogate pair at %s", state, p);
                +                            }
                +
                @@ -720 +725 @@
                -                            unescape = (char *) "?";
                +                            raise_parse_error_at("incomplete surrogate pair at %s", state, p);
                @@ -978 +983 @@
                -        *state->cursor++;
                +        state->cursor++;
                @@ -1268 +1273 @@
                -    raise_parse_error("unreacheable: %s", state);
                +    raise_parse_error("unreachable: %s", state);
                @@ -1317 +1322 @@
                -    else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; }
                +    else if (key == sym_allow_duplicate_key)  { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; }
        lib/json.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json.rb	2026-01-06 12:04:04.715336741 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json.rb	2026-01-06 12:04:04.720336728 +0000
                @@ -136 +136 @@
                -#   # waring: detected duplicate keys in JSON object.
                +#   # warning: detected duplicate keys in JSON object.
                @@ -309,0 +310,19 @@
                +# Option +allow_duplicate_key+ (boolean) specifies whether
                +# hashes with duplicate keys should be allowed or produce an error.
                +# defaults to emit a deprecation warning.
                +#
                +# With the default, (not set):
                +#   Warning[:deprecated] = true
                +#   JSON.generate({ foo: 1, "foo" => 2 })
                +#   # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
                +#   # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
                +#   # => '{"foo":1,"foo":2}'
                +#
                +# With <tt>false</tt>
                +#   JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
                +#   # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
                +#
                +# In version 3.0, <tt>false</tt> will become the default.
                +#
                +# ---
                +#
                @@ -385,0 +405,3 @@
                +#
                +# Note that JSON Additions must only be used with trusted data, and is
                +# deprecated.
        lib/json/add/core.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/add/core.rb	2026-01-06 12:04:04.716336739 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/add/core.rb	2026-01-06 12:04:04.721336725 +0000
                @@ -9,0 +10 @@
                +require 'json/add/string'
        lib/json/common.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/common.rb	2026-01-06 12:04:04.717336736 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/common.rb	2026-01-06 12:04:04.722336722 +0000
                @@ -76 +76 @@
                -                if (klass.respond_to?(:json_creatable?) && klass.json_creatable?) || klass.respond_to?(:json_create)
                +                if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
                @@ -100 +100 @@
                -      gem_root = File.expand_path("../../../", __FILE__) + "/"
                +      gem_root = File.expand_path("..", __dir__) + "/"
                @@ -188,0 +189,19 @@
                +    # Called from the extension when a hash has both string and symbol keys
                +    def on_mixed_keys_hash(hash, do_raise)
                +      set = {}
                +      hash.each_key do |key|
                +        key_str = key.to_s
                +
                +        if set[key_str]
                +          message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
                +          if do_raise
                +            raise GeneratorError, message
                +          else
                +            deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
                +          end
                +        else
                +          set[key_str] = true
                +        end
                +      end
                +    end
                +
                @@ -394 +413 @@
                -  # See also JSON.fast_generate, JSON.pretty_generate.
                +  # See also JSON.pretty_generate.
                @@ -645,0 +665 @@
                +  #     obj
                @@ -687,3 +707,7 @@
                -    result = parse(source, opts)
                -    recurse_proc(result, &proc) if proc
                -    result
                +
                +    if proc
                +      opts = opts.dup
                +      opts[:on_load] = proc.to_proc
                +    end
                +
                +    parse(source, opts)
                @@ -805,0 +830 @@
                +  #     obj
                @@ -1005 +1030 @@
                -    # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
                +    # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
        lib/json/ext/generator/state.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/ext/generator/state.rb	2026-01-06 12:04:04.717336736 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/ext/generator/state.rb	2026-01-06 12:04:04.722336722 +0000
                @@ -11,14 +11,2 @@
                -        # _opts_ can have the following keys:
                -        #
                -        # * *indent*: a string used to indent levels (default: ''),
                -        # * *space*: a string that is put after, a : or , delimiter (default: ''),
                -        # * *space_before*: a string that is put before a : pair delimiter (default: ''),
                -        # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
                -        # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
                -        # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
                -        #   generated, otherwise an exception is thrown, if these values are
                -        #   encountered. This options defaults to false.
                -        # * *ascii_only*: true if only ASCII characters should be generated. This
                -        #   option defaults to false.
                -        # * *buffer_initial_length*: sets the initial length of the generator's
                -        #   internal buffer.
                +        # Argument +opts+, if given, contains a \Hash of options for the generation.
                +        # See {Generating Options}[#module-JSON-label-Generating+Options].
                @@ -69,0 +58,5 @@
                +
                +          allow_duplicate_key = allow_duplicate_key?
                +          unless allow_duplicate_key.nil?
                +            result[:allow_duplicate_key] = allow_duplicate_key
                +          end
        lib/json/generic_object.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/generic_object.rb	2026-01-06 12:04:04.717336736 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/generic_object.rb	2026-01-06 12:04:04.722336722 +0000
                @@ -55,8 +54,0 @@
                -    def [](name)
                -      __send__(name)
                -    end unless method_defined?(:[])
                -
                -    def []=(name, value)
                -      __send__("#{name}=", value)
                -    end unless method_defined?(:[]=)
                -
        lib/json/truffle_ruby/generator.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/truffle_ruby/generator.rb	2026-01-06 12:04:04.717336736 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/truffle_ruby/generator.rb	2026-01-06 12:04:04.723336719 +0000
                @@ -273,0 +274,6 @@
                +          if opts.key?(:allow_duplicate_key)
                +            @allow_duplicate_key = !!opts[:allow_duplicate_key]
                +          else
                +            @allow_duplicate_key = nil # nil is deprecation
                +          end
                +
                @@ -286,0 +293,4 @@
                +        def allow_duplicate_key? # :nodoc:
                +          @allow_duplicate_key
                +        end
                +
                @@ -294,0 +305,5 @@
                +
                +          if result[:allow_duplicate_key].nil?
                +            result.delete(:allow_duplicate_key)
                +          end
                +
                @@ -332,0 +348 @@
                +            key_type = nil
                @@ -334 +350,9 @@
                -              buf << ',' unless first
                +              if first
                +                key_type = k.class
                +              else
                +                if key_type && !@allow_duplicate_key && key_type != k.class
                +                  key_type = nil # stop checking
                +                  JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
                +                end
                +                buf << ','
                +              end
                @@ -473,0 +498 @@
                +            key_type = nil
                @@ -476 +501,9 @@
                -              result << delim unless first
                +              if first
                +                key_type = key.class
                +              else
                +                if key_type && !state.allow_duplicate_key? && key_type != key.class
                +                  key_type = nil # stop checking
                +                  JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
                +                end
                +                result << delim
                +              end
                @@ -478,0 +512,10 @@
                +              if state.strict? && !(Symbol === key || String === key)
                +                if state.as_json
                +                  key = state.as_json.call(key)
                +                end
                +
                +                unless Symbol === key || String === key
                +                  raise GeneratorError.new("#{key.class} not allowed as object key in JSON", value)
                +                end
                +              end
                +
                @@ -637,33 +679,0 @@
                -          end
                -
                -          # Module that holds the extending methods if, the String module is
                -          # included.
                -          module Extend
                -            # Raw Strings are JSON Objects (the raw bytes are stored in an
                -            # array for the key "raw"). The Ruby String can be created by this
                -            # module method.
                -            def json_create(o)
                -              o['raw'].pack('C*')
                -            end
                -          end
                -
                -          # Extends _modul_ with the String::Extend module.
                -          def self.included(modul)
                -            modul.extend Extend
                -          end
                -
                -          # This method creates a raw object hash, that can be nested into
                -          # other data structures and will be unparsed as a raw string. This
                -          # method should be used, if you want to convert raw strings to JSON
                -          # instead of UTF-8 strings, e. g. binary data.
                -          def to_json_raw_object
                -            {
                -              JSON.create_id  => self.class.name,
                -              'raw'           => self.unpack('C*'),
                -            }
                -          end
                -
                -          # This method creates a JSON text from the result of
                -          # a call to to_json_raw_object of this String.
                -          def to_json_raw(*args)
                -            to_json_raw_object.to_json(*args)
        lib/json/version.rb
                --- /tmp/d20260106-520-oqtjdc/json-2.13.2/lib/json/version.rb	2026-01-06 12:04:04.717336736 +0000
                +++ /tmp/d20260106-520-oqtjdc/json-2.14.0/lib/json/version.rb	2026-01-06 12:04:04.723336719 +0000
                @@ -4 +4 @@
                -  VERSION = '2.13.2'
                +  VERSION = '2.14.0'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants