json 2.7.5-java → 2.8.0-java
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 +15 -0
- data/README.md +8 -77
- data/json.gemspec +3 -1
- data/lib/json/add/bigdecimal.rb +1 -1
- data/lib/json/common.rb +200 -59
- data/lib/json/ext/generator/state.rb +1 -31
- data/lib/json/ext.rb +2 -4
- data/lib/json/{pure → truffle_ruby}/generator.rb +158 -117
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +15 -20
- metadata +4 -6
- data/lib/json/pure/parser.rb +0 -331
- data/lib/json/pure.rb +0 -16
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: '028722a95a19f36273e395c75c39bce1d12eeaccc31b208c16e3c12adece4ea1'
         | 
| 4 | 
            +
              data.tar.gz: d4c11f6be31a3aaf913ee7d3675dfba0a760aaeff18bf58894d4e6693955a909
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: fac7a86491aa6f5844d8de472f8b7f9f1cb977cce0ce02044d384d5cf65ab180a6545514270b1f8ace2113fc0f0fc1dfef41b2cac233392cc3cf7f6dd8f2ac13
         | 
| 7 | 
            +
              data.tar.gz: d3af20766bf04d0ac65d3812de0cad1d88957c495a8d23064b48aafc72a89476bdbd4dd506228728d9263265704fc9952cadeb9c20dbffad10ffb02bd5123e6a
         | 
    
        data/CHANGES.md
    CHANGED
    
    | @@ -1,5 +1,20 @@ | |
| 1 1 | 
             
            # Changes
         | 
| 2 2 |  | 
| 3 | 
            +
            ### 2024-11-06 (2.8.0)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explictly enabled.
         | 
| 6 | 
            +
              * Prefer to use `JSON.unsafe_load(string)` or `JSON.load(string, create_additions: true)`.
         | 
| 7 | 
            +
            * Emit a deprecation warning when serializing valid UTF-8 strings encoded in `ASCII_8BIT` aka `BINARY`.
         | 
| 8 | 
            +
            * Bump required Ruby version to 2.7.
         | 
| 9 | 
            +
            * Add support for optionally parsing trailing commas, via `allow_trailing_comma: true`, which in cunjunction with the
         | 
| 10 | 
            +
              pre-existing support for comments, make it suitable to parse `jsonc` documents.
         | 
| 11 | 
            +
            * Many performance improvements to `JSON.parse` and `JSON.load`, up to `1.7x` faster on real world documents.
         | 
| 12 | 
            +
            * Some minor performance improvements to `JSON.dump` and `JSON.generate`.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ### 2024-11-04 (2.7.6)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            * Fix a regression in JSON.generate when dealing with Hash keys that are string subclasses, call `to_json` on them.
         | 
| 17 | 
            +
             | 
| 3 18 | 
             
            ### 2024-10-25 (2.7.5)
         | 
| 4 19 |  | 
| 5 20 | 
             
            * Fix a memory leak when `#to_json` methods raise an exception.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -5,16 +5,10 @@ | |
| 5 5 | 
             
            ## Description
         | 
| 6 6 |  | 
| 7 7 | 
             
            This is an implementation of the JSON specification according to RFC 7159
         | 
| 8 | 
            -
            http://www.ietf.org/rfc/rfc7159.txt . | 
| 8 | 
            +
            http://www.ietf.org/rfc/rfc7159.txt .
         | 
| 9 9 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
            * The quite a bit faster native extension variant, which is in parts
         | 
| 13 | 
            -
              implemented in C or Java and comes with a parser generated by the [Ragel]
         | 
| 14 | 
            -
              state machine compiler.
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            Both variants of the JSON generator generate UTF-8 character sequences by
         | 
| 17 | 
            -
            default. If an :ascii\_only option with a true value is given, they escape all
         | 
| 10 | 
            +
            The JSON generator generate UTF-8 character sequences by default.
         | 
| 11 | 
            +
            If an :ascii\_only option with a true value is given, they escape all
         | 
| 18 12 | 
             
            non-ASCII and control characters with \uXXXX escape sequences, and support
         | 
| 19 13 | 
             
            UTF-16 surrogate pairs in order to be able to generate the whole range of
         | 
| 20 14 | 
             
            unicode code points.
         | 
| @@ -27,10 +21,6 @@ endpoint. | |
| 27 21 |  | 
| 28 22 | 
             
            ## Installation
         | 
| 29 23 |  | 
| 30 | 
            -
            It's recommended to use the extension variant of JSON, because it's faster than
         | 
| 31 | 
            -
            the pure ruby variant. If you cannot build it on your system, you can settle
         | 
| 32 | 
            -
            for the latter.
         | 
| 33 | 
            -
             | 
| 34 24 | 
             
            Install the gem and add to the application's Gemfile by executing:
         | 
| 35 25 |  | 
| 36 26 | 
             
                $ bundle add json
         | 
| @@ -39,12 +29,6 @@ If bundler is not being used to manage dependencies, install the gem by executin | |
| 39 29 |  | 
| 40 30 | 
             
                $ gem install json
         | 
| 41 31 |  | 
| 42 | 
            -
             | 
| 43 | 
            -
            There is also a pure ruby json only variant of the gem, that can be installed
         | 
| 44 | 
            -
            with:
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                $ gem install json_pure
         | 
| 47 | 
            -
             | 
| 48 32 | 
             
            ## Usage
         | 
| 49 33 |  | 
| 50 34 | 
             
            To use JSON you can
         | 
| @@ -53,20 +37,6 @@ To use JSON you can | |
| 53 37 | 
             
            require 'json'
         | 
| 54 38 | 
             
            ```
         | 
| 55 39 |  | 
| 56 | 
            -
            to load the installed variant (either the extension `'json'` or the pure
         | 
| 57 | 
            -
            variant `'json_pure'`). If you have installed the extension variant, you can
         | 
| 58 | 
            -
            pick either the extension variant or the pure variant by typing
         | 
| 59 | 
            -
             | 
| 60 | 
            -
            ```ruby
         | 
| 61 | 
            -
            require 'json/ext'
         | 
| 62 | 
            -
            ```
         | 
| 63 | 
            -
             | 
| 64 | 
            -
            or
         | 
| 65 | 
            -
             | 
| 66 | 
            -
            ```ruby
         | 
| 67 | 
            -
            require 'json/pure'
         | 
| 68 | 
            -
            ```
         | 
| 69 | 
            -
             | 
| 70 40 | 
             
            Now you can parse a JSON document into a ruby data structure by calling
         | 
| 71 41 |  | 
| 72 42 | 
             
            ```ruby
         | 
| @@ -82,50 +52,11 @@ You can also use the `pretty_generate` method (which formats the output more | |
| 82 52 | 
             
            verbosely and nicely) or `fast_generate` (which doesn't do any of the security
         | 
| 83 53 | 
             
            checks generate performs, e. g. nesting deepness checks).
         | 
| 84 54 |  | 
| 85 | 
            -
             | 
| 86 | 
            -
            generate a JSON document from an array or hash:
         | 
| 87 | 
            -
             | 
| 88 | 
            -
            ```ruby
         | 
| 89 | 
            -
            document = JSON 'test'  => 23 # => "{\"test\":23}"
         | 
| 90 | 
            -
            document = JSON['test' => 23] # => "{\"test\":23}"
         | 
| 91 | 
            -
            ```
         | 
| 92 | 
            -
             | 
| 93 | 
            -
            and
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            ```ruby
         | 
| 96 | 
            -
            data = JSON '{"test":23}'  # => {"test"=>23}
         | 
| 97 | 
            -
            data = JSON['{"test":23}'] # => {"test"=>23}
         | 
| 98 | 
            -
            ```
         | 
| 99 | 
            -
             | 
| 100 | 
            -
            You can choose to load a set of common additions to ruby core's objects if
         | 
| 101 | 
            -
            you
         | 
| 102 | 
            -
             | 
| 103 | 
            -
            ```ruby
         | 
| 104 | 
            -
            require 'json/add/core'
         | 
| 105 | 
            -
            ```
         | 
| 106 | 
            -
             | 
| 107 | 
            -
            After requiring this you can, e. g., serialise/deserialise Ruby ranges:
         | 
| 108 | 
            -
             | 
| 109 | 
            -
            ```ruby
         | 
| 110 | 
            -
            JSON JSON(1..10) # => 1..10
         | 
| 111 | 
            -
            ```
         | 
| 112 | 
            -
             | 
| 113 | 
            -
            To find out how to add JSON support to other or your own classes, read the
         | 
| 114 | 
            -
            section "More Examples" below.
         | 
| 115 | 
            -
             | 
| 116 | 
            -
            ## Serializing exceptions
         | 
| 117 | 
            -
             | 
| 118 | 
            -
            The JSON module doesn't extend `Exception` by default. If you convert an `Exception`
         | 
| 119 | 
            -
            object to JSON, it will by default only include the exception message.
         | 
| 120 | 
            -
             | 
| 121 | 
            -
            To include the full details, you must either load the `json/add/core` mentioned
         | 
| 122 | 
            -
            above, or specifically load the exception addition:
         | 
| 123 | 
            -
             | 
| 124 | 
            -
            ```ruby
         | 
| 125 | 
            -
            require 'json/add/exception'
         | 
| 126 | 
            -
            ```
         | 
| 55 | 
            +
            ## Handling arbitrary types
         | 
| 127 56 |  | 
| 128 | 
            -
             | 
| 57 | 
            +
            > [!CAUTION]
         | 
| 58 | 
            +
            > You should never use `JSON.unsafe_load` nor `JSON.parse(str, create_additions: true)` to parse untrusted user input,
         | 
| 59 | 
            +
            > as it can lead to remote code execution vulnerabilities.
         | 
| 129 60 |  | 
| 130 61 | 
             
            To create a JSON document from a ruby data structure, you can call
         | 
| 131 62 | 
             
            `JSON.generate` like that:
         | 
| @@ -191,7 +122,7 @@ JSON.parse json | |
| 191 122 | 
             
            # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
         | 
| 192 123 | 
             
            json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
         | 
| 193 124 | 
             
            # => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
         | 
| 194 | 
            -
            JSON. | 
| 125 | 
            +
            JSON.unsafe_load json
         | 
| 195 126 | 
             
            # => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
         | 
| 196 127 | 
             
            ```
         | 
| 197 128 |  | 
    
        data/json.gemspec
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line|
         | 
| 2 4 | 
             
              /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
         | 
| 3 5 | 
             
            end rescue nil
         | 
| @@ -19,7 +21,7 @@ spec = Gem::Specification.new do |s| | |
| 19 21 | 
             
                'wiki_uri'          => 'https://github.com/ruby/json/wiki'
         | 
| 20 22 | 
             
              }
         | 
| 21 23 |  | 
| 22 | 
            -
              s.required_ruby_version = Gem::Requirement.new(">= 2. | 
| 24 | 
            +
              s.required_ruby_version = Gem::Requirement.new(">= 2.7")
         | 
| 23 25 |  | 
| 24 26 | 
             
              if java_ext
         | 
| 25 27 | 
             
                s.description = "A JSON implementation as a JRuby extension."
         | 
    
        data/lib/json/add/bigdecimal.rb
    CHANGED
    
    
    
        data/lib/json/common.rb
    CHANGED
    
    | @@ -32,9 +32,7 @@ module JSON | |
| 32 32 | 
             
                  JSON.generate(object, opts)
         | 
| 33 33 | 
             
                end
         | 
| 34 34 |  | 
| 35 | 
            -
                # Returns the JSON parser class that is used by JSON. | 
| 36 | 
            -
                # JSON::Ext::Parser or JSON::Pure::Parser:
         | 
| 37 | 
            -
                #   JSON.parser # => JSON::Ext::Parser
         | 
| 35 | 
            +
                # Returns the JSON parser class that is used by JSON.
         | 
| 38 36 | 
             
                attr_reader :parser
         | 
| 39 37 |  | 
| 40 38 | 
             
                # Set the JSON parser class _parser_ to be used by JSON.
         | 
| @@ -49,18 +47,9 @@ module JSON | |
| 49 47 | 
             
                # level (absolute namespace path?). If there doesn't exist a constant at
         | 
| 50 48 | 
             
                # the given path, an ArgumentError is raised.
         | 
| 51 49 | 
             
                def deep_const_get(path) # :nodoc:
         | 
| 52 | 
            -
                   | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                    when p.const_defined?(c, true) then p.const_get(c)
         | 
| 56 | 
            -
                    else
         | 
| 57 | 
            -
                      begin
         | 
| 58 | 
            -
                        p.const_missing(c)
         | 
| 59 | 
            -
                      rescue NameError => e
         | 
| 60 | 
            -
                        raise ArgumentError, "can't get const #{path}: #{e}"
         | 
| 61 | 
            -
                      end
         | 
| 62 | 
            -
                    end
         | 
| 63 | 
            -
                  end
         | 
| 50 | 
            +
                  Object.const_get(path)
         | 
| 51 | 
            +
                rescue NameError => e
         | 
| 52 | 
            +
                  raise ArgumentError, "can't get const #{path}: #{e}"
         | 
| 64 53 | 
             
                end
         | 
| 65 54 |  | 
| 66 55 | 
             
                # Set the module _generator_ to be used by JSON.
         | 
| @@ -69,7 +58,7 @@ module JSON | |
| 69 58 | 
             
                  @generator = generator
         | 
| 70 59 | 
             
                  generator_methods = generator::GeneratorMethods
         | 
| 71 60 | 
             
                  for const in generator_methods.constants
         | 
| 72 | 
            -
                    klass =  | 
| 61 | 
            +
                    klass = const_get(const)
         | 
| 73 62 | 
             
                    modul = generator_methods.const_get(const)
         | 
| 74 63 | 
             
                    klass.class_eval do
         | 
| 75 64 | 
             
                      instance_methods(false).each do |m|
         | 
| @@ -106,14 +95,10 @@ module JSON | |
| 106 95 | 
             
                  )
         | 
| 107 96 | 
             
                end
         | 
| 108 97 |  | 
| 109 | 
            -
                # Returns the JSON generator module that is used by JSON. | 
| 110 | 
            -
                # either JSON::Ext::Generator or JSON::Pure::Generator:
         | 
| 111 | 
            -
                #   JSON.generator # => JSON::Ext::Generator
         | 
| 98 | 
            +
                # Returns the JSON generator module that is used by JSON.
         | 
| 112 99 | 
             
                attr_reader :generator
         | 
| 113 100 |  | 
| 114 | 
            -
                # Sets or Returns the JSON generator state class that is used by JSON. | 
| 115 | 
            -
                # either JSON::Ext::Generator::State or JSON::Pure::Generator::State:
         | 
| 116 | 
            -
                #   JSON.state # => JSON::Ext::Generator::State
         | 
| 101 | 
            +
                # Sets or Returns the JSON generator state class that is used by JSON.
         | 
| 117 102 | 
             
                attr_accessor :state
         | 
| 118 103 | 
             
              end
         | 
| 119 104 |  | 
| @@ -195,17 +180,17 @@ module JSON | |
| 195 180 | 
             
              # {Parsing \JSON}[#module-JSON-label-Parsing+JSON].
         | 
| 196 181 | 
             
              #
         | 
| 197 182 | 
             
              # Parses nested JSON objects:
         | 
| 198 | 
            -
              #   source =  | 
| 199 | 
            -
              # | 
| 200 | 
            -
              # | 
| 201 | 
            -
              # | 
| 202 | 
            -
              # | 
| 203 | 
            -
              # | 
| 204 | 
            -
              # | 
| 205 | 
            -
              # | 
| 206 | 
            -
              # | 
| 207 | 
            -
              # | 
| 208 | 
            -
              #    | 
| 183 | 
            +
              #   source = <<~JSON
         | 
| 184 | 
            +
              #     {
         | 
| 185 | 
            +
              #     "name": "Dave",
         | 
| 186 | 
            +
              #       "age" :40,
         | 
| 187 | 
            +
              #       "hats": [
         | 
| 188 | 
            +
              #         "Cattleman's",
         | 
| 189 | 
            +
              #         "Panama",
         | 
| 190 | 
            +
              #         "Tophat"
         | 
| 191 | 
            +
              #       ]
         | 
| 192 | 
            +
              #     }
         | 
| 193 | 
            +
              #   JSON
         | 
| 209 194 | 
             
              #   ruby = JSON.parse(source)
         | 
| 210 195 | 
             
              #   ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
         | 
| 211 196 | 
             
              #
         | 
| @@ -216,16 +201,7 @@ module JSON | |
| 216 201 | 
             
              #   JSON.parse('')
         | 
| 217 202 | 
             
              #
         | 
| 218 203 | 
             
              def parse(source, opts = nil)
         | 
| 219 | 
            -
                 | 
| 220 | 
            -
                  Parser.new(source).parse
         | 
| 221 | 
            -
                else
         | 
| 222 | 
            -
                  # NB: The ** shouldn't be required, but we have to deal with
         | 
| 223 | 
            -
                  # different versions of the `json` and `json_pure` gems being
         | 
| 224 | 
            -
                  # loaded concurrently.
         | 
| 225 | 
            -
                  # Prior to 2.7.3, `JSON::Ext::Parser` would only take kwargs.
         | 
| 226 | 
            -
                  # Ref: https://github.com/ruby/json/issues/650
         | 
| 227 | 
            -
                  Parser.new(source, **opts).parse
         | 
| 228 | 
            -
                end
         | 
| 204 | 
            +
                Parser.parse(source, opts)
         | 
| 229 205 | 
             
              end
         | 
| 230 206 |  | 
| 231 207 | 
             
              # :call-seq:
         | 
| @@ -307,11 +283,10 @@ module JSON | |
| 307 283 | 
             
              #
         | 
| 308 284 | 
             
              def generate(obj, opts = nil)
         | 
| 309 285 | 
             
                if State === opts
         | 
| 310 | 
            -
                   | 
| 286 | 
            +
                  opts.generate(obj)
         | 
| 311 287 | 
             
                else
         | 
| 312 | 
            -
                   | 
| 288 | 
            +
                  State.generate(obj, opts)
         | 
| 313 289 | 
             
                end
         | 
| 314 | 
            -
                state.generate(obj)
         | 
| 315 290 | 
             
              end
         | 
| 316 291 |  | 
| 317 292 | 
             
              # :stopdoc:
         | 
| @@ -404,6 +379,20 @@ module JSON | |
| 404 379 | 
             
              module_function :pretty_unparse
         | 
| 405 380 | 
             
              # :startdoc:
         | 
| 406 381 |  | 
| 382 | 
            +
              class << self
         | 
| 383 | 
            +
                # Sets or returns default options for the JSON.unsafe_load method.
         | 
| 384 | 
            +
                # Initially:
         | 
| 385 | 
            +
                #   opts = JSON.load_default_options
         | 
| 386 | 
            +
                #   opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true}
         | 
| 387 | 
            +
                attr_accessor :unsafe_load_default_options
         | 
| 388 | 
            +
              end
         | 
| 389 | 
            +
              self.unsafe_load_default_options = {
         | 
| 390 | 
            +
                :max_nesting      => false,
         | 
| 391 | 
            +
                :allow_nan        => true,
         | 
| 392 | 
            +
                :allow_blank      => true,
         | 
| 393 | 
            +
                :create_additions => true,
         | 
| 394 | 
            +
              }
         | 
| 395 | 
            +
             | 
| 407 396 | 
             
              class << self
         | 
| 408 397 | 
             
                # Sets or returns default options for the JSON.load method.
         | 
| 409 398 | 
             
                # Initially:
         | 
| @@ -412,11 +401,162 @@ module JSON | |
| 412 401 | 
             
                attr_accessor :load_default_options
         | 
| 413 402 | 
             
              end
         | 
| 414 403 | 
             
              self.load_default_options = {
         | 
| 415 | 
            -
                :max_nesting      => false,
         | 
| 416 404 | 
             
                :allow_nan        => true,
         | 
| 417 405 | 
             
                :allow_blank      => true,
         | 
| 418 | 
            -
                :create_additions =>  | 
| 406 | 
            +
                :create_additions => nil,
         | 
| 419 407 | 
             
              }
         | 
| 408 | 
            +
              # :call-seq:
         | 
| 409 | 
            +
              #   JSON.unsafe_load(source, proc = nil, options = {}) -> object
         | 
| 410 | 
            +
              #
         | 
| 411 | 
            +
              # Returns the Ruby objects created by parsing the given +source+.
         | 
| 412 | 
            +
              #
         | 
| 413 | 
            +
              # - Argument +source+ must be, or be convertible to, a \String:
         | 
| 414 | 
            +
              #   - If +source+ responds to instance method +to_str+,
         | 
| 415 | 
            +
              #     <tt>source.to_str</tt> becomes the source.
         | 
| 416 | 
            +
              #   - If +source+ responds to instance method +to_io+,
         | 
| 417 | 
            +
              #     <tt>source.to_io.read</tt> becomes the source.
         | 
| 418 | 
            +
              #   - If +source+ responds to instance method +read+,
         | 
| 419 | 
            +
              #     <tt>source.read</tt> becomes the source.
         | 
| 420 | 
            +
              #   - If both of the following are true, source becomes the \String <tt>'null'</tt>:
         | 
| 421 | 
            +
              #     - Option +allow_blank+ specifies a truthy value.
         | 
| 422 | 
            +
              #     - The source, as defined above, is +nil+ or the empty \String <tt>''</tt>.
         | 
| 423 | 
            +
              #   - Otherwise, +source+ remains the source.
         | 
| 424 | 
            +
              # - Argument +proc+, if given, must be a \Proc that accepts one argument.
         | 
| 425 | 
            +
              #   It will be called recursively with each result (depth-first order).
         | 
| 426 | 
            +
              #   See details below.
         | 
| 427 | 
            +
              #   BEWARE: This method is meant to serialise data from trusted user input,
         | 
| 428 | 
            +
              #   like from your own database server or clients under your control, it could
         | 
| 429 | 
            +
              #   be dangerous to allow untrusted users to pass JSON sources into it.
         | 
| 430 | 
            +
              # - Argument +opts+, if given, contains a \Hash of options for the parsing.
         | 
| 431 | 
            +
              #   See {Parsing Options}[#module-JSON-label-Parsing+Options].
         | 
| 432 | 
            +
              #   The default options can be changed via method JSON.unsafe_load_default_options=.
         | 
| 433 | 
            +
              #
         | 
| 434 | 
            +
              # ---
         | 
| 435 | 
            +
              #
         | 
| 436 | 
            +
              # When no +proc+ is given, modifies +source+ as above and returns the result of
         | 
| 437 | 
            +
              # <tt>parse(source, opts)</tt>;  see #parse.
         | 
| 438 | 
            +
              #
         | 
| 439 | 
            +
              # Source for following examples:
         | 
| 440 | 
            +
              #   source = <<~JSON
         | 
| 441 | 
            +
              #     {
         | 
| 442 | 
            +
              #       "name": "Dave",
         | 
| 443 | 
            +
              #       "age" :40,
         | 
| 444 | 
            +
              #       "hats": [
         | 
| 445 | 
            +
              #         "Cattleman's",
         | 
| 446 | 
            +
              #         "Panama",
         | 
| 447 | 
            +
              #         "Tophat"
         | 
| 448 | 
            +
              #       ]
         | 
| 449 | 
            +
              #     }
         | 
| 450 | 
            +
              #   JSON
         | 
| 451 | 
            +
              #
         | 
| 452 | 
            +
              # Load a \String:
         | 
| 453 | 
            +
              #   ruby = JSON.unsafe_load(source)
         | 
| 454 | 
            +
              #   ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
         | 
| 455 | 
            +
              #
         | 
| 456 | 
            +
              # Load an \IO object:
         | 
| 457 | 
            +
              #   require 'stringio'
         | 
| 458 | 
            +
              #   object = JSON.unsafe_load(StringIO.new(source))
         | 
| 459 | 
            +
              #   object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
         | 
| 460 | 
            +
              #
         | 
| 461 | 
            +
              # Load a \File object:
         | 
| 462 | 
            +
              #   path = 't.json'
         | 
| 463 | 
            +
              #   File.write(path, source)
         | 
| 464 | 
            +
              #   File.open(path) do |file|
         | 
| 465 | 
            +
              #     JSON.unsafe_load(file)
         | 
| 466 | 
            +
              #   end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}
         | 
| 467 | 
            +
              #
         | 
| 468 | 
            +
              # ---
         | 
| 469 | 
            +
              #
         | 
| 470 | 
            +
              # When +proc+ is given:
         | 
| 471 | 
            +
              # - Modifies +source+ as above.
         | 
| 472 | 
            +
              # - Gets the +result+ from calling <tt>parse(source, opts)</tt>.
         | 
| 473 | 
            +
              # - Recursively calls <tt>proc(result)</tt>.
         | 
| 474 | 
            +
              # - Returns the final result.
         | 
| 475 | 
            +
              #
         | 
| 476 | 
            +
              # Example:
         | 
| 477 | 
            +
              #   require 'json'
         | 
| 478 | 
            +
              #
         | 
| 479 | 
            +
              #   # Some classes for the example.
         | 
| 480 | 
            +
              #   class Base
         | 
| 481 | 
            +
              #     def initialize(attributes)
         | 
| 482 | 
            +
              #       @attributes = attributes
         | 
| 483 | 
            +
              #     end
         | 
| 484 | 
            +
              #   end
         | 
| 485 | 
            +
              #   class User    < Base; end
         | 
| 486 | 
            +
              #   class Account < Base; end
         | 
| 487 | 
            +
              #   class Admin   < Base; end
         | 
| 488 | 
            +
              #   # The JSON source.
         | 
| 489 | 
            +
              #   json = <<-EOF
         | 
| 490 | 
            +
              #   {
         | 
| 491 | 
            +
              #     "users": [
         | 
| 492 | 
            +
              #         {"type": "User", "username": "jane", "email": "jane@example.com"},
         | 
| 493 | 
            +
              #         {"type": "User", "username": "john", "email": "john@example.com"}
         | 
| 494 | 
            +
              #     ],
         | 
| 495 | 
            +
              #     "accounts": [
         | 
| 496 | 
            +
              #         {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
         | 
| 497 | 
            +
              #         {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
         | 
| 498 | 
            +
              #     ],
         | 
| 499 | 
            +
              #     "admins": {"type": "Admin", "password": "0wn3d"}
         | 
| 500 | 
            +
              #   }
         | 
| 501 | 
            +
              #   EOF
         | 
| 502 | 
            +
              #   # Deserializer method.
         | 
| 503 | 
            +
              #   def deserialize_obj(obj, safe_types = %w(User Account Admin))
         | 
| 504 | 
            +
              #     type = obj.is_a?(Hash) && obj["type"]
         | 
| 505 | 
            +
              #     safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
         | 
| 506 | 
            +
              #   end
         | 
| 507 | 
            +
              #   # Call to JSON.unsafe_load
         | 
| 508 | 
            +
              #   ruby = JSON.unsafe_load(json, proc {|obj|
         | 
| 509 | 
            +
              #     case obj
         | 
| 510 | 
            +
              #     when Hash
         | 
| 511 | 
            +
              #       obj.each {|k, v| obj[k] = deserialize_obj v }
         | 
| 512 | 
            +
              #     when Array
         | 
| 513 | 
            +
              #       obj.map! {|v| deserialize_obj v }
         | 
| 514 | 
            +
              #     end
         | 
| 515 | 
            +
              #   })
         | 
| 516 | 
            +
              #   pp ruby
         | 
| 517 | 
            +
              # Output:
         | 
| 518 | 
            +
              #   {"users"=>
         | 
| 519 | 
            +
              #      [#<User:0x00000000064c4c98
         | 
| 520 | 
            +
              #        @attributes=
         | 
| 521 | 
            +
              #          {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
         | 
| 522 | 
            +
              #        #<User:0x00000000064c4bd0
         | 
| 523 | 
            +
              #        @attributes=
         | 
| 524 | 
            +
              #          {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
         | 
| 525 | 
            +
              #    "accounts"=>
         | 
| 526 | 
            +
              #      [{"account"=>
         | 
| 527 | 
            +
              #          #<Account:0x00000000064c4928
         | 
| 528 | 
            +
              #          @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
         | 
| 529 | 
            +
              #       {"account"=>
         | 
| 530 | 
            +
              #          #<Account:0x00000000064c4680
         | 
| 531 | 
            +
              #          @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
         | 
| 532 | 
            +
              #    "admins"=>
         | 
| 533 | 
            +
              #      #<Admin:0x00000000064c41f8
         | 
| 534 | 
            +
              #      @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
         | 
| 535 | 
            +
              #
         | 
| 536 | 
            +
              def unsafe_load(source, proc = nil, options = nil)
         | 
| 537 | 
            +
                opts = if options.nil?
         | 
| 538 | 
            +
                  unsafe_load_default_options
         | 
| 539 | 
            +
                else
         | 
| 540 | 
            +
                  unsafe_load_default_options.merge(options)
         | 
| 541 | 
            +
                end
         | 
| 542 | 
            +
             | 
| 543 | 
            +
                unless source.is_a?(String)
         | 
| 544 | 
            +
                  if source.respond_to? :to_str
         | 
| 545 | 
            +
                    source = source.to_str
         | 
| 546 | 
            +
                  elsif source.respond_to? :to_io
         | 
| 547 | 
            +
                    source = source.to_io.read
         | 
| 548 | 
            +
                  elsif source.respond_to?(:read)
         | 
| 549 | 
            +
                    source = source.read
         | 
| 550 | 
            +
                  end
         | 
| 551 | 
            +
                end
         | 
| 552 | 
            +
             | 
| 553 | 
            +
                if opts[:allow_blank] && (source.nil? || source.empty?)
         | 
| 554 | 
            +
                  source = 'null'
         | 
| 555 | 
            +
                end
         | 
| 556 | 
            +
                result = parse(source, opts)
         | 
| 557 | 
            +
                recurse_proc(result, &proc) if proc
         | 
| 558 | 
            +
                result
         | 
| 559 | 
            +
              end
         | 
| 420 560 |  | 
| 421 561 | 
             
              # :call-seq:
         | 
| 422 562 | 
             
              #   JSON.load(source, proc = nil, options = {}) -> object
         | 
| @@ -440,6 +580,7 @@ module JSON | |
| 440 580 | 
             
              #   BEWARE: This method is meant to serialise data from trusted user input,
         | 
| 441 581 | 
             
              #   like from your own database server or clients under your control, it could
         | 
| 442 582 | 
             
              #   be dangerous to allow untrusted users to pass JSON sources into it.
         | 
| 583 | 
            +
              #   If you must use it, use JSON.unsafe_load instead to make it clear.
         | 
| 443 584 | 
             
              # - Argument +opts+, if given, contains a \Hash of options for the parsing.
         | 
| 444 585 | 
             
              #   See {Parsing Options}[#module-JSON-label-Parsing+Options].
         | 
| 445 586 | 
             
              #   The default options can be changed via method JSON.load_default_options=.
         | 
| @@ -450,17 +591,17 @@ module JSON | |
| 450 591 | 
             
              # <tt>parse(source, opts)</tt>;  see #parse.
         | 
| 451 592 | 
             
              #
         | 
| 452 593 | 
             
              # Source for following examples:
         | 
| 453 | 
            -
              #   source =  | 
| 454 | 
            -
              # | 
| 455 | 
            -
              # | 
| 456 | 
            -
              # | 
| 457 | 
            -
              # | 
| 458 | 
            -
              # | 
| 459 | 
            -
              # | 
| 460 | 
            -
              # | 
| 461 | 
            -
              # | 
| 462 | 
            -
              # | 
| 463 | 
            -
              #    | 
| 594 | 
            +
              #   source = <<~JSON
         | 
| 595 | 
            +
              #     {
         | 
| 596 | 
            +
              #       "name": "Dave",
         | 
| 597 | 
            +
              #       "age" :40,
         | 
| 598 | 
            +
              #       "hats": [
         | 
| 599 | 
            +
              #         "Cattleman's",
         | 
| 600 | 
            +
              #         "Panama",
         | 
| 601 | 
            +
              #         "Tophat"
         | 
| 602 | 
            +
              #       ]
         | 
| 603 | 
            +
              #     }
         | 
| 604 | 
            +
              #   JSON
         | 
| 464 605 | 
             
              #
         | 
| 465 606 | 
             
              # Load a \String:
         | 
| 466 607 | 
             
              #   ruby = JSON.load(source)
         | 
| @@ -42,37 +42,7 @@ module JSON | |
| 42 42 | 
             
                          raise TypeError, "can't convert #{opts.class} into Hash"
         | 
| 43 43 | 
             
                        end
         | 
| 44 44 | 
             
                      end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                      opts.each do |key, value|
         | 
| 47 | 
            -
                        case key
         | 
| 48 | 
            -
                        when :indent
         | 
| 49 | 
            -
                          self.indent = value || ''
         | 
| 50 | 
            -
                        when :space
         | 
| 51 | 
            -
                          self.space = value || ''
         | 
| 52 | 
            -
                        when :space_before
         | 
| 53 | 
            -
                          self.space_before = value || ''
         | 
| 54 | 
            -
                        when :array_nl
         | 
| 55 | 
            -
                          self.array_nl = value || ''
         | 
| 56 | 
            -
                        when :object_nl
         | 
| 57 | 
            -
                          self.object_nl = value || ''
         | 
| 58 | 
            -
                        when :max_nesting
         | 
| 59 | 
            -
                          self.max_nesting = value || 0
         | 
| 60 | 
            -
                        when :depth
         | 
| 61 | 
            -
                          self.depth = value
         | 
| 62 | 
            -
                        when :buffer_initial_length
         | 
| 63 | 
            -
                          self.buffer_initial_length = value
         | 
| 64 | 
            -
                        when :allow_nan
         | 
| 65 | 
            -
                          self.allow_nan = value
         | 
| 66 | 
            -
                        when :ascii_only
         | 
| 67 | 
            -
                          self.ascii_only = value
         | 
| 68 | 
            -
                        when :script_safe, :escape_slash
         | 
| 69 | 
            -
                          self.script_safe = value
         | 
| 70 | 
            -
                        when :strict
         | 
| 71 | 
            -
                          self.strict = value
         | 
| 72 | 
            -
                        end
         | 
| 73 | 
            -
                      end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                      self
         | 
| 45 | 
            +
                      _configure(opts)
         | 
| 76 46 | 
             
                    end
         | 
| 77 47 |  | 
| 78 48 | 
             
                    alias_method :merge, :configure
         | 
    
        data/lib/json/ext.rb
    CHANGED
    
    | @@ -8,14 +8,12 @@ module JSON | |
| 8 8 | 
             
              module Ext
         | 
| 9 9 | 
             
                if RUBY_ENGINE == 'truffleruby'
         | 
| 10 10 | 
             
                  require 'json/ext/parser'
         | 
| 11 | 
            -
                  require 'json/ | 
| 12 | 
            -
                  $DEBUG and warn "Using Ext extension for JSON parser and Pure library for JSON generator."
         | 
| 11 | 
            +
                  require 'json/truffle_ruby/generator'
         | 
| 13 12 | 
             
                  JSON.parser = Parser
         | 
| 14 | 
            -
                  JSON.generator = JSON:: | 
| 13 | 
            +
                  JSON.generator = ::JSON::TruffleRuby::Generator
         | 
| 15 14 | 
             
                else
         | 
| 16 15 | 
             
                  require 'json/ext/parser'
         | 
| 17 16 | 
             
                  require 'json/ext/generator'
         | 
| 18 | 
            -
                  $DEBUG and warn "Using Ext extension for JSON."
         | 
| 19 17 | 
             
                  JSON.parser = Parser
         | 
| 20 18 | 
             
                  JSON.generator = Generator
         | 
| 21 19 | 
             
                end
         |