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}]})