Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-json_pure for 
openSUSE:Factory checked in at 2024-02-26 19:48:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-json_pure (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-json_pure.new.1770 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-json_pure"

Mon Feb 26 19:48:56 2024 rev:32 rq:1151726 version:2.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-json_pure/rubygem-json_pure.changes      
2022-12-13 18:57:07.139732155 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-json_pure.new.1770/rubygem-json_pure.changes
    2024-02-26 19:50:02.263988170 +0100
@@ -1,0 +2,89 @@
+Mon Jan 29 14:10:24 UTC 2024 - Dan Čermák <dan.cer...@posteo.net>
+
+- 2.7.1:
+
+## What's Changed
+
+### Improved
+* [DOC] RDoc for additions by @BurdetteLamar in 
https://github.com/flori/json/pull/557
+
+### Fixed 
+* JSON.dump: handle unenclosed hashes regression by @casperisfine in 
https://github.com/flori/json/pull/554
+* Overload kwargs in JSON.dump by @k0kubun in 
https://github.com/flori/json/pull/556
+* Fix JSON.dump overload combination by @tompng in 
https://github.com/flori/json/pull/558
+
+
+### Misc
+* Remove needless encodings by @hsbt in https://github.com/flori/json/pull/559
+* Unify versions by @hsbt in https://github.com/flori/json/pull/560
+
+## New Contributors
+* @k0kubun made their first contribution in 
https://github.com/flori/json/pull/556
+* @tompng made their first contribution in 
https://github.com/flori/json/pull/558
+
+**Full Changelog**: https://github.com/flori/json/compare/v2.7.0...v2.7.1
+
+2.7.0:
+
+## What's Changed
+
+### Improved
+
+* Perf. improvements to Hash#to_json in pure implementation generator. by 
@vipulnsward in https://github.com/flori/json/pull/203
+* Remove unnecessary initialization of create_id in JSON.parse() by 
@Watson1978 in https://github.com/flori/json/pull/454
+
+### Added 
+
+* Call `super` in `included` hook by @paracycle in 
https://github.com/flori/json/pull/486
+* Rename escape_slash in script_safe and also escape E+2028 and E+2029 by 
@casperisfine in https://github.com/flori/json/pull/525
+* Add a `strict` option to Generator by @casperisfine in 
https://github.com/flori/json/pull/519
+
+### Fixed
+
+* Fix homepage url in gemspec by @unasuke in 
https://github.com/flori/json/pull/508
+* Fix dead link to Ragel in README by @okuramasafumi in 
https://github.com/flori/json/pull/509
+* [DOC] Fix yet another dead link to Ragel by @nobu in 
https://github.com/flori/json/pull/510
+* Fix "unexpected token" offset for Infinity by @jhawthorn in 
https://github.com/flori/json/pull/507
+* Use ruby_xfree to free buffers by @casperisfine in 
https://github.com/flori/json/pull/518
+
+### Compatibility changes
+
+* JRuby requires a minimum of Java 8 by @headius in 
https://github.com/flori/json/pull/516
+* Rename JSON::ParseError to JSON:ParserError by @dalizard in 
https://github.com/flori/json/pull/530
+* Removed code for Ruby 1.8 by @hsbt in https://github.com/flori/json/pull/540
+* alias_method is private on Ruby 2.3 and 2.4 by @hsbt in 
https://github.com/flori/json/pull/541
+* remove_method of Module is private at Ruby 2.3 and 2.4 by @hsbt in 
https://github.com/flori/json/pull/544
+* [jruby] avoid using deprecated BigDecimal.new by @kares in 
https://github.com/flori/json/pull/546
+* Always indent even if empty by @headius in 
https://github.com/flori/json/pull/517
+
+### Misc
+* Update CI matrix by @hsbt in https://github.com/flori/json/pull/521
+* Add missing changelog entries for 1.8.5 and 1.8.6 by @r7kamura in 
https://github.com/flori/json/pull/520
+* Actions workflow - Add new OS's, Ruby 3.1, Ruby master, Windows by @MSP-Greg 
in https://github.com/flori/json/pull/491
+* Skip unsupported test on JRuby by @nobu in 
https://github.com/flori/json/pull/532
+* Skip BigDecimal tests when it's missing to load by @hsbt in 
https://github.com/flori/json/pull/533
+* Simplify by @nobu in https://github.com/flori/json/pull/531
+* Load extension ('json/ext') consistently in test_ext by @aeroastro in 
https://github.com/flori/json/pull/536
+* Use test-unit-ruby-core gem by @hsbt in 
https://github.com/flori/json/pull/539
+* [CI] Add Windows mswin job by @MSP-Greg in 
https://github.com/flori/json/pull/545
+* Exclude truffleruby-head from Actions by @hsbt in 
https://github.com/flori/json/pull/551
+* tests/ractor_test.rb: make assert_separately available by @lucaskanashiro in 
https://github.com/flori/json/pull/506
+* Added changes for 2.7.0 and restore entries to 2.6.3 and 2.6.2 by @hsbt in 
https://github.com/flori/json/pull/552
+
+## New Contributors
+* @unasuke made their first contribution in 
https://github.com/flori/json/pull/508
+* @okuramasafumi made their first contribution in 
https://github.com/flori/json/pull/509
+* @r7kamura made their first contribution in 
https://github.com/flori/json/pull/520
+* @MSP-Greg made their first contribution in 
https://github.com/flori/json/pull/491
+* @paracycle made their first contribution in 
https://github.com/flori/json/pull/486
+* @dalizard made their first contribution in 
https://github.com/flori/json/pull/530
+* @aeroastro made their first contribution in 
https://github.com/flori/json/pull/536
+* @jhawthorn made their first contribution in 
https://github.com/flori/json/pull/507
+* @lucaskanashiro made their first contribution in 
https://github.com/flori/json/pull/506
+* @Watson1978 made their first contribution in 
https://github.com/flori/json/pull/454
+
+**Full Changelog**: https://github.com/flori/json/compare/v2.6.3...v2.7.0
+
+
+
+-------------------------------------------------------------------

Old:
----
  json_pure-2.6.3.gem

New:
----
  json_pure-2.7.1.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-json_pure.spec ++++++
--- /var/tmp/diff_new_pack.oaEc5y/_old  2024-02-26 19:50:03.220022732 +0100
+++ /var/tmp/diff_new_pack.oaEc5y/_new  2024-02-26 19:50:03.220022732 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-json_pure
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,21 +24,19 @@
 #
 
 Name:           rubygem-json_pure
-Version:        2.6.3
+Version:        2.7.1
 Release:        0
 %define mod_name json_pure
 %define mod_full_name %{mod_name}-%{version}
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  %{ruby >= 2.3}
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  %{rubygem rdoc > 3.10}
 BuildRequires:  ruby-macros >= 5
-URL:            http://flori.github.com/json
+URL:            https://flori.github.io/json
 Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Source1:        gem2rpm.yml
 Summary:        JSON Implementation for Ruby
 License:        Ruby
-Group:          Development/Languages/Ruby
 
 %description
 This is a JSON implementation in pure Ruby.

++++++ json_pure-2.6.3.gem -> json_pure-2.7.1.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGES.md new/CHANGES.md
--- old/CHANGES.md      2022-12-05 12:09:33.000000000 +0100
+++ new/CHANGES.md      2023-12-05 05:01:42.000000000 +0100
@@ -1,5 +1,38 @@
 # Changes
 
+### 2023-12-05 (2.7.1)
+
+* JSON.dump: handle unenclosed hashes regression #554
+* Overload kwargs in JSON.dump #556
+* [DOC] RDoc for additions #557
+* Fix JSON.dump overload combination #558
+
+### 2023-12-01 (2.7.0)
+
+* Add a strict option to Generator #519
+* `escape_slash` option was renamed as `script_safe` and now also escape 
U+2028 and U+2029. `escape_slash` is now an alias of `script_safe` #525
+* Remove unnecessary initialization of create_id in JSON.parse() #454
+* Improvements to Hash#to_json in pure implementation generator #203
+* Use ruby_xfree to free buffers #518
+* Fix "unexpected token" offset for Infinity #507
+* Avoid using deprecated BigDecimal.new on JRuby #546
+* Removed code for Ruby 1.8 #540
+* Rename JSON::ParseError to JSON:ParserError #530
+* Call super in included hook #486
+* JRuby requires a minimum of Java 8 #516
+* Always indent even if empty #517
+
+### 2022-11-30 (2.6.3)
+
+* bugfix json/pure mixing escaped with literal unicode raises 
Encoding::CompatibilityError #483
+* Stop including the parser source __LINE__ in exceptions #470
+
+### 2022-11-17 (2.6.2)
+
+* Remove unknown keyword arg from DateTime.parse #488
+* Ignore java artifacts by @hsbt #489
+* Fix parser bug for empty string allocation #496
+
 ### 2021-10-24 (2.6.1)
 
 * Restore version.rb with 2.6.1
@@ -100,6 +133,19 @@
   * There were still some mentions of dual GPL licensing in the source, but 
JSON
     has just the Ruby license that itself includes an explicit dual-licensing
     clause that allows covered software to be distributed under the terms of
+    the Simplified BSD License instead for all ruby versions >= 1.9.3. This is
+    however a GPL compatible license according to the Free Software Foundation.
+    I changed these mentions to be consistent with the Ruby license setting in
+    the gemspec files which were already correct now.
+
+## 2017-01-13 (1.8.6)
+  * Be compatible with ancient ruby 1.8 (maybe?)
+
+## 2015-09-11 (1.8.5)
+  * Be compatible with ruby 2.4.0
+  * There were still some mentions of dual GPL licensing in the source, but 
JSON
+    has just the Ruby license that itself includes an explicit dual-licensing
+    clause that allows covered software to be distributed under the terms of
     the Simplified BSD License instead for all ruby versions >= 1.9.3. This is
     however a GPL compatible license according to the Free Software Foundation.
     I changed these mentions to be consistent with the Ruby license setting in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2022-12-05 12:09:33.000000000 +0100
+++ new/README.md       2023-12-05 05:01:42.000000000 +0100
@@ -12,8 +12,7 @@
   extensions, which are both part of the ruby standard library.
 * The quite a bit faster native extension variant, which is in parts
   implemented in C or Java and comes with its own unicode conversion
-  functions and a parser generated by the ragel state machine compiler
-  http://www.complang.org/ragel/ .
+  functions and a parser generated by the [Ragel] state machine compiler.
 
 Both variants of the JSON generator generate UTF-8 character sequences by
 default. If an :ascii\_only option with a true value is given, they escape all
@@ -71,8 +70,7 @@
 ## Compiling the extensions yourself
 
 If you want to create the `parser.c` file from its `parser.rl` file or draw 
nice
-graphviz images of the state machines, you need ragel from:
-http://www.complang.org/ragel/
+graphviz images of the state machines, you need [Ragel].
 
 ## Usage
 
@@ -423,3 +421,5 @@
 Online Documentation should be located at
 
 * https://www.rubydoc.info/gems/json
+
+[Ragel]: http://www.colm.net/open-source/ragel/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/VERSION new/VERSION
--- old/VERSION 2022-12-05 12:09:33.000000000 +0100
+++ new/VERSION 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-2.6.3
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/json_pure.gemspec new/json_pure.gemspec
--- old/json_pure.gemspec       2022-12-05 12:09:33.000000000 +0100
+++ new/json_pure.gemspec       2023-12-05 05:01:42.000000000 +0100
@@ -1,8 +1,10 @@
-# -*- encoding: utf-8 -*-
+version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line|
+  /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
+end rescue nil
 
 Gem::Specification.new do |s|
   s.name = "json_pure".freeze
-  s.version = File.read("VERSION").chomp
+  s.version = version
 
   s.summary = "JSON Implementation for Ruby".freeze
   s.description = "This is a JSON implementation in pure Ruby.".freeze
@@ -16,7 +18,6 @@
     "CHANGES.md".freeze,
     "LICENSE".freeze,
     "README.md".freeze,
-    "VERSION".freeze,
     "json_pure.gemspec".freeze,
     "lib/json.rb".freeze,
     "lib/json/add/bigdecimal.rb".freeze,
@@ -41,12 +42,12 @@
     "lib/json/pure/parser.rb".freeze,
     "lib/json/version.rb".freeze,
   ]
-  s.homepage = "http://flori.github.com/json".freeze
+  s.homepage = "https://flori.github.io/json".freeze
   s.metadata = {
     'bug_tracker_uri'   => 'https://github.com/flori/json/issues',
     'changelog_uri'     => 
'https://github.com/flori/json/blob/master/CHANGES.md',
-    'documentation_uri' => 'http://flori.github.io/json/doc/index.html',
-    'homepage_uri'      => 'http://flori.github.io/json/',
+    'documentation_uri' => 'https://flori.github.io/json/doc/index.html',
+    'homepage_uri'      => s.homepage,
     'source_code_uri'   => 'https://github.com/flori/json',
     'wiki_uri'          => 'https://github.com/flori/json/wiki'
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/bigdecimal.rb 
new/lib/json/add/bigdecimal.rb
--- old/lib/json/add/bigdecimal.rb      2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/bigdecimal.rb      2023-12-05 05:01:42.000000000 +0100
@@ -2,19 +2,36 @@
 unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
   require 'json'
 end
-defined?(::BigDecimal) or require 'bigdecimal'
+begin
+  require 'bigdecimal'
+rescue LoadError
+end
 
 class BigDecimal
-  # Import a JSON Marshalled object.
-  #
-  # method used for JSON marshalling support.
+
+  # See #as_json.
   def self.json_create(object)
     BigDecimal._load object['b']
   end
 
-  # Marshal the object to JSON.
+  # Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be 
used
+  # to serialize and deserialize a \BigDecimal object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>BigDecimal#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/bigdecimal'
+  #   x = BigDecimal(2).as_json             # => {"json_class"=>"BigDecimal", 
"b"=>"27:0.2e1"}
+  #   y = BigDecimal(2.0, 4).as_json        # => {"json_class"=>"BigDecimal", 
"b"=>"36:0.2e1"}
+  #   z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", 
"b"=>"27:0.2e1"}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal 
object:
+  #
+  #   BigDecimal.json_create(x) # => 0.2e1
+  #   BigDecimal.json_create(y) # => 0.2e1
+  #   BigDecimal.json_create(z) # => 0.2e1
   #
-  # method used for JSON marshalling support.
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -22,8 +39,20 @@
     }
   end
 
-  # return the JSON value
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/bigdecimal'
+  #   puts BigDecimal(2).to_json
+  #   puts BigDecimal(2.0, 4).to_json
+  #   puts BigDecimal(Complex(2, 0)).to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"BigDecimal","b":"27:0.2e1"}
+  #   {"json_class":"BigDecimal","b":"36:0.2e1"}
+  #   {"json_class":"BigDecimal","b":"27:0.2e1"}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
-end
+end if defined?(::BigDecimal)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/complex.rb new/lib/json/add/complex.rb
--- old/lib/json/add/complex.rb 2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/complex.rb 2023-12-05 05:01:42.000000000 +0100
@@ -5,14 +5,27 @@
 
 class Complex
 
-  # Deserializes JSON string by converting Real value <tt>r</tt>, imaginary
-  # value <tt>i</tt>, to a Complex object.
+  # See #as_json.
   def self.json_create(object)
     Complex(object['r'], object['i'])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used
+  # to serialize and deserialize a \Complex object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Complex#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/complex'
+  #   x = Complex(2).as_json      # => {"json_class"=>"Complex", "r"=>2, 
"i"=>0}
+  #   y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, 
"i"=>4}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Complex 
object:
+  #
+  #   Complex.json_create(x) # => (2+0i)
+  #   Complex.json_create(y) # => (2.0+4i)
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -21,7 +34,17 @@
     }
   end
 
-  # Stores class name (Complex) along with real value <tt>r</tt> and imaginary 
value <tt>i</tt> as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/complex'
+  #   puts Complex(2).to_json
+  #   puts Complex(2.0, 4).to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Complex","r":2,"i":0}
+  #   {"json_class":"Complex","r":2.0,"i":4}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/date.rb new/lib/json/add/date.rb
--- old/lib/json/add/date.rb    2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/date.rb    2023-12-05 05:01:42.000000000 +0100
@@ -6,16 +6,29 @@
 
 class Date
 
-  # Deserializes JSON string by converting Julian year <tt>y</tt>, month
-  # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
+  # See #as_json.
   def self.json_create(object)
     civil(*object.values_at('y', 'm', 'd', 'sg'))
   end
 
   alias start sg unless method_defined?(:start)
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Date#as_json</tt> and +Date.json_create+ may be used
+  # to serialize and deserialize a \Date object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Date#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/date'
+  #   x = Date.today.as_json
+  #   # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Date object:
+  #
+  #   Date.json_create(x)
+  #   # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)>
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -26,8 +39,15 @@
     }
   end
 
-  # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
-  # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/date'
+  #   puts Date.today.to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/date_time.rb 
new/lib/json/add/date_time.rb
--- old/lib/json/add/date_time.rb       2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/date_time.rb       2023-12-05 05:01:42.000000000 +0100
@@ -6,9 +6,7 @@
 
 class DateTime
 
-  # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
-  # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
-  # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
+  # See #as_json.
   def self.json_create(object)
     args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
     of_a, of_b = object['of'].split('/')
@@ -23,8 +21,21 @@
 
   alias start sg unless method_defined?(:start)
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>DateTime#as_json</tt> and +DateTime.json_create+ may be used
+  # to serialize and deserialize a \DateTime object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>DateTime#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/datetime'
+  #   x = DateTime.now.as_json
+  #   # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, 
"sg"=>2299161.0}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \DateTime 
object:
+  #
+  #   DateTime.json_create(x) # BUG? Raises Date::Error "invalid date"
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -39,9 +50,15 @@
     }
   end
 
-  # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
-  # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
-  # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/datetime'
+  #   puts DateTime.now.to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/exception.rb 
new/lib/json/add/exception.rb
--- old/lib/json/add/exception.rb       2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/exception.rb       2023-12-05 05:01:42.000000000 +0100
@@ -5,16 +5,27 @@
 
 class Exception
 
-  # Deserializes JSON string by constructing new Exception object with message
-  # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
+  # See #as_json.
   def self.json_create(object)
     result = new(object['m'])
     result.set_backtrace object['b']
     result
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Exception#as_json</tt> and +Exception.json_create+ may be used
+  # to serialize and deserialize a \Exception object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Exception#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/exception'
+  #   x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", 
"m"=>"Foo", "b"=>nil}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Exception 
object:
+  #
+  #   Exception.json_create(x) # => #<Exception: Foo>
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -23,8 +34,15 @@
     }
   end
 
-  # Stores class name (Exception) with message <tt>m</tt> and backtrace array
-  # <tt>b</tt> as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/exception'
+  #   puts Exception.new('Foo').to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Exception","m":"Foo","b":null}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/ostruct.rb new/lib/json/add/ostruct.rb
--- old/lib/json/add/ostruct.rb 2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/ostruct.rb 2023-12-05 05:01:42.000000000 +0100
@@ -6,14 +6,27 @@
 
 class OpenStruct
 
-  # Deserializes JSON string by constructing new Struct object with values
-  # <tt>t</tt> serialized by <tt>to_json</tt>.
+  # See #as_json.
   def self.json_create(object)
     new(object['t'] || object[:t])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>OpenStruct#as_json</tt> and +OpenStruct.json_create+ may be 
used
+  # to serialize and deserialize a \OpenStruct object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>OpenStruct#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/ostruct'
+  #   x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json
+  #   # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct 
object:
+  #
+  #   OpenStruct.json_create(x)
+  #   # => #<OpenStruct name='Rowdy', age=nil>
+  #
   def as_json(*)
     klass = self.class.name
     klass.to_s.empty? and raise JSON::JSONError, "Only named structs are 
supported!"
@@ -23,8 +36,15 @@
     }
   end
 
-  # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a
-  # JSON string.
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/ostruct'
+  #   puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/range.rb new/lib/json/add/range.rb
--- old/lib/json/add/range.rb   2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/range.rb   2023-12-05 05:01:42.000000000 +0100
@@ -5,14 +5,29 @@
 
 class Range
 
-  # Deserializes JSON string by constructing new Range object with arguments
-  # <tt>a</tt> serialized by <tt>to_json</tt>.
+  # See #as_json.
   def self.json_create(object)
     new(*object['a'])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Range#as_json</tt> and +Range.json_create+ may be used
+  # to serialize and deserialize a \Range object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Range#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/range'
+  #   x = (1..4).as_json     # => {"json_class"=>"Range", "a"=>[1, 4, false]}
+  #   y = (1...4).as_json    # => {"json_class"=>"Range", "a"=>[1, 4, true]}
+  #   z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", 
false]}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Range object:
+  #
+  #   Range.json_create(x) # => 1..4
+  #   Range.json_create(y) # => 1...4
+  #   Range.json_create(z) # => "a".."d"
+  #
   def as_json(*)
     {
       JSON.create_id  => self.class.name,
@@ -20,9 +35,19 @@
     }
   end
 
-  # Stores class name (Range) with JSON array of arguments <tt>a</tt> which
-  # include <tt>first</tt> (integer), <tt>last</tt> (integer), and
-  # <tt>exclude_end?</tt> (boolean) as JSON string.
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/range'
+  #   puts (1..4).to_json
+  #   puts (1...4).to_json
+  #   puts ('a'..'d').to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Range","a":[1,4,false]}
+  #   {"json_class":"Range","a":[1,4,true]}
+  #   {"json_class":"Range","a":["a","d",false]}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/rational.rb new/lib/json/add/rational.rb
--- old/lib/json/add/rational.rb        2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/rational.rb        2023-12-05 05:01:42.000000000 +0100
@@ -4,14 +4,28 @@
 end
 
 class Rational
-  # Deserializes JSON string by converting numerator value <tt>n</tt>,
-  # denominator value <tt>d</tt>, to a Rational object.
+
+  # See #as_json.
   def self.json_create(object)
     Rational(object['n'], object['d'])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Rational#as_json</tt> and +Rational.json_create+ may be used
+  # to serialize and deserialize a \Rational object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Rational#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/rational'
+  #   x = Rational(2, 3).as_json
+  #   # => {"json_class"=>"Rational", "n"=>2, "d"=>3}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Rational 
object:
+  #
+  #   Rational.json_create(x)
+  #   # => (2/3)
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -20,7 +34,15 @@
     }
   end
 
-  # Stores class name (Rational) along with numerator value <tt>n</tt> and 
denominator value <tt>d</tt> as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/rational'
+  #   puts Rational(2, 3).to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Rational","n":2,"d":3}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/regexp.rb new/lib/json/add/regexp.rb
--- old/lib/json/add/regexp.rb  2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/regexp.rb  2023-12-05 05:01:42.000000000 +0100
@@ -5,15 +5,26 @@
 
 class Regexp
 
-  # Deserializes JSON string by constructing new Regexp object with source
-  # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by
-  # <tt>to_json</tt>
+  # See #as_json.
   def self.json_create(object)
     new(object['s'], object['o'])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Regexp#as_json</tt> and +Regexp.json_create+ may be used
+  # to serialize and deserialize a \Regexp object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Regexp#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/regexp'
+  #   x = /foo/.as_json
+  #   # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object:
+  #
+  #   Regexp.json_create(x) # => /foo/
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -22,8 +33,15 @@
     }
   end
 
-  # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
-  # (Regexp or String) as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/regexp'
+  #   puts /foo/.to_json
+  #
+  # Output:
+  #
+  #    {"json_class":"Regexp","o":0,"s":"foo"}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/set.rb new/lib/json/add/set.rb
--- old/lib/json/add/set.rb     2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/set.rb     2023-12-05 05:01:42.000000000 +0100
@@ -4,16 +4,27 @@
 defined?(::Set) or require 'set'
 
 class Set
-  # Import a JSON Marshalled object.
-  #
-  # method used for JSON marshalling support.
+
+  # See #as_json.
   def self.json_create(object)
     new object['a']
   end
 
-  # Marshal the object to JSON.
+  # Methods <tt>Set#as_json</tt> and +Set.json_create+ may be used
+  # to serialize and deserialize a \Set object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Set#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/set'
+  #   x = Set.new(%w/foo bar baz/).as_json
+  #   # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Set object:
+  #
+  #   Set.json_create(x) # => #<Set: {"foo", "bar", "baz"}>
   #
-  # method used for JSON marshalling support.
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -21,7 +32,15 @@
     }
   end
 
-  # return the JSON value
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/set'
+  #   puts Set.new(%w/foo bar baz/).to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Set","a":["foo","bar","baz"]}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/struct.rb new/lib/json/add/struct.rb
--- old/lib/json/add/struct.rb  2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/struct.rb  2023-12-05 05:01:42.000000000 +0100
@@ -5,14 +5,28 @@
 
 class Struct
 
-  # Deserializes JSON string by constructing new Struct object with values
-  # <tt>v</tt> serialized by <tt>to_json</tt>.
+  # See #as_json.
   def self.json_create(object)
     new(*object['v'])
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Struct#as_json</tt> and +Struct.json_create+ may be used
+  # to serialize and deserialize a \Struct object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Struct#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/struct'
+  #   Customer = Struct.new('Customer', :name, :address, :zip)
+  #   x = Struct::Customer.new.as_json
+  #   # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Struct object:
+  #
+  #   Struct::Customer.json_create(x)
+  #   # => #<struct Struct::Customer name=nil, address=nil, zip=nil>
+  #
   def as_json(*)
     klass = self.class.name
     klass.to_s.empty? and raise JSON::JSONError, "Only named structs are 
supported!"
@@ -22,8 +36,16 @@
     }
   end
 
-  # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string.
-  # Only named structs are supported.
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/struct'
+  #   Customer = Struct.new('Customer', :name, :address, :zip)
+  #   puts Struct::Customer.new.to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Struct","t":{'name':'Rowdy',"age":null}}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/symbol.rb new/lib/json/add/symbol.rb
--- old/lib/json/add/symbol.rb  2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/symbol.rb  2023-12-05 05:01:42.000000000 +0100
@@ -1,11 +1,26 @@
+
 #frozen_string_literal: false
 unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
   require 'json'
 end
 
 class Symbol
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+
+  # Methods <tt>Symbol#as_json</tt> and +Symbol.json_create+ may be used
+  # to serialize and deserialize a \Symbol object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Symbol#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/symbol'
+  #   x = :foo.as_json
+  #   # => {"json_class"=>"Symbol", "s"=>"foo"}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object:
+  #
+  #   Symbol.json_create(x) # => :foo
+  #
   def as_json(*)
     {
       JSON.create_id => self.class.name,
@@ -13,12 +28,20 @@
     }
   end
 
-  # Stores class name (Symbol) with String representation of Symbol as a JSON 
string.
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/symbol'
+  #   puts :foo.to_json
+  #
+  # Output:
+  #
+  #   # {"json_class":"Symbol","s":"foo"}
+  #
   def to_json(*a)
     as_json.to_json(*a)
   end
 
-  # Deserializes JSON string by converting the <tt>string</tt> value stored in 
the object to a Symbol
+  # See #as_json.
   def self.json_create(o)
     o['s'].to_sym
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/add/time.rb new/lib/json/add/time.rb
--- old/lib/json/add/time.rb    2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/add/time.rb    2023-12-05 05:01:42.000000000 +0100
@@ -5,7 +5,7 @@
 
 class Time
 
-  # Deserializes JSON string by converting time since epoch to Time
+  # See #as_json.
   def self.json_create(object)
     if usec = object.delete('u') # used to be tv_usec -> tv_nsec
       object['n'] = usec * 1000
@@ -17,8 +17,22 @@
     end
   end
 
-  # Returns a hash, that will be turned into a JSON object and represent this
-  # object.
+  # Methods <tt>Time#as_json</tt> and +Time.json_create+ may be used
+  # to serialize and deserialize a \Time object;
+  # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
+  #
+  # \Method <tt>Time#as_json</tt> serializes +self+,
+  # returning a 2-element hash representing +self+:
+  #
+  #   require 'json/add/time'
+  #   x = Time.now.as_json
+  #   # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644}
+  #
+  # \Method +JSON.create+ deserializes such a hash, returning a \Time object:
+  #
+  #    Time.json_create(x)
+  #    # => 2023-11-25 11:00:56.472846644 -0600
+  #
   def as_json(*)
     nanoseconds = [ tv_usec * 1000 ]
     respond_to?(:tv_nsec) and nanoseconds << tv_nsec
@@ -30,8 +44,15 @@
     }
   end
 
-  # Stores class name (Time) with number of seconds since epoch and number of
-  # microseconds for Time as JSON string
+  # Returns a JSON string representing +self+:
+  #
+  #   require 'json/add/time'
+  #   puts Time.now.to_json
+  #
+  # Output:
+  #
+  #   {"json_class":"Time","s":1700931678,"n":980650786}
+  #
   def to_json(*args)
     as_json.to_json(*args)
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/common.rb new/lib/json/common.rb
--- old/lib/json/common.rb      2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/common.rb      2023-12-05 05:01:42.000000000 +0100
@@ -3,6 +3,9 @@
 require 'json/generic_object'
 
 module JSON
+  NOT_SET = Object.new.freeze
+  private_constant :NOT_SET
+
   class << self
     # :call-seq:
     #   JSON[object] -> new_array or new_string
@@ -295,19 +298,9 @@
   #
   def generate(obj, opts = nil)
     if State === opts
-      state, opts = opts, nil
+      state = opts
     else
-      state = State.new
-    end
-    if opts
-      if opts.respond_to? :to_hash
-        opts = opts.to_hash
-      elsif opts.respond_to? :to_h
-        opts = opts.to_h
-      else
-        raise TypeError, "can't convert #{opts.class} into Hash"
-      end
-      state = state.configure(opts)
+      state = State.new(opts)
     end
     state.generate(obj)
   end
@@ -334,19 +327,9 @@
   #   JSON.fast_generate(a)
   def fast_generate(obj, opts = nil)
     if State === opts
-      state, opts = opts, nil
+      state = opts
     else
-      state = JSON.create_fast_state
-    end
-    if opts
-      if opts.respond_to? :to_hash
-        opts = opts.to_hash
-      elsif opts.respond_to? :to_h
-        opts = opts.to_h
-      else
-        raise TypeError, "can't convert #{opts.class} into Hash"
-      end
-      state.configure(opts)
+      state = JSON.create_fast_state.configure(opts)
     end
     state.generate(obj)
   end
@@ -592,13 +575,13 @@
     # Sets or returns the default options for the JSON.dump method.
     # Initially:
     #   opts = JSON.dump_default_options
-    #   opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false}
+    #   opts # => {:max_nesting=>false, :allow_nan=>true, :script_safe=>false}
     attr_accessor :dump_default_options
   end
   self.dump_default_options = {
     :max_nesting => false,
     :allow_nan   => true,
-    :escape_slash => false,
+    :script_safe => false,
   }
 
   # :call-seq:
@@ -628,16 +611,18 @@
   #   puts File.read(path)
   # Output:
   #   {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}
-  def dump(obj, anIO = nil, limit = nil)
-    if anIO and limit.nil?
-      anIO = anIO.to_io if anIO.respond_to?(:to_io)
-      unless anIO.respond_to?(:write)
-        limit = anIO
-        anIO = nil
-      end
+  def dump(obj, anIO = nil, limit = nil, kwargs = nil)
+    io_limit_opt = [anIO, limit, kwargs].compact
+    kwargs = io_limit_opt.pop if io_limit_opt.last.is_a?(Hash)
+    anIO, limit = io_limit_opt
+    if anIO.respond_to?(:to_io)
+      anIO = anIO.to_io
+    elsif limit.nil? && !anIO.respond_to?(:write)
+      anIO, limit = nil, anIO
     end
     opts = JSON.dump_default_options
     opts = opts.merge(:max_nesting => limit) if limit
+    opts = merge_dump_options(opts, **kwargs) if kwargs
     result = generate(obj, opts)
     if anIO
       anIO.write result
@@ -653,6 +638,15 @@
   def self.iconv(to, from, string)
     string.encode(to, from)
   end
+
+  def merge_dump_options(opts, strict: NOT_SET)
+    opts = opts.merge(strict: strict) if NOT_SET != strict
+    opts
+  end
+
+  class << self
+    private :merge_dump_options
+  end
 end
 
 module ::Kernel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/pure/generator.rb 
new/lib/json/pure/generator.rb
--- old/lib/json/pure/generator.rb      2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/pure/generator.rb      2023-12-05 05:01:42.000000000 +0100
@@ -37,25 +37,34 @@
     '\\'  =>  '\\\\',
   } # :nodoc:
 
-  ESCAPE_SLASH_MAP = MAP.merge(
+  ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
+
+  SCRIPT_SAFE_MAP = MAP.merge(
     '/'  =>  '\\/',
+    "\u2028".b => '\u2028',
+    "\u2029".b => '\u2029',
   )
 
+  SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, 
"\u2029".b)
+
   # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
   # UTF16 big endian characters as \u????, and return it.
-  def utf8_to_json(string, escape_slash = false) # :nodoc:
+  def utf8_to_json(string, script_safe = false) # :nodoc:
     string = string.dup
     string.force_encoding(::Encoding::ASCII_8BIT)
-    map = escape_slash ? ESCAPE_SLASH_MAP : MAP
-    string.gsub!(/[\/"\\\x0-\x1f]/) { map[$&] || $& }
+    if script_safe
+      string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
+    else
+      string.gsub!(ESCAPE_PATTERN) { MAP[$&] || $& }
+    end
     string.force_encoding(::Encoding::UTF_8)
     string
   end
 
-  def utf8_to_json_ascii(string, escape_slash = false) # :nodoc:
+  def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
     string = string.dup
     string.force_encoding(::Encoding::ASCII_8BIT)
-    map = escape_slash ? ESCAPE_SLASH_MAP : MAP
+    map = script_safe ? SCRIPT_SAFE_MAP : MAP
     string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
     string.gsub!(/(
       (?:
@@ -115,7 +124,8 @@
         # * *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: ''),
-        # * *escape_slash*: true if forward slash (/) should be escaped 
(default: false)
+        # * *script_safe*: true if U+2028, U+2029 and forward slash (/) should 
be escaped
+        #   as to make the JSON object safe to interpolate in a script tag 
(default: false).
         # * *check_circular*: is deprecated now, use the :max_nesting option 
instead,
         # * *max_nesting*: sets the maximum level of data structure nesting in
         #   the generated JSON, max_nesting = 0 if no maximum should be 
checked.
@@ -130,7 +140,8 @@
           @array_nl              = ''
           @allow_nan             = false
           @ascii_only            = false
-          @escape_slash          = false
+          @script_safe          = false
+          @strict                = false
           @buffer_initial_length = 1024
           configure opts
         end
@@ -158,7 +169,11 @@
 
         # If this attribute is set to true, forward slashes will be escaped in
         # all json strings.
-        attr_accessor :escape_slash
+        attr_accessor :script_safe
+
+        # If this attribute is set to true, attempting to serialize types not
+        # supported by the JSON spec will raise a JSON::GeneratorError
+        attr_accessor :strict
 
         # :stopdoc:
         attr_reader :buffer_initial_length
@@ -200,8 +215,13 @@
         end
 
         # Returns true, if forward slashes are escaped. Otherwise returns 
false.
-        def escape_slash?
-          @escape_slash
+        def script_safe?
+          @script_safe
+        end
+
+        # Returns true, if forward slashes are escaped. Otherwise returns 
false.
+        def strict?
+          @strict
         end
 
         # Configure this State instance with the Hash _opts_, and return
@@ -214,7 +234,7 @@
           else
             raise TypeError, "can't convert #{opts.class} into Hash"
           end
-          for key, value in opts
+          opts.each do |key, value|
             instance_variable_set "@#{key}", value
           end
           @indent                = opts[:indent] if opts.key?(:indent)
@@ -226,7 +246,16 @@
           @ascii_only            = opts[:ascii_only] if opts.key?(:ascii_only)
           @depth                 = opts[:depth] || 0
           @buffer_initial_length ||= opts[:buffer_initial_length]
-          @escape_slash          = !!opts[:escape_slash] if 
opts.key?(:escape_slash)
+
+          @script_safe = if opts.key?(:script_safe)
+            !!opts[:script_safe]
+          elsif opts.key?(:escape_slash)
+            !!opts[:escape_slash]
+          else
+            false
+          end
+
+          @strict                = !!opts[:strict] if opts.key?(:strict)
 
           if !opts.key?(:max_nesting) # defaults to 100
             @max_nesting = 100
@@ -243,7 +272,7 @@
         # passed to the configure method.
         def to_h
           result = {}
-          for iv in instance_variables
+          instance_variables.each do |iv|
             iv = iv.to_s[1..-1]
             result[iv.to_sym] = self[iv]
           end
@@ -287,7 +316,13 @@
           # Converts this object to a string (calling #to_s), converts
           # it to a JSON string, and returns the result. This is a fallback, 
if no
           # special method #to_json was defined for some object.
-          def to_json(*) to_s.to_json end
+          def to_json(generator_state)
+            if generator_state.strict?
+              raise GeneratorError, "#{self.class} not allowed in JSON"
+            else
+              to_s.to_json
+            end
+          end
         end
 
         module Hash
@@ -310,21 +345,18 @@
           end
 
           def json_transform(state)
-            delim = ','
-            delim << state.object_nl
-            result = '{'
-            result << state.object_nl
+            delim = ",#{state.object_nl}"
+            result = "{#{state.object_nl}"
             depth = state.depth += 1
             first = true
             indent = !state.object_nl.empty?
-            each { |key,value|
+            each { |key, value|
               result << delim unless first
               result << state.indent * depth if indent
-              result << key.to_s.to_json(state)
-              result << state.space_before
-              result << ':'
-              result << state.space
-              if value.respond_to?(:to_json)
+              result = 
"#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
+              if state.strict?
+                raise GeneratorError, "#{value.class} not allowed in JSON"
+              elsif value.respond_to?(:to_json)
                 result << value.to_json(state)
               else
                 result << %{"#{String(value)}"}
@@ -365,7 +397,9 @@
             each { |value|
               result << delim unless first
               result << state.indent * depth if indent
-              if value.respond_to?(:to_json)
+              if state.strict?
+                raise GeneratorError, "#{value.class} not allowed in JSON"
+              elsif value.respond_to?(:to_json)
                 result << value.to_json(state)
               else
                 result << %{"#{String(value)}"}
@@ -419,9 +453,9 @@
               string = encode(::Encoding::UTF_8)
             end
             if state.ascii_only?
-              '"' << JSON.utf8_to_json_ascii(string, state.escape_slash) << '"'
+              '"' << JSON.utf8_to_json_ascii(string, state.script_safe) << '"'
             else
-              '"' << JSON.utf8_to_json(string, state.escape_slash) << '"'
+              '"' << JSON.utf8_to_json(string, state.script_safe) << '"'
             end
           end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json/version.rb new/lib/json/version.rb
--- old/lib/json/version.rb     2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json/version.rb     2023-12-05 05:01:42.000000000 +0100
@@ -1,7 +1,7 @@
 # frozen_string_literal: false
 module JSON
   # JSON version
-  VERSION         = '2.6.3'
+  VERSION         = '2.7.1'
   VERSION_ARRAY   = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
   VERSION_MAJOR   = VERSION_ARRAY[0] # :nodoc:
   VERSION_MINOR   = VERSION_ARRAY[1] # :nodoc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/json.rb new/lib/json.rb
--- old/lib/json.rb     2022-12-05 12:09:33.000000000 +0100
+++ new/lib/json.rb     2023-12-05 05:01:42.000000000 +0100
@@ -285,6 +285,15 @@
 #   # Raises JSON::NestingError (nesting of 2 is too deep):
 #   JSON.generate(obj, max_nesting: 2)
 #
+# ====== Escaping Options
+#
+# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, 
<tt>'\u2029'</tt>
+# and <tt>'/'</tt> should be escaped as to make the JSON object safe to 
interpolate in script
+# tags.
+#
+# Options +ascii_only+ (boolean) specifies wether all characters outside the 
ASCII range
+# should be escaped.
+#
 # ====== Output Options
 #
 # The default formatting options generate the most compact
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2022-12-05 12:09:33.000000000 +0100
+++ new/metadata        2023-12-05 05:01:42.000000000 +0100
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: json_pure
 version: !ruby/object:Gem::Version
-  version: 2.6.3
+  version: 2.7.1
 platform: ruby
 authors:
 - Florian Frank
 autorequire:
 bindir: bin
 cert_chain: []
-date: 2022-12-05 00:00:00.000000000 Z
+date: 2023-12-05 00:00:00.000000000 Z
 dependencies: []
 description: This is a JSON implementation in pure Ruby.
 email: fl...@ping.de
@@ -20,7 +20,6 @@
 - CHANGES.md
 - LICENSE
 - README.md
-- VERSION
 - json_pure.gemspec
 - lib/json.rb
 - lib/json/add/bigdecimal.rb
@@ -44,14 +43,14 @@
 - lib/json/pure/generator.rb
 - lib/json/pure/parser.rb
 - lib/json/version.rb
-homepage: http://flori.github.com/json
+homepage: https://flori.github.io/json
 licenses:
 - Ruby
 metadata:
   bug_tracker_uri: https://github.com/flori/json/issues
   changelog_uri: https://github.com/flori/json/blob/master/CHANGES.md
-  documentation_uri: http://flori.github.io/json/doc/index.html
-  homepage_uri: http://flori.github.io/json/
+  documentation_uri: https://flori.github.io/json/doc/index.html
+  homepage_uri: https://flori.github.io/json
   source_code_uri: https://github.com/flori/json
   wiki_uri: https://github.com/flori/json/wiki
 post_install_message:
@@ -73,7 +72,7 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.4.0.dev
+rubygems_version: 3.5.0.dev
 signing_key:
 specification_version: 4
 summary: JSON Implementation for Ruby

Reply via email to