Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-msgpack for openSUSE:Factory 
checked in at 2021-02-20 22:12:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-msgpack (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-msgpack.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-msgpack"

Sat Feb 20 22:12:07 2021 rev:13 rq:869949 version:1.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-msgpack/rubygem-msgpack.changes  
2020-03-07 21:39:10.092309812 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-msgpack.new.28504/rubygem-msgpack.changes   
    2021-02-20 22:12:13.535034951 +0100
@@ -1,0 +2,8 @@
+Sat Feb  6 11:31:06 UTC 2021 - Manuel Schnitzer <mschnit...@suse.com>
+
+- updated to version 1.4.2
+
+  * Add the required Ruby version (>= 2.4) to avoid compilation errors on 
older Ruby runtimes
+  * Drop the support of old Ruby versions explicitly (1.8, 1.9, 2.0, 2.1, 2.2, 
2.3)
+
+-------------------------------------------------------------------

Old:
----
  msgpack-1.3.3.gem

New:
----
  msgpack-1.4.2.gem

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

Other differences:
------------------
++++++ rubygem-msgpack.spec ++++++
--- /var/tmp/diff_new_pack.ZNlbYv/_old  2021-02-20 22:12:14.067035516 +0100
+++ /var/tmp/diff_new_pack.ZNlbYv/_new  2021-02-20 22:12:14.067035516 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-msgpack
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,12 +24,12 @@
 #
 
 Name:           rubygem-msgpack
-Version:        1.3.3
+Version:        1.4.2
 Release:        0
 %define mod_name msgpack
 %define mod_full_name %{mod_name}-%{version}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  %{rubydevel}
+BuildRequires:  %{rubydevel >= 2.4}
 BuildRequires:  %{rubygem gem2rpm}
 BuildRequires:  ruby-macros >= 5
 URL:            http://msgpack.org/
@@ -52,7 +52,7 @@
 
 %install
 %gem_install \
-  --doc-files="ChangeLog LICENSE README.rdoc" \
+  --doc-files="ChangeLog LICENSE README.md" \
   -f
 %gem_cleanup
 

++++++ msgpack-1.3.3.gem -> msgpack-1.4.2.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.rubocop.yml new/.rubocop.yml
--- old/.rubocop.yml    2020-02-05 03:07:56.000000000 +0100
+++ new/.rubocop.yml    2021-02-01 04:16:37.000000000 +0100
@@ -6,7 +6,7 @@
 # versions of RuboCop, may require this file to be generated again.
 
 AllCops:
-  TargetRubyVersion: 2.3
+  TargetRubyVersion: 2.4
 
 # Offense count: 3
 Lint/AmbiguousOperator:
@@ -18,7 +18,7 @@
   Enabled: false
 
 # Offense count: 1
-Lint/Eval:
+Security/Eval:
   Enabled: false
 
 # Offense count: 3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.travis.yml new/.travis.yml
--- old/.travis.yml     2020-02-05 03:07:56.000000000 +0100
+++ new/.travis.yml     2021-02-01 04:16:37.000000000 +0100
@@ -1,7 +1,5 @@
 language: ruby
 
-sudo: false
-
 branches:
   only:
     - master
@@ -17,19 +15,17 @@
 # http://rubies.travis-ci.org/
 matrix:
   include:
-    - rvm: 2.3.8
-      os: linux
     - rvm: 2.4.5
       os: linux
-    - rvm: 2.5.3
+    - rvm: 2.5.8
       os: linux
-    - rvm: 2.6.1
+    - rvm: 2.6.6
       os: linux
-    - rvm: 2.6.1
+    - rvm: 2.6.6
       os: osx
-    - rvm: ruby-head
+    - rvm: 2.7.1
       os: linux
-    - rvm: jruby-9.1.9.0
+    - rvm: ruby-head
       os: linux
     - rvm: jruby-head
       os: linux
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ChangeLog new/ChangeLog
--- old/ChangeLog       2020-02-05 03:07:56.000000000 +0100
+++ new/ChangeLog       2021-02-01 04:16:37.000000000 +0100
@@ -1,3 +1,17 @@
+2021-02-01 version 1.4.2:
+
+* Add the required Ruby version (>= 2.4) to avoid compilation errors on older 
Ruby runtimes
+* Drop the support of old Ruby versions explicitly (1.8, 1.9, 2.0, 2.1, 2.2, 
2.3)
+
+2021-01-27 version 1.4.1:
+
+* Bugfix about the wrong string encoding longer than 256 bytes (#200)
+
+2021-01-27 version 1.4.0:
+
+* Introduce the optimization to use frozen/deduped keys for map objects
+* Stop releasing fat gem (pre-built binaries) for mswin32 arch environments
+
 2020-02-05 version 1.3.3:
 
 * Hotfix release for Windows environments: 1.3.2 missed including binaries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2020-02-05 03:07:56.000000000 +0100
+++ new/Gemfile 2021-02-01 04:16:37.000000000 +0100
@@ -5,5 +5,5 @@
 ## enable this line to run benchmarks
 # gem "viiite"
 
-gem "rubocop"
+gem "rubocop", "~> 0.82.0"
 gem "simplecov"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       1970-01-01 01:00:00.000000000 +0100
+++ new/README.md       2021-02-01 04:16:37.000000000 +0100
@@ -0,0 +1,242 @@
+# MessagePack
+
+[MessagePack](http://msgpack.org) is an efficient binary serialization format.
+It lets you exchange data among multiple languages like JSON but it's faster 
and smaller.
+For example, small integers (like flags or error code) are encoded into a 
single byte,
+and typical short strings only require an extra byte in addition to the 
strings themselves.
+
+If you ever wished to use JSON for convenience (storing an image with 
metadata) but could
+not for technical reasons (binary data, size, speed...), MessagePack is a 
perfect replacement.
+
+    require 'msgpack'
+    msg = [1,2,3].to_msgpack  #=> "\x93\x01\x02\x03"
+    MessagePack.unpack(msg)   #=> [1,2,3]
+
+Use RubyGems to install:
+
+    gem install msgpack
+
+or build msgpack-ruby and install:
+
+    bundle
+    rake
+    gem install --local pkg/msgpack
+
+
+## Use cases
+
+* Create REST API returing MessagePack using Rails + 
[RABL](https://github.com/nesquena/rabl)
+* Store objects efficiently serialized by msgpack on memcached or Redis
+  * In fact Redis supports msgpack in 
[EVAL-scripts](http://redis.io/commands/eval)
+* Upload data in efficient format from mobile devices such as smartphones
+  * MessagePack works on iPhone/iPad and Android. See also 
[Objective-C](https://github.com/msgpack/msgpack-objectivec) and 
[Java](https://github.com/msgpack/msgpack-java) implementations
+* Design a portable protocol to communicate with embedded devices
+  * Check also [Fluentd](http://fluentd.org/) which is a log collector which 
uses msgpack for the log format (they say it uses JSON but actually it's 
msgpack, which is compatible with JSON)
+* Exchange objects between software components written in different languages
+  * You'll need a flexible but efficient format so that components exchange 
objects while keeping compatibility
+
+## Portability
+
+MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU 
architectures.
+
+And it works with MRI (CRuby) and Rubinius.
+Patches to improve portability is highly welcomed.
+
+
+## Serializing objects
+
+Use `MessagePack.pack` or `to_msgpack`:
+
+```ruby
+require 'msgpack'
+msg = MessagePack.pack(obj)  # or
+msg = obj.to_msgpack
+```
+
+### Streaming serialization
+
+Packer provides advanced API to serialize objects in streaming style:
+
+```ruby
+# serialize a 2-element array [e1, e2]
+pk = MessagePack::Packer.new(io)
+pk.write_array_header(2).write(e1).write(e2).flush
+```
+
+See [API reference](http://ruby.msgpack.org/MessagePack/Packer.html) for 
details.
+
+## Deserializing objects
+
+Use `MessagePack.unpack`:
+
+```ruby
+require 'msgpack'
+obj = MessagePack.unpack(msg)
+```
+
+### Streaming deserialization
+
+Unpacker provides advanced API to deserialize objects in streaming style:
+
+```ruby
+# deserialize objects from an IO
+u = MessagePack::Unpacker.new(io)
+u.each do |obj|
+  # ...
+end
+```
+
+or event-driven style which works well with EventMachine:
+
+```ruby
+# event-driven deserialization
+def on_read(data)
+  @u ||= MessagePack::Unpacker.new
+  @u.feed_each(data) {|obj|
+     # ...
+  }
+end
+```
+
+See [API reference](http://ruby.msgpack.org/MessagePack/Unpacker.html) for 
details.
+
+## Serializing and deserializing symbols
+
+By default, symbols are serialized as strings:
+
+```ruby
+packed = :symbol.to_msgpack     # => "\xA6symbol"
+MessagePack.unpack(packed)      # => "symbol"
+```
+
+This can be customized by registering an extension type for them:
+
+```ruby
+MessagePack::DefaultFactory.register_type(0x00, Symbol)
+
+# symbols now survive round trips
+packed = :symbol.to_msgpack     # => "\xc7\x06\x00symbol"
+MessagePack.unpack(packed)      # => :symbol
+```
+
+The extension type for symbols is configurable like any other extension type.
+For example, to customize how symbols are packed you can just redefine
+Symbol#to_msgpack_ext. Doing this gives you an option to prevent symbols from
+being serialized altogether by throwing an exception:
+
+```ruby
+class Symbol
+    def to_msgpack_ext
+        raise "Serialization of symbols prohibited"
+    end
+end
+
+MessagePack::DefaultFactory.register_type(0x00, Symbol)
+
+[1, :symbol, 'string'].to_msgpack  # => RuntimeError: Serialization of symbols 
prohibited
+```
+
+## Serializing and deserializing Time instances
+
+There are the timestamp extension type in MessagePack,
+but it is not registered by default.
+
+To map Ruby's Time to MessagePack's timestamp for the default factory:
+
+```ruby
+MessagePack::DefaultFactory.register_type(
+  MessagePack::Timestamp::TYPE, # or just -1
+  Time,
+  packer: MessagePack::Time::Packer,
+  unpacker: MessagePack::Time::Unpacker
+)
+```
+
+See [API reference](http://ruby.msgpack.org/) for details.
+
+## Extension Types
+
+Packer and Unpacker support [Extension types of 
MessagePack](https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type).
+
+```ruby
+# register how to serialize custom class at first
+pk = MessagePack::Packer.new(io)
+pk.register_type(0x01, MyClass1, :to_msgpack_ext) # equal to 
pk.register_type(0x01, MyClass)
+pk.register_type(0x02, MyClass2){|obj| obj.how_to_serialize() } # blocks also 
available
+
+# almost same API for unpacker
+uk = MessagePack::Unpacker.new()
+uk.register_type(0x01, MyClass1, :from_msgpack_ext)
+uk.register_type(0x02){|data| MyClass2.create_from_serialized_data(data) }
+```
+
+`MessagePack::Factory` is to create packer and unpacker which have same 
extension types.
+
+```ruby
+factory = MessagePack::Factory.new
+factory.register_type(0x01, MyClass1) # same with next line
+factory.register_type(0x01, MyClass1, packer: :to_msgpack_ext, unpacker: 
:from_msgpack_ext)
+pk = factory.packer(options_for_packer)
+uk = factory.unpacker(options_for_unpacker)
+```
+
+For `MessagePack.pack` and `MessagePack.unpack`, default packer/unpacker refer 
`MessagePack::DefaultFactory`. Call `MessagePack::DefaultFactory.register_type` 
to enable types process globally.
+
+```ruby
+MessagePack::DefaultFactory.register_type(0x03, MyClass3)
+MessagePack.unpack(data_with_ext_typeid_03) #=> MyClass3 instance
+```
+
+## Buffer API
+
+MessagePack for Ruby provides a buffer API so that you can read or write data 
by hand, not via Packer or Unpacker API.
+
+This [MessagePack::Buffer](http://ruby.msgpack.org/MessagePack/Buffer.html) is 
backed with a fixed-length shared memory pool which is very fast for small data 
(<= 4KB),
+and has zero-copy capability which significantly affects performance to handle 
large binary data.
+
+## How to build and run tests
+
+Before building msgpack, you need to install bundler and dependencies.
+
+    gem install bundler
+    bundle install
+
+Then, you can run the tasks as follows:
+
+### Build
+
+    bundle exec rake build
+
+### Run tests
+
+    bundle exec rake spec
+
+### Generating docs
+
+    bundle exec rake doc
+
+## How to build -java rubygems
+
+To build -java gems for JRuby, run:
+
+    rake build:java
+
+If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
+
+## Updating documents
+
+Online documents (http://ruby.msgpack.org) is generated from gh-pages branch.
+Following commands update documents in gh-pages branch:
+
+    bundle exec rake doc
+    git checkout gh-pages
+    cp doc/* ./ -a
+
+## Copyright
+
+* Author
+  * Sadayuki Furuhashi <frsy...@gmail.com>
+* Copyright
+  * Copyright (c) 2008-2015 Sadayuki Furuhashi
+* License
+  * Apache License, Version 2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.rdoc new/README.rdoc
--- old/README.rdoc     2020-02-05 03:07:56.000000000 +0100
+++ new/README.rdoc     1970-01-01 01:00:00.000000000 +0100
@@ -1,225 +0,0 @@
-
-= MessagePack
-
-MessagePack[http://msgpack.org] is an efficient binary serialization format.
-It lets you exchange data among multiple languages like JSON but it's faster 
and smaller.
-For example, small integers (like flags or error code) are encoded into a 
single byte,
-and typical short strings only require an extra byte in addition to the 
strings themselves.
-
-If you ever wished to use JSON for convenience (storing an image with 
metadata) but could
-not for technical reasons (binary data, size, speed...), MessagePack is a 
perfect replacement.
-
-    require 'msgpack'
-    msg = [1,2,3].to_msgpack  #=> "\x93\x01\x02\x03"
-    MessagePack.unpack(msg)   #=> [1,2,3]
-
-Use RubyGems to install:
-
-    gem install msgpack
-
-or build msgpack-ruby and install:
-
-    bundle
-    rake
-    gem install --local pkg/msgpack
-
-
-= Use cases
-
-* Create REST API returing MessagePack using Rails + 
[RABL](https://github.com/nesquena/rabl)
-* Store objects efficiently serialized by msgpack on memcached or Redis
-  * In fact Redis supports msgpack in 
EVAL-scripts[http://redis.io/commands/eval]
-* Upload data in efficient format from mobile devices such as smartphones
-  * MessagePack works on iPhone/iPad and Android. See also 
Objective-C[https://github.com/msgpack/msgpack-objectivec] and 
Java[https://github.com/msgpack/msgpack-java] implementations
-* Design a portable protocol to communicate with embedded devices
-  * Check also Fluentd[http://fluentd.org/] which is a log collector which 
uses msgpack for the log format (they say it uses JSON but actually it's 
msgpack, which is compatible with JSON)
-* Exchange objects between software components written in different languages
-  * You'll need a flexible but efficient format so that components exchange 
objects while keeping compatibility
-
-= Portability
-
-MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU 
architectures.
-
-And it works with MRI (CRuby) and Rubinius.
-Patches to improve portability is highly welcomed.
-
-
-= Serializing objects
-
-Use *MessagePack.pack* or *to_msgpack*:
-
-    require 'msgpack'
-    msg = MessagePack.pack(obj)  # or
-    msg = obj.to_msgpack
-
-== Streaming serialization
-
-Packer provides advanced API to serialize objects in streaming style:
-
-    # serialize a 2-element array [e1, e2]
-    pk = MessagePack::Packer.new(io)
-    pk.write_array_header(2).write(e1).write(e2).flush
-
-See {API reference}[http://ruby.msgpack.org/MessagePack/Packer.html] for 
details.
-
-= Deserializing objects
-
-Use *MessagePack.unpack*:
-
-    require 'msgpack'
-    obj = MessagePack.unpack(msg)
-
-== Streaming deserialization
-
-Unpacker provides advanced API to deserialize objects in streaming style:
-
-    # deserialize objects from an IO
-    u = MessagePack::Unpacker.new(io)
-    u.each do |obj|
-      # ...
-    end
-
-or event-driven style which works well with EventMachine:
-
-    # event-driven deserialization
-    def on_read(data)
-      @u ||= MessagePack::Unpacker.new
-      @u.feed_each(data) {|obj|
-         # ...
-      }
-    end
-
-See {API reference}[http://ruby.msgpack.org/MessagePack/Unpacker.html] for 
details.
-
-= Serializing and deserializing symbols
-
-By default, symbols are serialized as strings:
-
-    packed = :symbol.to_msgpack     # => "\xA6symbol"
-    MessagePack.unpack(packed)      # => "symbol"
-
-This can be customized by registering an extension type for them:
-
-    MessagePack::DefaultFactory.register_type(0x00, Symbol)
-
-    # symbols now survive round trips
-    packed = :symbol.to_msgpack     # => "\xc7\x06\x00symbol"
-    MessagePack.unpack(packed)      # => :symbol
-
-The extension type for symbols is configurable like any other extension type.
-For example, to customize how symbols are packed you can just redefine
-Symbol#to_msgpack_ext. Doing this gives you an option to prevent symbols from
-being serialized altogether by throwing an exception:
-
-    class Symbol
-        def to_msgpack_ext
-            raise "Serialization of symbols prohibited"
-        end
-    end
-
-    MessagePack::DefaultFactory.register_type(0x00, Symbol)
-
-    [1, :symbol, 'string'].to_msgpack  # => RuntimeError: Serialization of 
symbols prohibited
-
-= Serializing and deserializing Time instances
-
-There are the timestamp extension type in MessagePack,
-but it is not registered by default.
-
-To map Ruby's Time to MessagePack's timestamp for the default factory:
-
-    MessagePack::DefaultFactory.register_type(
-      MessagePack::Timestamp::TYPE, # or just -1
-      Time,
-      packer: MessagePack::Time::Packer,
-      unpacker: MessagePack::Time::Unpacker
-    )
-
-See {API reference}[http://ruby.msgpack.org/] for details.
-
-= Extension Types
-
-Packer and Unpacker support {Extension types of 
MessagePack}[https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type].
-
-    # register how to serialize custom class at first
-    pk = MessagePack::Packer.new(io)
-    pk.register_type(0x01, MyClass1, :to_msgpack_ext) # equal to 
pk.register_type(0x01, MyClass)
-    pk.register_type(0x02, MyClass2){|obj| obj.how_to_serialize() } # blocks 
also available
-    
-    # almost same API for unpacker
-    uk = MessagePack::Unpacker.new()
-    uk.register_type(0x01, MyClass1, :from_msgpack_ext)
-    uk.register_type(0x02){|data| MyClass2.create_from_serialized_data(data) }
-
-MessagePack::Factory is to create packer and unpacker which have same 
extension types.
-
-    factory = MessagePack::Factory.new
-    factory.register_type(0x01, MyClass1) # same with next line
-    factory.register_type(0x01, MyClass1, packer: :to_msgpack_ext, unpacker: 
:from_msgpack_ext)
-    pk = factory.packer(options_for_packer)
-    uk = factory.unpacker(options_for_unpacker)
-
-For *MessagePack.pack* and *MessagePack.unpack*, default packer/unpacker refer 
*MessagePack::DefaultFactory*. Call *MessagePack::DefaultFactory.register_type* 
to enable types process globally.
-
-    MessagePack::DefaultFactory.register_type(0x03, MyClass3)
-    MessagePack.unpack(data_with_ext_typeid_03) #=> MyClass3 instance
-
-= Buffer API
-
-MessagePack for Ruby provides a buffer API so that you can read or write data 
by hand, not via Packer or Unpacker API.
-
-This {MessagePack::Buffer}[http://ruby.msgpack.org/MessagePack/Buffer.html] is 
backed with a fixed-length shared memory pool which is very fast for small data 
(<= 4KB),
-and has zero-copy capability which significantly affects performance to handle 
large binary data.
-
-= How to build and run tests
-
-Before building msgpack, you need to install bundler and dependencies.
-
-    gem install bundler
-    bundle install
-
-Then, you can run the tasks as follows:
-
-* Build
-
-    bundle exec rake build
-
-* Run tests
-
-    bundle exec rake spec
-
-* Generating docs
-
-    bundle exec rake doc
-
-== How to build -java rubygems
-
-To build -java gems for JRuby, run:
-
-    rake build:java
-
-If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
-
-== How to build -mingw32 rubygems
-
-MessagePack mingw32/64 rubygems build process uses 
{rake-compiler-dock}[https://github.com/rake-compiler/rake-compiler-dock]. Run:
-
-    rake build:windows
-
-Once this step successes, target gems exist in 
pkg/msgpack-*-{x86,x64}-mingw32.gem.
-
-== Updating documents
-
-Online documents (http://ruby.msgpack.org) is generated from gh-pages branch.
-Following commands update documents in gh-pages branch:
-
-    bundle exec rake doc
-    git checkout gh-pages
-    cp doc/* ./ -a
-
-= Copyright
-
-Author::    Sadayuki Furuhashi <frsy...@gmail.com>
-Copyright:: Copyright (c) 2008-2015 Sadayuki Furuhashi
-License::   Apache License, Version 2.0
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile        2020-02-05 03:07:56.000000000 +0100
+++ new/Rakefile        2021-02-01 04:16:37.000000000 +0100
@@ -64,13 +64,6 @@
 namespace :build do
   desc 'Build gem for JRuby after cleaning'
   task :java => [:clean, :spec, :build]
-
-  desc 'Build gems for Windows per rake-compiler-dock'
-  task :windows do
-    require 'rake_compiler_dock'
-    # See RUBY_CC_VERSION in 
https://github.com/rake-compiler/rake-compiler-dock/blob/master/Dockerfile
-    RakeCompilerDock.sh 'bundle && gem i json && rake cross native gem 
RUBY_CC_VERSION=2.2.2:2.3.0:2.4.0:2.5.0:2.6.0:2.7.0'
-  end
 end
 
 CLEAN.include('lib/msgpack/msgpack.*')
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/java/org/msgpack/jruby/Decoder.java 
new/ext/java/org/msgpack/jruby/Decoder.java
--- old/ext/java/org/msgpack/jruby/Decoder.java 2020-02-05 03:07:56.000000000 
+0100
+++ new/ext/java/org/msgpack/jruby/Decoder.java 2021-02-01 04:16:37.000000000 
+0100
@@ -38,36 +38,38 @@
   private ExtensionRegistry registry;
   private ByteBuffer buffer;
   private boolean symbolizeKeys;
+  private boolean freeze;
   private boolean allowUnknownExt;
 
   public Decoder(Ruby runtime) {
-    this(runtime, null, new byte[] {}, 0, 0, false, false);
+    this(runtime, null, new byte[] {}, 0, 0, false, false, false);
   }
 
   public Decoder(Ruby runtime, ExtensionRegistry registry) {
-    this(runtime, registry, new byte[] {}, 0, 0, false, false);
+    this(runtime, registry, new byte[] {}, 0, 0, false, false, false);
   }
 
   public Decoder(Ruby runtime, byte[] bytes) {
-    this(runtime, null, bytes, 0, bytes.length, false, false);
+    this(runtime, null, bytes, 0, bytes.length, false, false, false);
   }
 
   public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes) {
-    this(runtime, registry, bytes, 0, bytes.length, false, false);
+    this(runtime, registry, bytes, 0, bytes.length, false, false, false);
   }
 
-  public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, 
boolean symbolizeKeys, boolean allowUnknownExt) {
-    this(runtime, registry, bytes, 0, bytes.length, symbolizeKeys, 
allowUnknownExt);
+  public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, 
boolean symbolizeKeys, boolean freeze, boolean allowUnknownExt) {
+    this(runtime, registry, bytes, 0, bytes.length, symbolizeKeys, freeze, 
allowUnknownExt);
   }
 
   public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, int 
offset, int length) {
-    this(runtime, registry, bytes, offset, length, false, false);
+    this(runtime, registry, bytes, offset, length, false, false, false);
   }
 
-  public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, int 
offset, int length, boolean symbolizeKeys, boolean allowUnknownExt) {
+  public Decoder(Ruby runtime, ExtensionRegistry registry, byte[] bytes, int 
offset, int length, boolean symbolizeKeys, boolean freeze, boolean 
allowUnknownExt) {
     this.runtime = runtime;
     this.registry = registry;
     this.symbolizeKeys = symbolizeKeys;
+    this.freeze = freeze;
     this.allowUnknownExt = allowUnknownExt;
     this.binaryEncoding = runtime.getEncodingService().getAscii8bitEncoding();
     this.utf8Encoding = UTF8Encoding.INSTANCE;
@@ -118,7 +120,12 @@
   private IRubyObject consumeString(int size, Encoding encoding) {
     byte[] bytes = readBytes(size);
     ByteList byteList = new ByteList(bytes, encoding);
-    return runtime.newString(byteList);
+    RubyString string = runtime.newString(byteList);
+    if (this.freeze) {
+      string.setFrozen(true);
+      string = runtime.freezeAndDedupString(string);
+    }
+    return string;
   }
 
   private IRubyObject consumeArray(int size) {
@@ -220,6 +227,14 @@
 
   @Override
   public IRubyObject next() {
+    IRubyObject next = consumeNext();
+    if (freeze) {
+      next.setFrozen(true);
+    }
+    return next;
+  }
+
+  private IRubyObject consumeNext() {
     int position = buffer.position();
     try {
       byte b = buffer.get();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/java/org/msgpack/jruby/Unpacker.java 
new/ext/java/org/msgpack/jruby/Unpacker.java
--- old/ext/java/org/msgpack/jruby/Unpacker.java        2020-02-05 
03:07:56.000000000 +0100
+++ new/ext/java/org/msgpack/jruby/Unpacker.java        2021-02-01 
04:16:37.000000000 +0100
@@ -34,6 +34,7 @@
   private Decoder decoder;
   private final RubyClass underflowErrorClass;
   private boolean symbolizeKeys;
+  private boolean freeze;
   private boolean allowUnknownExt;
 
   public Unpacker(Ruby runtime, RubyClass type) {
@@ -56,6 +57,7 @@
   public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
     symbolizeKeys = false;
     allowUnknownExt = false;
+    freeze = false;
     if (args.length > 0) {
       if (args[args.length - 1] instanceof RubyHash) {
         RubyHash options = (RubyHash) args[args.length - 1];
@@ -63,6 +65,10 @@
         if (sk != null) {
           symbolizeKeys = sk.isTrue();
         }
+        IRubyObject f = options.fastARef(ctx.getRuntime().newSymbol("freeze"));
+        if (f != null) {
+          freeze = f.isTrue();
+        }
         IRubyObject au = 
options.fastARef(ctx.getRuntime().newSymbol("allow_unknown_ext"));
         if (au != null) {
           allowUnknownExt = au.isTrue();
@@ -86,6 +92,11 @@
     return symbolizeKeys ? ctx.getRuntime().getTrue() : 
ctx.getRuntime().getFalse();
   }
 
+  @JRubyMethod(name = "freeze?")
+  public IRubyObject isFreeze(ThreadContext ctx) {
+    return freeze ? ctx.getRuntime().getTrue() : ctx.getRuntime().getFalse();
+  }
+
   @JRubyMethod(name = "allow_unknown_ext?")
   public IRubyObject isAllowUnknownExt(ThreadContext ctx) {
     return allowUnknownExt ? ctx.getRuntime().getTrue() : 
ctx.getRuntime().getFalse();
@@ -144,7 +155,7 @@
     if (limit == -1) {
       limit = byteList.length() - offset;
     }
-    Decoder decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin() + offset, limit, symbolizeKeys, 
allowUnknownExt);
+    Decoder decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin() + offset, limit, symbolizeKeys, 
freeze, allowUnknownExt);
     try {
       data = null;
       data = decoder.next();
@@ -174,7 +185,7 @@
   public IRubyObject feed(ThreadContext ctx, IRubyObject data) {
     ByteList byteList = data.asString().getByteList();
     if (decoder == null) {
-      decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, 
allowUnknownExt);
+      decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, 
freeze, allowUnknownExt);
     } else {
       decoder.feed(byteList.unsafeBytes(), byteList.begin(), 
byteList.length());
     }
@@ -312,7 +323,7 @@
     ByteList byteList = str.getByteList();
     this.stream = stream;
     this.decoder = null;
-    this.decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, 
allowUnknownExt);
+    this.decoder = new Decoder(ctx.getRuntime(), registry, 
byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, 
freeze, allowUnknownExt);
     return getStream(ctx);
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/buffer.c new/ext/msgpack/buffer.c
--- old/ext/msgpack/buffer.c    2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/buffer.c    2021-02-01 04:16:37.000000000 +0100
@@ -23,11 +23,11 @@
 static ID s_replace;
 #endif
 
-#ifdef COMPAT_HAVE_ENCODING  /* see compat.h*/
 int msgpack_rb_encindex_utf8;
 int msgpack_rb_encindex_usascii;
 int msgpack_rb_encindex_ascii8bit;
-#endif
+
+ID s_uminus;
 
 #ifndef DISABLE_RMEM
 static msgpack_rmem_t s_rmem;
@@ -35,11 +35,11 @@
 
 void msgpack_buffer_static_init()
 {
-#ifdef COMPAT_HAVE_ENCODING
+    s_uminus = rb_intern("-@");
+
     msgpack_rb_encindex_utf8 = rb_utf8_encindex();
     msgpack_rb_encindex_usascii = rb_usascii_encindex();
     msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
-#endif
 
 #ifndef DISABLE_RMEM
     msgpack_rmem_init(&s_rmem);
@@ -308,9 +308,7 @@
 static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE 
string)
 {
     VALUE mapped_string = rb_str_dup(string);
-#ifdef COMPAT_HAVE_ENCODING
     ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
-#endif
 
     _msgpack_buffer_add_new_chunk(b);
 
@@ -337,7 +335,6 @@
 
     if(b->io != Qnil) {
         msgpack_buffer_flush(b);
-#ifdef COMPAT_HAVE_ENCODING
         if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
             rb_funcall(b->io, b->io_write_all_method, 1, string);
         } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
@@ -347,10 +344,6 @@
         } else {
             msgpack_buffer_append(b, RSTRING_PTR(string), length);
         }
-#else
-        rb_funcall(b->io, b->io_write_all_method, 1, string);
-#endif
-
     } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
         _msgpack_buffer_append_reference(b, string);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/buffer.h new/ext/msgpack/buffer.h
--- old/ext/msgpack/buffer.h    2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/buffer.h    2021-02-01 04:16:37.000000000 +0100
@@ -49,11 +49,11 @@
 
 #define NO_MAPPED_STRING ((VALUE)0)
 
-#ifdef COMPAT_HAVE_ENCODING  /* see compat.h*/
 extern int msgpack_rb_encindex_utf8;
 extern int msgpack_rb_encindex_usascii;
 extern int msgpack_rb_encindex_ascii8bit;
-#endif
+
+extern ID s_uminus;
 
 struct msgpack_buffer_chunk_t;
 typedef struct msgpack_buffer_chunk_t msgpack_buffer_chunk_t;
@@ -438,7 +438,7 @@
     return rb_str_substr(b->head->mapped_string, offset, length);
 }
 
-static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, 
size_t length, bool will_be_frozen)
+static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, 
size_t length, bool will_be_frozen, bool utf8)
 {
 #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
     /* optimize */
@@ -446,16 +446,52 @@
             b->head->mapped_string != NO_MAPPED_STRING &&
             length >= b->read_reference_threshold) {
         VALUE result = _msgpack_buffer_refer_head_mapped_string(b, length);
+        if (utf8) ENCODING_SET(result, msgpack_rb_encindex_utf8);
         _msgpack_buffer_consumed(b, length);
         return result;
     }
 #endif
 
-    VALUE result = rb_str_new(b->read_buffer, length);
+    VALUE result;
+
+#ifdef HAVE_RB_ENC_INTERNED_STR
+    if (will_be_frozen) {
+        result = rb_enc_interned_str(b->read_buffer, length, utf8 ? 
rb_utf8_encoding() : rb_ascii8bit_encoding());
+    } else {
+        if (utf8) {
+            result = rb_utf8_str_new(b->read_buffer, length);
+        } else {
+            result = rb_str_new(b->read_buffer, length);
+        }
+    }
     _msgpack_buffer_consumed(b, length);
     return result;
-}
 
+#else
 
-#endif
+    if (utf8) {
+        result = rb_utf8_str_new(b->read_buffer, length);
+    } else {
+        result = rb_str_new(b->read_buffer, length);
+    }
+
+#if STR_UMINUS_DEDUPE
+    if (will_be_frozen) {
+#if STR_UMINUS_DEDUPE_FROZEN
+        // Starting from MRI 2.8 it is preferable to freeze the string
+        // before deduplication so that it can be interned directly
+        // otherwise it would be duplicated first which is wasteful.
+        rb_str_freeze(result);
+#endif //STR_UMINUS_DEDUPE_FROZEN
+        // MRI 2.5 and older do not deduplicate strings that are already
+        // frozen.
+        result = rb_funcall(result, s_uminus, 0);
+    }
+#endif // STR_UMINUS_DEDUPE
+    _msgpack_buffer_consumed(b, length);
+    return result;
+
+#endif // HAVE_RB_ENC_INTERNED_STR
+}
 
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/compat.h new/ext/msgpack/compat.h
--- old/ext/msgpack/compat.h    2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/compat.h    2021-02-01 04:16:37.000000000 +0100
@@ -20,6 +20,7 @@
 
 #include <stdbool.h>
 #include "ruby.h"
+#include "ruby/encoding.h"
 
 #if defined(HAVE_RUBY_ST_H)
 #  include "ruby/st.h"  /* ruby hash on Ruby 1.9 */
@@ -38,18 +39,6 @@
 #  define ZALLOC_N(type,n) RB_ZALLOC_N(type,n)
 #endif
 
-/*
- * COMPAT_HAVE_ENCODING
- */
-#ifdef HAVE_RUBY_ENCODING_H
-#  include "ruby/encoding.h"
-#  define COMPAT_HAVE_ENCODING
-#endif
-
-#if defined(__MACRUBY__)  /* MacRuby */
-#  undef COMPAT_HAVE_ENCODING
-#endif
-
 
 /*
  * define STR_DUP_LIKELY_DOES_COPY
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/extconf.rb new/ext/msgpack/extconf.rb
--- old/ext/msgpack/extconf.rb  2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/extconf.rb  2021-02-01 04:16:37.000000000 +0100
@@ -4,6 +4,7 @@
 have_header("st.h")
 have_func("rb_str_replace", ["ruby.h"])
 have_func("rb_intern_str", ["ruby.h"])
+have_func("rb_enc_interned_str", "ruby.h")
 have_func("rb_sym2str", ["ruby.h"])
 have_func("rb_str_intern", ["ruby.h"])
 have_func("rb_block_lambda", ["ruby.h"])
@@ -25,6 +26,44 @@
   $CFLAGS << %[ -DDISABLE_RMEM]
 end
 
+# checking if Hash#[]= (rb_hash_aset) dedupes string keys
+h = {}
+x = {}
+r = rand.to_s
+h[%W(#{r}).join('')] = :foo
+x[%W(#{r}).join('')] = :foo
+if x.keys[0].equal?(h.keys[0])
+  $CFLAGS << ' -DHASH_ASET_DEDUPE=1 '
+else
+  $CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
+end
+
+
+# checking if String#-@ (str_uminus) dedupes... '
+begin
+  a = -(%w(t e s t).join)
+  b = -(%w(t e s t).join)
+  if a.equal?(b)
+    $CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
+  else
+    $CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
+  end
+rescue NoMethodError
+  $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
+end
+
+# checking if String#-@ (str_uminus) directly interns frozen strings... '
+begin
+  s = rand.to_s.freeze
+  if (-s).equal?(s) && (-s.dup).equal?(s)
+    $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
+  else
+    $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
+  end
+rescue NoMethodError
+  $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
+end
+
 if warnflags = CONFIG['warnflags']
   warnflags.slice!(/ -Wdeclaration-after-statement/)
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/packer.h new/ext/msgpack/packer.h
--- old/ext/msgpack/packer.h    2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/packer.h    2021-02-01 04:16:37.000000000 +0100
@@ -396,7 +396,6 @@
     msgpack_buffer_append_string(PACKER_BUFFER_(pk), payload);
 }
 
-#ifdef COMPAT_HAVE_ENCODING
 static inline bool msgpack_packer_is_binary(VALUE v, int encindex)
 {
     return encindex == msgpack_rb_encindex_ascii8bit;
@@ -414,7 +413,6 @@
 #endif
         ;
 }
-#endif
 
 static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, 
VALUE v)
 {
@@ -425,7 +423,6 @@
         rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes 
should be <= %lu", len, 0xffffffffUL);
     }
 
-#ifdef COMPAT_HAVE_ENCODING
     int encindex = ENCODING_GET(v);
     if(msgpack_packer_is_binary(v, encindex) && !pk->compatibility_mode) {
         /* write ASCII-8BIT string using Binary type */
@@ -443,10 +440,6 @@
         msgpack_packer_write_raw_header(pk, (unsigned int)len);
         msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
     }
-#else
-    msgpack_packer_write_raw_header(pk, (unsigned int)len);
-    msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
-#endif
 }
 
 static inline void msgpack_packer_write_symbol_string_value(msgpack_packer_t* 
pk, VALUE v)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/unpacker.c new/ext/msgpack/unpacker.c
--- old/ext/msgpack/unpacker.c  2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/unpacker.c  2021-02-01 04:16:37.000000000 +0100
@@ -142,33 +142,17 @@
 
 static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
 {
+    if(uk->freeze) {
+        rb_obj_freeze(object);
+    }
+
     uk->last_object = object;
     reset_head_byte(uk);
     return PRIMITIVE_OBJECT_COMPLETE;
 }
 
-static inline int object_complete_string(msgpack_unpacker_t* uk, VALUE str)
-{
-#ifdef COMPAT_HAVE_ENCODING
-    ENCODING_SET(str, msgpack_rb_encindex_utf8);
-#endif
-    return object_complete(uk, str);
-}
-
-static inline int object_complete_binary(msgpack_unpacker_t* uk, VALUE str)
-{
-#ifdef COMPAT_HAVE_ENCODING
-    ENCODING_SET(str, msgpack_rb_encindex_ascii8bit);
-#endif
-    return object_complete(uk, str);
-}
-
 static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, 
VALUE str)
 {
-#ifdef COMPAT_HAVE_ENCODING
-    ENCODING_SET(str, msgpack_rb_encindex_ascii8bit);
-#endif
-
     VALUE proc = msgpack_unpacker_ext_registry_lookup(&uk->ext_registry, 
ext_type);
     if(proc != Qnil) {
         VALUE obj = rb_funcall(proc, s_call, 1, str);
@@ -271,9 +255,10 @@
 
     int ret;
     if(uk->reading_raw_type == RAW_TYPE_STRING) {
-        ret = object_complete_string(uk, uk->reading_raw);
-    } else if(uk->reading_raw_type == RAW_TYPE_BINARY) {
-        ret = object_complete_binary(uk, uk->reading_raw);
+        ENCODING_SET(uk->reading_raw, msgpack_rb_encindex_utf8);
+        ret = object_complete(uk, uk->reading_raw);
+    } else if (uk->reading_raw_type == RAW_TYPE_BINARY) {
+        ret = object_complete(uk, uk->reading_raw);
     } else {
         ret = object_complete_ext(uk, uk->reading_raw_type, uk->reading_raw);
     }
@@ -290,19 +275,20 @@
     if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
         /* don't use zerocopy for hash keys but get a frozen string directly
          * because rb_hash_aset freezes keys and it causes copying */
-        bool will_freeze = is_reading_map_key(uk);
-        VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), 
length, will_freeze);
+        bool will_freeze = uk->freeze || is_reading_map_key(uk);
+        VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), 
length, will_freeze, raw_type == RAW_TYPE_STRING);
         int ret;
-        if(raw_type == RAW_TYPE_STRING) {
-            ret = object_complete_string(uk, string);
-        } else if(raw_type == RAW_TYPE_BINARY) {
-            ret = object_complete_binary(uk, string);
+        if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
+            ret = object_complete(uk, string);
         } else {
             ret = object_complete_ext(uk, raw_type, string);
         }
+
+# if !HASH_ASET_DEDUPE
         if(will_freeze) {
             rb_obj_freeze(string);
         }
+# endif
         uk->reading_raw_remaining = 0;
         return ret;
     }
@@ -332,7 +318,7 @@
     SWITCH_RANGE(b, 0xa0, 0xbf)  // FixRaw / fixstr
         int count = b & 0x1f;
         if(count == 0) {
-            return object_complete_string(uk, rb_str_buf_new(0));
+            return object_complete(uk, rb_utf8_str_new_static("", 0));
         }
         /* read_raw_body_begin sets uk->reading_raw */
         uk->reading_raw_remaining = count;
@@ -517,7 +503,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
                 uint8_t count = cb->u8;
                 if(count == 0) {
-                    return object_complete_string(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_utf8_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
@@ -529,7 +515,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
                 uint16_t count = _msgpack_be16(cb->u16);
                 if(count == 0) {
-                    return object_complete_string(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_utf8_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
@@ -541,7 +527,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
                 uint32_t count = _msgpack_be32(cb->u32);
                 if(count == 0) {
-                    return object_complete_string(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_utf8_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
@@ -553,7 +539,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
                 uint8_t count = cb->u8;
                 if(count == 0) {
-                    return object_complete_binary(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
@@ -565,7 +551,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
                 uint16_t count = _msgpack_be16(cb->u16);
                 if(count == 0) {
-                    return object_complete_binary(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
@@ -577,7 +563,7 @@
                 READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
                 uint32_t count = _msgpack_be32(cb->u32);
                 if(count == 0) {
-                    return object_complete_binary(uk, rb_str_buf_new(0));
+                    return object_complete(uk, rb_str_new_static("", 0));
                 }
                 /* read_raw_body_begin sets uk->reading_raw */
                 uk->reading_raw_remaining = count;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/unpacker.h new/ext/msgpack/unpacker.h
--- old/ext/msgpack/unpacker.h  2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/unpacker.h  2021-02-01 04:16:37.000000000 +0100
@@ -64,6 +64,7 @@
 
     /* options */
     bool symbolize_keys;
+    bool freeze;
     bool allow_unknown_ext;
 };
 
@@ -96,6 +97,11 @@
     uk->symbolize_keys = enable;
 }
 
+static inline void msgpack_unpacker_set_freeze(msgpack_unpacker_t* uk, bool 
enable)
+{
+    uk->freeze = enable;
+}
+
 static inline void msgpack_unpacker_set_allow_unknown_ext(msgpack_unpacker_t* 
uk, bool enable)
 {
     uk->allow_unknown_ext = enable;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ext/msgpack/unpacker_class.c 
new/ext/msgpack/unpacker_class.c
--- old/ext/msgpack/unpacker_class.c    2020-02-05 03:07:56.000000000 +0100
+++ new/ext/msgpack/unpacker_class.c    2021-02-01 04:16:37.000000000 +0100
@@ -105,6 +105,9 @@
         v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys")));
         msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
 
+        v = rb_hash_aref(options, ID2SYM(rb_intern("freeze")));
+        msgpack_unpacker_set_freeze(uk, RTEST(v));
+
         v = rb_hash_aref(options, ID2SYM(rb_intern("allow_unknown_ext")));
         msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
     }
@@ -118,6 +121,12 @@
     return uk->symbolize_keys ? Qtrue : Qfalse;
 }
 
+static VALUE Unpacker_freeze_p(VALUE self)
+{
+    UNPACKER(self, uk);
+    return uk->freeze ? Qtrue : Qfalse;
+}
+
 static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
 {
     UNPACKER(self, uk);
@@ -438,6 +447,7 @@
 
     rb_define_method(cMessagePack_Unpacker, "initialize", 
MessagePack_Unpacker_initialize, -1);
     rb_define_method(cMessagePack_Unpacker, "symbolize_keys?", 
Unpacker_symbolized_keys_p, 0);
+    rb_define_method(cMessagePack_Unpacker, "freeze?", Unpacker_freeze_p, 0);
     rb_define_method(cMessagePack_Unpacker, "allow_unknown_ext?", 
Unpacker_allow_unknown_ext_p, 0);
     rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
     rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/msgpack/version.rb new/lib/msgpack/version.rb
--- old/lib/msgpack/version.rb  2020-02-05 03:07:56.000000000 +0100
+++ new/lib/msgpack/version.rb  2021-02-01 04:16:37.000000000 +0100
@@ -1,10 +1,6 @@
 module MessagePack
-  VERSION = "1.3.3"
-
-  # NOTE for msgpack-ruby maintainer:
-  # Check these things to release new binaryes for new Ruby versions 
(especially for Windows):
-  # * versions/supports of rake-compiler & rake-compiler-dock
-  #   
https://github.com/rake-compiler/rake-compiler-dock/blob/master/History.md
-  # * update RUBY_CC_VERSION in Rakefile
-  # * check Ruby dependency of released mswin gem details
+  VERSION = "1.4.2"
+  # Note for maintainers:
+  #  Don't miss building/releasing the JRuby version (rake buld:java)
+  #  See "How to build -java rubygems" in README for more details.
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/msgpack.rb new/lib/msgpack.rb
--- old/lib/msgpack.rb  2020-02-05 03:07:56.000000000 +0100
+++ new/lib/msgpack.rb  2021-02-01 04:16:37.000000000 +0100
@@ -5,11 +5,7 @@
   require "msgpack/msgpack.jar"
   org.msgpack.jruby.MessagePackLibrary.new.load(JRuby.runtime, false)
 else
-  begin
-    require "msgpack/#{RUBY_VERSION[/\d+.\d+/]}/msgpack"
-  rescue LoadError
-    require "msgpack/msgpack"
-  end
+  require "msgpack/msgpack"
 end
 
 require "msgpack/packer"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2020-02-05 03:07:56.000000000 +0100
+++ new/metadata        2021-02-01 04:16:37.000000000 +0100
@@ -1,16 +1,16 @@
 --- !ruby/object:Gem::Specification
 name: msgpack
 version: !ruby/object:Gem::Version
-  version: 1.3.3
+  version: 1.4.2
 platform: ruby
 authors:
 - Sadayuki Furuhashi
 - Theo Hultberg
 - Satoshi Tagomori
-autorequire: 
+autorequire:
 bindir: bin
 cert_chain: []
-date: 2020-02-05 00:00:00.000000000 Z
+date: 2021-02-01 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: bundler
@@ -44,30 +44,16 @@
   name: rake-compiler
   requirement: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-  type: :development
-  prerelease: false
-  version_requirements: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
-      - !ruby/object:Gem::Version
-        version: '1.0'
-- !ruby/object:Gem::Dependency
-  name: rake-compiler-dock
-  requirement: !ruby/object:Gem::Requirement
-    requirements:
-    - - "~>"
+    - - ">="
       - !ruby/object:Gem::Version
-        version: '1.0'
+        version: '0'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
-    - - "~>"
+    - - ">="
       - !ruby/object:Gem::Version
-        version: '1.0'
+        version: '0'
 - !ruby/object:Gem::Dependency
   name: rspec
   requirement: !ruby/object:Gem::Requirement
@@ -128,7 +114,7 @@
 - ChangeLog
 - Gemfile
 - LICENSE
-- README.rdoc
+- README.md
 - Rakefile
 - appveyor.yml
 - bench/pack.rb
@@ -228,7 +214,7 @@
 licenses:
 - Apache 2.0
 metadata: {}
-post_install_message: 
+post_install_message:
 rdoc_options: []
 require_paths:
 - lib
@@ -236,15 +222,15 @@
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
-      version: '0'
+      version: '2.4'
 required_rubygems_version: !ruby/object:Gem::Requirement
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.1.2
-signing_key: 
+rubygems_version: 3.2.3
+signing_key:
 specification_version: 4
 summary: MessagePack, a binary-based efficient data interchange format.
 test_files:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack.gemspec new/msgpack.gemspec
--- old/msgpack.gemspec 2020-02-05 03:07:56.000000000 +0100
+++ new/msgpack.gemspec 2021-02-01 04:16:37.000000000 +0100
@@ -20,13 +20,11 @@
   end
   s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
 
+  s.required_ruby_version = ">= 2.4"
+
   s.add_development_dependency 'bundler'
   s.add_development_dependency 'rake'
-  s.add_development_dependency 'rake-compiler', ['~> 1.0']
-  if /java/ !~ RUBY_PLATFORM
-    # NOTE: rake-compiler-dock SHOULD be updated for new Ruby versions
-    s.add_development_dependency 'rake-compiler-dock', ['~> 1.0']
-  end
+  s.add_development_dependency 'rake-compiler'
   s.add_development_dependency 'rspec', ['~> 3.3']
   s.add_development_dependency 'yard'
   s.add_development_dependency 'json'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/spec_helper.rb new/spec/spec_helper.rb
--- old/spec/spec_helper.rb     2020-02-05 03:07:56.000000000 +0100
+++ new/spec/spec_helper.rb     2021-02-01 04:16:37.000000000 +0100
@@ -19,6 +19,23 @@
   /java/ =~ RUBY_PLATFORM
 end
 
+# checking if Hash#[]= (rb_hash_aset) dedupes string keys
+def automatic_string_keys_deduplication?
+  h = {}
+  x = {}
+  r = rand.to_s
+  h[%W(#{r}).join('')] = :foo
+  x[%W(#{r}).join('')] = :foo
+
+  x.keys[0].equal?(h.keys[0])
+end
+
+def string_deduplication?
+  r1 = rand.to_s
+  r2 = r1.dup
+  (-r1).equal?(-r2)
+end
+
 if java?
   RSpec.configure do |c|
     c.treat_symbols_as_metadata_keys_with_true_values = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/unpacker_spec.rb new/spec/unpacker_spec.rb
--- old/spec/unpacker_spec.rb   2020-02-05 03:07:56.000000000 +0100
+++ new/spec/unpacker_spec.rb   2021-02-01 04:16:37.000000000 +0100
@@ -18,13 +18,26 @@
   it 'gets options to specify how to unpack values' do
     u1 = MessagePack::Unpacker.new
     u1.symbolize_keys?.should == false
+    u1.freeze?.should == false
     u1.allow_unknown_ext?.should == false
 
-    u2 = MessagePack::Unpacker.new(symbolize_keys: true, allow_unknown_ext: 
true)
+    u2 = MessagePack::Unpacker.new(symbolize_keys: true, freeze: true, 
allow_unknown_ext: true)
     u2.symbolize_keys?.should == true
+    u2.freeze?.should == true
     u2.allow_unknown_ext?.should == true
   end
 
+  if automatic_string_keys_deduplication?
+    it 'ensure string hash keys are deduplicated' do
+      sample_data = [{"foo" => 1}, {"foo" => 2}]
+      sample_packed = 
MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
+      unpacker.feed(sample_packed)
+      hashes = nil
+      unpacker.each { |obj| hashes = obj }
+      expect(hashes[0].keys.first).to equal(hashes[1].keys.first)
+    end
+  end
+
   it 'gets IO or object which has #read to read data from it' do
     sample_data = {"message" => "morning!", "num" => 1}
     sample_packed = MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
@@ -621,6 +634,14 @@
       array = ['foo'] * 10_000
       MessagePack.unpack(MessagePack.pack(array)).size.should == 10_000
     end
+
+    it 'preserve string encoding (issue #200)' do
+      string = 'a'.force_encoding(Encoding::UTF_8)
+      MessagePack.unpack(MessagePack.pack(string)).encoding.should == 
string.encoding
+
+      string *= 256
+      MessagePack.unpack(MessagePack.pack(string)).encoding.should == 
string.encoding
+    end
   end
 
   context 'extensions' do
@@ -651,6 +672,88 @@
       end
     end
 
+    context 'freeze' do
+      let :struct do
+        {'hello' => 'world', 'nested' => ['object', {'structure' => true}]}
+      end
+
+      let :buffer do
+        MessagePack.pack(struct)
+      end
+
+      let :unpacker do
+        described_class.new(:freeze => true)
+      end
+
+      it 'can freeze objects when using .unpack' do
+        parsed_struct = MessagePack.unpack(buffer, freeze: true)
+        parsed_struct.should == struct
+
+        parsed_struct.should be_frozen
+        parsed_struct['hello'].should be_frozen
+        parsed_struct['nested'].should be_frozen
+        parsed_struct['nested'][0].should be_frozen
+        parsed_struct['nested'][1].should be_frozen
+
+        if string_deduplication?
+          parsed_struct.keys[0].should be_equal('hello'.freeze)
+          parsed_struct.keys[1].should be_equal('nested'.freeze)
+          parsed_struct.values[0].should be_equal('world'.freeze)
+          parsed_struct.values[1][0].should be_equal('object'.freeze)
+          parsed_struct.values[1][1].keys[0].should 
be_equal('structure'.freeze)
+        end
+      end
+
+      it 'can freeze objects when using #each' do
+        objs = []
+        unpacker.feed(buffer)
+        unpacker.each do |obj|
+          objs << obj
+        end
+
+        parsed_struct = objs.first
+        parsed_struct.should == struct
+
+        parsed_struct.should be_frozen
+        parsed_struct['hello'].should be_frozen
+        parsed_struct['nested'].should be_frozen
+        parsed_struct['nested'][0].should be_frozen
+        parsed_struct['nested'][1].should be_frozen
+
+        if string_deduplication?
+          parsed_struct.keys[0].should be_equal('hello'.freeze)
+          parsed_struct.keys[1].should be_equal('nested'.freeze)
+          parsed_struct.values[0].should be_equal('world'.freeze)
+          parsed_struct.values[1][0].should be_equal('object'.freeze)
+          parsed_struct.values[1][1].keys[0].should 
be_equal('structure'.freeze)
+        end
+      end
+
+      it 'can freeze objects when using #feed_each' do
+        objs = []
+        unpacker.feed_each(buffer) do |obj|
+          objs << obj
+        end
+
+        parsed_struct = objs.first
+        parsed_struct.should == struct
+
+        parsed_struct.should be_frozen
+        parsed_struct['hello'].should be_frozen
+        parsed_struct['nested'].should be_frozen
+        parsed_struct['nested'][0].should be_frozen
+        parsed_struct['nested'][1].should be_frozen
+
+        if string_deduplication?
+          parsed_struct.keys[0].should be_equal('hello'.freeze)
+          parsed_struct.keys[1].should be_equal('nested'.freeze)
+          parsed_struct.values[0].should be_equal('world'.freeze)
+          parsed_struct.values[1][0].should be_equal('object'.freeze)
+          parsed_struct.values[1][1].keys[0].should 
be_equal('structure'.freeze)
+        end
+      end
+    end
+
     context 'binary encoding', :encodings do
       let :buffer do
         MessagePack.pack({'hello' => 'world', 'nested' => ['object', 
{'structure' => true}]})

Reply via email to