msgpack 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c57015d343570a2bccf9f0cb8877bf7e0a83cffa478fa4a99816dc1bb4e5f3d0
4
- data.tar.gz: 13e5f99e0b73c98071e8b0bb8bf841a52283ef9f1502ea578732a4baf1f4d9de
3
+ metadata.gz: a51f64e1c017cafcef6fe080992135f5c610984ecd126f4a3a2127baa4e4a644
4
+ data.tar.gz: bf45726e8f6cb658390199ecb51345e034c908207b090d53934f037555d7c37a
5
5
  SHA512:
6
- metadata.gz: 2c048635dc9d9451ace0aff991a3ea92ccd7bbc397cfa4431c6428a07149fcdf9b31c1b1cd9392aca806669839236b26f90234cc99b8232061b3441707adc409
7
- data.tar.gz: 63af2e6f9f11f8a96115d81aa9d8754220b44cdda069c0094ac5c635c01df75e84ac1e76dd3c2e9e81c7b3d6f5a1ba66f9006c620ec30ef047bfc7c857ffec0d
6
+ metadata.gz: 0ee24ab0cb11c648e9a022f23053c118c020b7c79cac14e00a1bb82faf90c59302727a2dc691c63a959225b06a5c40ec5e09fd8f35154c7474b1e652e27b9bc5
7
+ data.tar.gz: 2fee550949875cc119f1865b9519c75794124ec17065b1da1ec0fd06af29ed7fbdd37d709bf8cdb217d3cf86e3004a18fab16a6ac032eec176735725439ec268
@@ -12,6 +12,7 @@ on:
12
12
  jobs:
13
13
  mri:
14
14
  strategy:
15
+ fail-fast: false
15
16
  matrix:
16
17
  os: [ubuntu, macos, windows]
17
18
  ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1']
@@ -26,11 +27,10 @@ jobs:
26
27
 
27
28
  jruby:
28
29
  strategy:
30
+ fail-fast: false
29
31
  matrix:
30
32
  os: [ubuntu]
31
- # TODO: update to 9.3.3.0 once supported
32
- # https://github.com/ruby/setup-ruby#supported-versions
33
- ruby: ['jruby-9.2.19.0', 'jruby-9.3.2.0']
33
+ ruby: ['jruby-9.2.19.0', 'jruby-9.3.3.0']
34
34
  runs-on: ${{ matrix.os }}-latest
35
35
  steps:
36
36
  - uses: actions/checkout@v2
@@ -43,6 +43,7 @@ jobs:
43
43
  head-versions:
44
44
  continue-on-error: true
45
45
  strategy:
46
+ fail-fast: false
46
47
  matrix:
47
48
  os: [ubuntu]
48
49
  ruby: ['ruby-head', 'jruby-head', 'truffleruby']
data/ChangeLog CHANGED
@@ -1,3 +1,11 @@
1
+ 2022-02-15 version 1.4.5:
2
+
3
+ * Fix to create UTF-8 Symbol keys when symbolize_keys: true
4
+ * Fix to assume Symbols as US-ASCII or UTF-8
5
+ * Optimize Packer/Unpacker initialization
6
+ * Optimize extension class lookup
7
+ * Rename Packer#clear as Packer#reset (#clear is still available as an alias)
8
+
1
9
  2022-01-22 version 1.4.4:
2
10
 
3
11
  * Specify the build option --platform=8 for older Java platforms
@@ -63,7 +63,7 @@ module MessagePack
63
63
 
64
64
  #
65
65
  # Register a type and Class to be registered for packer and/or unpacker.
66
- # If options are not speicified, factory will use :to_msgpack_ext for packer, and
66
+ # If options are not specified, factory will use :to_msgpack_ext for packer, and
67
67
  # :from_msgpack_ext for unpacker.
68
68
  #
69
69
  # @param type [Fixnum] type id of registered Class (0-127)
@@ -14,7 +14,7 @@ module MessagePack
14
14
  # @overload initialize(io, options={})
15
15
  # @param io [IO]
16
16
  # @param options [Hash]
17
- # This packer writes serialzied objects into the IO when the internal buffer is filled.
17
+ # This packer writes serialized objects into the IO when the internal buffer is filled.
18
18
  # _io_ must respond to write(string) or append(string) method.
19
19
  #
20
20
  # Supported options:
@@ -33,12 +33,12 @@ module MessagePack
33
33
  #
34
34
  # @overload register_type(type, klass, &block)
35
35
  # @param type [Fixnum] type id (0-127) user defined type id for specified Class
36
- # @param klass [Class] Class to be serialized with speicifed type id
36
+ # @param klass [Class] Class to be serialized with specified type id
37
37
  # @yieldparam object [Object] object to be serialized
38
38
  #
39
39
  # @overload register_type(type, klass, method_name)
40
40
  # @param type [Fixnum] type id (0-127) user defined type id for specified Class
41
- # @param klass [Class] Class to be serialized with speicifed type id
41
+ # @param klass [Class] Class to be serialized with specified type id
42
42
  # @param method_name [Symbol] method which returns bytes of serialized representation
43
43
  #
44
44
  # @return nil
@@ -155,8 +155,9 @@ module MessagePack
155
155
  #
156
156
  # @return nil
157
157
  #
158
- def clear
158
+ def reset
159
159
  end
160
+ alias clear reset
160
161
 
161
162
  #
162
163
  # Returns size of the internal buffer. Same as buffer.size.
@@ -36,7 +36,7 @@ module MessagePack
36
36
  #
37
37
  # @overload register_type(type, klass, class_method_name)
38
38
  # @param type [Fixnum] type id (0-127) user defined type id for specified Class
39
- # @param klass [Class] Class to be serialized with speicifed type id
39
+ # @param klass [Class] Class to be serialized with specified type id
40
40
  # @param class_method_name [Symbol] class method which returns an instance object
41
41
  #
42
42
  # @return nil
@@ -149,7 +149,7 @@ module MessagePack
149
149
  #
150
150
  # It repeats until the io or internal buffer does not include any complete objects.
151
151
  #
152
- # If the an IO is set, it repeats to read data from the IO when the buffer
152
+ # If an IO is set, it repeats to read data from the IO when the buffer
153
153
  # becomes empty until the IO raises EOFError.
154
154
  #
155
155
  # This method could raise same errors with _read_ excepting EOFError.
@@ -82,26 +82,21 @@ public class ExtensionRegistry {
82
82
  * Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
83
83
  * String have no singleton class and raise a TypeError when trying to get
84
84
  * it.
85
- *
86
- * Since all but symbols are already filtered out when reaching this code
87
- * only symbols are checked here.
88
85
  */
89
- if (!(object instanceof RubySymbol)) {
90
- lookupClass = object.getSingletonClass();
91
- pair = fetchEntryByModule(lookupClass);
92
- if (pair != null) {
93
- return pair;
94
- }
95
- }
96
-
97
- pair = fetchEntryByModule(object.getType());
86
+ lookupClass = object.getMetaClass();
87
+ pair = fetchEntryByModule(lookupClass);
98
88
  if (pair != null) {
99
89
  return pair;
100
90
  }
101
91
 
102
- if (lookupClass == null) {
103
- lookupClass = object.getType(); // only for Symbol
92
+ RubyModule realClass = object.getType();
93
+ if (realClass != lookupClass) {
94
+ pair = fetchEntryByModule(realClass);
95
+ if (pair != null) {
96
+ return pair;
97
+ }
104
98
  }
99
+
105
100
  ExtensionEntry e = findEntryByModuleOrAncestor(lookupClass);
106
101
  if (e != null && e.hasPacker()) {
107
102
  extensionsByAncestor.put(e.getExtensionModule(), e);
data/ext/msgpack/buffer.h CHANGED
@@ -494,9 +494,9 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
494
494
  #endif // HAVE_RB_ENC_INTERNED_STR
495
495
  }
496
496
 
497
- static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length)
497
+ static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length, bool utf8)
498
498
  {
499
- return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true, false));
499
+ return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true, utf8));
500
500
  }
501
501
 
502
502
  #endif
@@ -62,24 +62,22 @@ static VALUE Buffer_alloc(VALUE klass)
62
62
 
63
63
  static ID get_partial_read_method(VALUE io)
64
64
  {
65
- if(rb_respond_to(io, s_readpartial)) {
65
+ if(io != Qnil && rb_respond_to(io, s_readpartial)) {
66
66
  return s_readpartial;
67
- } else if(rb_respond_to(io, s_read)) {
68
- return s_read;
69
- } else {
70
- return s_read;
71
67
  }
68
+ return s_read;
72
69
  }
73
70
 
74
71
  static ID get_write_all_method(VALUE io)
75
72
  {
76
- if(rb_respond_to(io, s_write)) {
77
- return s_write;
78
- } else if(rb_respond_to(io, s_append)) {
79
- return s_append;
80
- } else {
81
- return s_write;
73
+ if(io != Qnil) {
74
+ if(rb_respond_to(io, s_write)) {
75
+ return s_write;
76
+ } else if(rb_respond_to(io, s_append)) {
77
+ return s_append;
78
+ }
82
79
  }
80
+ return s_write;
83
81
  }
84
82
 
85
83
  void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options)
@@ -245,10 +243,11 @@ static VALUE read_until_eof_rescue(VALUE args)
245
243
  return Qnil;
246
244
  }
247
245
 
248
- static VALUE read_until_eof_error(VALUE args)
246
+ static VALUE read_until_eof_error(VALUE args, VALUE error)
249
247
  {
250
248
  /* ignore EOFError */
251
249
  UNUSED(args);
250
+ UNUSED(error);
252
251
  return Qnil;
253
252
  }
254
253
 
@@ -30,7 +30,7 @@ typedef struct msgpack_factory_t msgpack_factory_t;
30
30
 
31
31
  struct msgpack_factory_t {
32
32
  msgpack_packer_ext_registry_t pkrg;
33
- msgpack_unpacker_ext_registry_t ukrg;
33
+ msgpack_unpacker_ext_registry_t *ukrg;
34
34
  bool has_symbol_ext_type;
35
35
  bool optimized_symbol_ext_type;
36
36
  int symbol_ext_type;
@@ -49,14 +49,14 @@ static void Factory_free(msgpack_factory_t* fc)
49
49
  return;
50
50
  }
51
51
  msgpack_packer_ext_registry_destroy(&fc->pkrg);
52
- msgpack_unpacker_ext_registry_destroy(&fc->ukrg);
52
+ msgpack_unpacker_ext_registry_release(fc->ukrg);
53
53
  xfree(fc);
54
54
  }
55
55
 
56
56
  void Factory_mark(msgpack_factory_t* fc)
57
57
  {
58
58
  msgpack_packer_ext_registry_mark(&fc->pkrg);
59
- msgpack_unpacker_ext_registry_mark(&fc->ukrg);
59
+ msgpack_unpacker_ext_registry_mark(fc->ukrg);
60
60
  }
61
61
 
62
62
  static VALUE Factory_alloc(VALUE klass)
@@ -72,7 +72,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
72
72
  FACTORY(self, fc);
73
73
 
74
74
  msgpack_packer_ext_registry_init(&fc->pkrg);
75
- msgpack_unpacker_ext_registry_init(&fc->ukrg);
75
+ // fc->ukrg is lazily initialized
76
76
 
77
77
  fc->has_symbol_ext_type = false;
78
78
 
@@ -113,9 +113,7 @@ VALUE MessagePack_Factory_unpacker(int argc, VALUE* argv, VALUE self)
113
113
 
114
114
  msgpack_unpacker_t* uk;
115
115
  Data_Get_Struct(unpacker, msgpack_unpacker_t, uk);
116
-
117
- msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
118
- msgpack_unpacker_ext_registry_dup(&fc->ukrg, &uk->ext_registry);
116
+ msgpack_unpacker_ext_registry_borrow(fc->ukrg, &uk->ext_registry);
119
117
  uk->optimized_symbol_ext_type = fc->optimized_symbol_ext_type;
120
118
  uk->symbol_ext_type = fc->symbol_ext_type;
121
119
 
@@ -127,12 +125,19 @@ static VALUE Factory_registered_types_internal(VALUE self)
127
125
  FACTORY(self, fc);
128
126
 
129
127
  VALUE uk_mapping = rb_hash_new();
130
- for(int i=0; i < 256; i++) {
131
- if(fc->ukrg.array[i] != Qnil) {
132
- rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg.array[i]);
128
+ if (fc->ukrg) {
129
+ for(int i=0; i < 256; i++) {
130
+ if(fc->ukrg->array[i] != Qnil) {
131
+ rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
132
+ }
133
133
  }
134
134
  }
135
- return rb_ary_new3(2, rb_hash_dup(fc->pkrg.hash), uk_mapping);
135
+
136
+ return rb_ary_new3(
137
+ 2,
138
+ RTEST(fc->pkrg.hash) ? rb_hash_dup(fc->pkrg.hash) : rb_hash_new(),
139
+ uk_mapping
140
+ );
136
141
  }
137
142
 
138
143
  static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
@@ -281,7 +281,7 @@ static VALUE Packer_flush(VALUE self)
281
281
  return self;
282
282
  }
283
283
 
284
- static VALUE Packer_clear(VALUE self)
284
+ static VALUE Packer_reset(VALUE self)
285
285
  {
286
286
  PACKER(self, pk);
287
287
  msgpack_buffer_clear(PACKER_BUFFER_(pk));
@@ -339,7 +339,10 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
339
339
  static VALUE Packer_registered_types_internal(VALUE self)
340
340
  {
341
341
  PACKER(self, pk);
342
- return rb_hash_dup(pk->ext_registry.hash);
342
+ if (RTEST(pk->ext_registry.hash)) {
343
+ return rb_hash_dup(pk->ext_registry.hash);
344
+ }
345
+ return rb_hash_new();
343
346
  }
344
347
 
345
348
  static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
@@ -440,7 +443,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
440
443
  rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
441
444
 
442
445
  /* delegation methods */
443
- rb_define_method(cMessagePack_Packer, "clear", Packer_clear, 0);
446
+ rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
447
+ rb_define_alias(cMessagePack_Packer, "clear", "reset");
444
448
  rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
445
449
  rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
446
450
  rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
@@ -30,8 +30,8 @@ void msgpack_packer_ext_registry_static_destroy()
30
30
 
31
31
  void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
32
32
  {
33
- pkrg->hash = rb_hash_new();
34
- pkrg->cache = rb_hash_new();
33
+ pkrg->hash = Qnil;
34
+ pkrg->cache = Qnil;
35
35
  }
36
36
 
37
37
  void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
@@ -43,15 +43,20 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
43
43
  void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
44
44
  msgpack_packer_ext_registry_t* dst)
45
45
  {
46
- dst->hash = rb_hash_dup(src->hash);
47
- dst->cache = rb_hash_dup(src->cache);
46
+ dst->hash = RTEST(src->hash) ? rb_hash_dup(src->hash) : Qnil;
47
+ dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache): Qnil;
48
48
  }
49
49
 
50
50
  VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
51
51
  VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
52
52
  {
53
- VALUE e = rb_ary_new3(3, INT2FIX(ext_type), proc, arg);
54
- /* clear lookup cache not to miss added type */
55
- rb_hash_clear(pkrg->cache);
56
- return rb_hash_aset(pkrg->hash, ext_module, e);
53
+ if (!RTEST(pkrg->hash)) {
54
+ pkrg->hash = rb_hash_new();
55
+ }
56
+
57
+ if (RTEST(pkrg->cache)) {
58
+ /* clear lookup cache not to miss added type */
59
+ rb_hash_clear(pkrg->cache);
60
+ }
61
+ return rb_hash_aset(pkrg->hash, ext_module, rb_ary_new3(3, INT2FIX(ext_type), proc, arg));
57
62
  }
@@ -70,10 +70,12 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
70
70
  }
71
71
 
72
72
  // fetch lookup_class from cache, which stores results of searching ancestors from pkrg->hash
73
- VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
74
- if(type_inht != Qnil) {
75
- *ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
76
- return rb_ary_entry(type_inht, 1);
73
+ if (RTEST(pkrg->cache)) {
74
+ VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
75
+ if(type_inht != Qnil) {
76
+ *ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
77
+ return rb_ary_entry(type_inht, 1);
78
+ }
77
79
  }
78
80
 
79
81
  return Qnil;
@@ -82,37 +84,34 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
82
84
  static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
83
85
  VALUE instance, int* ext_type_result)
84
86
  {
85
- VALUE lookup_class;
86
87
  VALUE type;
87
88
 
88
- /*
89
- * 1. check whether singleton_class of this instance is registered (or resolved in past) or not.
90
- *
91
- * Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
92
- * String have no singleton class and raise a TypeError when trying to get
93
- * it. See implementation of #singleton_class in ruby's source code:
94
- * VALUE rb_singleton_class(VALUE obj);
95
- *
96
- * Since all but symbols are already filtered out when reaching this code
97
- * only symbols are checked here.
98
- */
99
- if (!SYMBOL_P(instance)) {
100
- lookup_class = rb_singleton_class(instance);
101
-
102
- type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
89
+ if (pkrg->hash == Qnil) { // No extensions registered
90
+ return Qnil;
91
+ }
103
92
 
104
- if(type != Qnil) {
105
- return type;
106
- }
93
+ /*
94
+ * 1. check whether singleton_class or class of this instance is registered (or resolved in past) or not.
95
+ *
96
+ * Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
97
+ * `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
98
+ */
99
+ VALUE lookup_class = rb_class_of(instance);
100
+ type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
101
+ if(type != Qnil) {
102
+ return type;
107
103
  }
108
104
 
109
105
  /*
110
- * 2. check the class of instance is registered (or resolved in past) or not.
106
+ * 2. If the object had a singleton_class check if the real class of instance is registered
107
+ * (or resolved in past) or not.
111
108
  */
112
- type = msgpack_packer_ext_registry_fetch(pkrg, rb_obj_class(instance), ext_type_result);
113
-
114
- if(type != Qnil) {
115
- return type;
109
+ VALUE real_class = rb_obj_class(instance);
110
+ if(lookup_class != real_class) {
111
+ type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result);
112
+ if(type != Qnil) {
113
+ return type;
114
+ }
116
115
  }
117
116
 
118
117
  /*
@@ -126,6 +125,9 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
126
125
  VALUE superclass = args[1];
127
126
  if(superclass != Qnil) {
128
127
  VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
128
+ if (!RTEST(pkrg->cache)) {
129
+ pkrg->cache = rb_hash_new();
130
+ }
129
131
  rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
130
132
  *ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
131
133
  return rb_ary_entry(superclass_type, 1);
@@ -52,9 +52,9 @@ void msgpack_unpacker_static_destroy()
52
52
 
53
53
  #define HEAD_BYTE_REQUIRED 0xc1
54
54
 
55
- void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
55
+ msgpack_unpacker_t* _msgpack_unpacker_new(void)
56
56
  {
57
- memset(uk, 0, sizeof(msgpack_unpacker_t));
57
+ msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
58
58
 
59
59
  msgpack_buffer_init(UNPACKER_BUFFER_(uk));
60
60
 
@@ -71,6 +71,8 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
71
71
  uk->stack = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
72
72
  #endif
73
73
  uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
74
+
75
+ return uk;
74
76
  }
75
77
 
76
78
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
@@ -164,7 +166,7 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
164
166
  return object_complete_symbol(uk, rb_str_intern(str));
165
167
  }
166
168
 
167
- VALUE proc = msgpack_unpacker_ext_registry_lookup(&uk->ext_registry, ext_type);
169
+ VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type);
168
170
  if(proc != Qnil) {
169
171
  VALUE obj = rb_funcall(proc, s_call, 1, str);
170
172
  return object_complete(uk, obj);
@@ -286,24 +288,20 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
286
288
  if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
287
289
  int ret;
288
290
  if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
289
- VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length);
291
+ VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
290
292
  ret = object_complete_symbol(uk, symbol);
291
293
  } else {
292
- /* don't use zerocopy for hash keys but get a frozen string directly
293
- * because rb_hash_aset freezes keys and it causes copying */
294
- bool will_freeze = uk->freeze || is_reading_map_key(uk);
295
- VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
294
+ bool will_freeze = uk->freeze;
296
295
  if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
296
+ /* don't use zerocopy for hash keys but get a frozen string directly
297
+ * because rb_hash_aset freezes keys and it causes copying */
298
+ will_freeze = will_freeze || is_reading_map_key(uk);
299
+ VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
297
300
  ret = object_complete(uk, string);
298
301
  } else {
302
+ VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
299
303
  ret = object_complete_ext(uk, raw_type, string);
300
304
  }
301
-
302
- # if !HASH_ASET_DEDUPE
303
- if(will_freeze) {
304
- rb_obj_freeze(string);
305
- }
306
- # endif
307
305
  }
308
306
  uk->reading_raw_remaining = 0;
309
307
  return ret;
@@ -60,7 +60,7 @@ struct msgpack_unpacker_t {
60
60
 
61
61
  VALUE buffer_ref;
62
62
 
63
- msgpack_unpacker_ext_registry_t ext_registry;
63
+ msgpack_unpacker_ext_registry_t *ext_registry;
64
64
 
65
65
  /* options */
66
66
  bool symbolize_keys;
@@ -86,7 +86,7 @@ void msgpack_unpacker_static_init();
86
86
 
87
87
  void msgpack_unpacker_static_destroy();
88
88
 
89
- void _msgpack_unpacker_init(msgpack_unpacker_t* uk);
89
+ msgpack_unpacker_t* _msgpack_unpacker_new(void);
90
90
 
91
91
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
92
92
 
@@ -45,7 +45,7 @@ static void Unpacker_free(msgpack_unpacker_t* uk)
45
45
  if(uk == NULL) {
46
46
  return;
47
47
  }
48
- msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
48
+ msgpack_unpacker_ext_registry_release(uk->ext_registry);
49
49
  _msgpack_unpacker_destroy(uk);
50
50
  xfree(uk);
51
51
  }
@@ -53,13 +53,12 @@ static void Unpacker_free(msgpack_unpacker_t* uk)
53
53
  static void Unpacker_mark(msgpack_unpacker_t* uk)
54
54
  {
55
55
  msgpack_unpacker_mark(uk);
56
- msgpack_unpacker_ext_registry_mark(&uk->ext_registry);
56
+ msgpack_unpacker_ext_registry_mark(uk->ext_registry);
57
57
  }
58
58
 
59
59
  VALUE MessagePack_Unpacker_alloc(VALUE klass)
60
60
  {
61
- msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
62
- _msgpack_unpacker_init(uk);
61
+ msgpack_unpacker_t* uk = _msgpack_unpacker_new();
63
62
 
64
63
  VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
65
64
  return self;
@@ -94,7 +93,6 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
94
93
 
95
94
  UNPACKER(self, uk);
96
95
 
97
- msgpack_unpacker_ext_registry_init(&uk->ext_registry);
98
96
  uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
99
97
 
100
98
  MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
@@ -133,7 +131,7 @@ static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
133
131
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
134
132
  }
135
133
 
136
- static void raise_unpacker_error(int r)
134
+ NORETURN(static void raise_unpacker_error(int r))
137
135
  {
138
136
  switch(r) {
139
137
  case PRIMITIVE_EOF:
@@ -222,34 +220,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
222
220
  return ULONG2NUM(size);
223
221
  }
224
222
 
225
- static VALUE Unpacker_peek_next_type(VALUE self)
226
- {
227
- UNPACKER(self, uk);
228
-
229
- int r = msgpack_unpacker_peek_next_object_type(uk);
230
- if(r < 0) {
231
- raise_unpacker_error(r);
232
- }
233
-
234
- switch((enum msgpack_unpacker_object_type) r) {
235
- case TYPE_NIL:
236
- return rb_intern("nil");
237
- case TYPE_BOOLEAN:
238
- return rb_intern("boolean");
239
- case TYPE_INTEGER:
240
- return rb_intern("integer");
241
- case TYPE_FLOAT:
242
- return rb_intern("float");
243
- case TYPE_RAW:
244
- return rb_intern("raw");
245
- case TYPE_ARRAY:
246
- return rb_intern("array");
247
- case TYPE_MAP:
248
- return rb_intern("map");
249
- default:
250
- rb_raise(eUnpackError, "logically unknown type %d", r);
251
- }
252
- }
253
223
 
254
224
  static VALUE Unpacker_feed(VALUE self, VALUE data)
255
225
  {
@@ -296,9 +266,10 @@ static VALUE Unpacker_each_impl(VALUE self)
296
266
  }
297
267
  }
298
268
 
299
- static VALUE Unpacker_rescue_EOFError(VALUE self)
269
+ static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
300
270
  {
301
- UNUSED(self);
271
+ UNUSED(args);
272
+ UNUSED(error);
302
273
  return Qnil;
303
274
  }
304
275
 
@@ -347,9 +318,11 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
347
318
  UNPACKER(self, uk);
348
319
 
349
320
  VALUE mapping = rb_hash_new();
350
- for(int i=0; i < 256; i++) {
351
- if(uk->ext_registry.array[i] != Qnil) {
352
- rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry.array[i]);
321
+ if (uk->ext_registry) {
322
+ for(int i=0; i < 256; i++) {
323
+ if(uk->ext_registry->array[i] != Qnil) {
324
+ rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
325
+ }
353
326
  }
354
327
  }
355
328
 
@@ -451,7 +424,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
451
424
  rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
452
425
  rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
453
426
  rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
454
- //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
455
427
  rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
456
428
  rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
457
429
  rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
@@ -27,36 +27,59 @@ void msgpack_unpacker_ext_registry_static_init()
27
27
  s_dup = rb_intern("dup");
28
28
  }
29
29
 
30
+
30
31
  void msgpack_unpacker_ext_registry_static_destroy()
31
32
  { }
32
33
 
33
- void msgpack_unpacker_ext_registry_init(msgpack_unpacker_ext_registry_t* ukrg)
34
+ void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
34
35
  {
35
- for(int i=0; i < 256; i++) {
36
- ukrg->array[i] = Qnil;
36
+ if (ukrg) {
37
+ for(int i=0; i < 256; i++) {
38
+ if (ukrg->array[i] != Qnil) {
39
+ rb_gc_mark(ukrg->array[i]);
40
+ }
41
+ }
37
42
  }
38
43
  }
39
44
 
40
- void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
45
+ msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
41
46
  {
42
- for(int i=0; i < 256; i++) {
43
- rb_gc_mark(ukrg->array[i]);
47
+ msgpack_unpacker_ext_registry_t* dst;
48
+ if (src) {
49
+ if (src->borrow_count) {
50
+ dst = ALLOC(msgpack_unpacker_ext_registry_t);
51
+ dst->borrow_count = 0;
52
+ MEMCPY(dst->array, src->array, VALUE, 256);
53
+ msgpack_unpacker_ext_registry_release(src);
54
+ return dst;
55
+ } else {
56
+ return src;
57
+ }
58
+ } else {
59
+ dst = ALLOC(msgpack_unpacker_ext_registry_t);
60
+ dst->borrow_count = 0;
61
+ for(int i=0; i < 256; i++) {
62
+ dst->array[i] = Qnil;
63
+ }
64
+ return dst;
44
65
  }
45
66
  }
46
67
 
47
- void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
48
- msgpack_unpacker_ext_registry_t* dst)
68
+ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
49
69
  {
50
- for(int i=0; i < 256; i++) {
51
- dst->array[i] = src->array[i];
70
+ if (ukrg) {
71
+ if (ukrg->borrow_count) {
72
+ ukrg->borrow_count--;
73
+ } else {
74
+ xfree(ukrg);
75
+ }
52
76
  }
53
77
  }
54
78
 
55
- VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
79
+ void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
56
80
  VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
57
81
  {
58
- VALUE e = rb_ary_new3(3, ext_module, proc, arg);
59
- VALUE before = ukrg->array[ext_type + 128];
60
- ukrg->array[ext_type + 128] = e;
61
- return before;
82
+ msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
83
+ ext_registry->array[ext_type + 128] = rb_ary_new3(3, ext_module, proc, arg);
84
+ *ukrg = ext_registry;
62
85
  }
@@ -25,35 +25,39 @@ struct msgpack_unpacker_ext_registry_t;
25
25
  typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
26
26
 
27
27
  struct msgpack_unpacker_ext_registry_t {
28
+ unsigned int borrow_count;
28
29
  VALUE array[256];
29
- //int bitmap;
30
30
  };
31
31
 
32
32
  void msgpack_unpacker_ext_registry_static_init();
33
33
 
34
34
  void msgpack_unpacker_ext_registry_static_destroy();
35
35
 
36
- void msgpack_unpacker_ext_registry_init(msgpack_unpacker_ext_registry_t* ukrg);
36
+ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
37
37
 
38
- static inline void msgpack_unpacker_ext_registry_destroy(msgpack_unpacker_ext_registry_t* ukrg)
39
- { }
38
+ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
39
+ {
40
+ if (src) {
41
+ src->borrow_count++;
42
+ *dst = src;
43
+ }
44
+ }
40
45
 
41
46
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
42
47
 
43
- void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
44
- msgpack_unpacker_ext_registry_t* dst);
45
-
46
- VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
48
+ void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
47
49
  VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
48
50
 
49
51
  static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
50
52
  int ext_type)
51
53
  {
52
- VALUE e = ukrg->array[ext_type + 128];
53
- if(e == Qnil) {
54
- return Qnil;
54
+ if (ukrg) {
55
+ VALUE entry = ukrg->array[ext_type + 128];
56
+ if (entry != Qnil) {
57
+ return rb_ary_entry(entry, 1);
58
+ }
55
59
  }
56
- return rb_ary_entry(e, 1);
60
+ return Qnil;
57
61
  }
58
62
 
59
63
  #endif
@@ -14,6 +14,13 @@ class Symbol
14
14
  # The canonical way to do it for symbols would be:
15
15
  # data.unpack1('A*').to_sym
16
16
  # However in this instance we can take a shortcut
17
- data.to_sym
17
+
18
+ # We assume the string encoding is UTF-8, and let Ruby create either
19
+ # an ASCII symbol or UTF-8 symbol.
20
+ data.force_encoding(Encoding::UTF_8).to_sym
21
+ rescue EncodingError
22
+ # If somehow the string wasn't valid UTF-8 not valid ASCII, we fallback
23
+ # to what has been the historical behavior of creating a binary symbol
24
+ data.force_encoding(Encoding::BINARY).to_sym
18
25
  end
19
26
  end
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.4.4"
2
+ VERSION = "1.4.5"
3
3
  # Note for maintainers:
4
4
  # Don't miss building/releasing the JRuby version (rake buld:java)
5
5
  # See "How to build -java rubygems" in README for more details.
data/spec/factory_spec.rb CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: ascii-8bit
2
1
  require 'spec_helper'
3
2
 
4
3
  describe MessagePack::Factory do
@@ -42,6 +41,21 @@ describe MessagePack::Factory do
42
41
  unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
43
42
  expect{ unpacker.read }.to raise_error(MessagePack::UnknownExtTypeError)
44
43
  end
44
+
45
+ it 'does not share the extension registry with unpackers' do
46
+ subject.register_type(0x00, Symbol)
47
+ expect do
48
+ unpacker = subject.unpacker
49
+ expect do
50
+ unpacker.register_type(0x01) {}
51
+ end.to change { unpacker.registered_types }
52
+
53
+ second_unpacker = subject.unpacker
54
+ expect do
55
+ second_unpacker.register_type(0x01) {}
56
+ end.to_not change { unpacker.registered_types }
57
+ end.to_not change { subject.registered_types }
58
+ end
45
59
  end
46
60
 
47
61
  describe '#dump and #load' do
@@ -255,29 +269,25 @@ describe MessagePack::Factory do
255
269
  subject { factory.packer.pack(value).to_s }
256
270
  before { stub_const('Value', Class.new{ include Mod }) }
257
271
  let(:value) { Value.new }
258
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
272
+ it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
259
273
  end
260
274
 
261
275
  describe "packing an object which has been extended by the module" do
262
276
  subject { factory.packer.pack(object).to_s }
263
277
  let(:object) { Object.new.extend Mod }
264
- it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
278
+ it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
265
279
  end
266
280
 
267
281
  describe "unpacking with the module" do
268
- subject { factory.unpacker.feed("\xC7\x06\x01module").unpack }
282
+ subject { factory.unpacker.feed("\xC7\x06\x01module".force_encoding(Encoding::BINARY)).unpack }
269
283
  it { is_expected.to eq "unpacked module" }
270
284
  end
271
285
  end
272
286
  end
273
287
 
274
288
  describe 'the special treatment of symbols with ext type' do
275
- let(:packer) { subject.packer }
276
- let(:unpacker) { subject.unpacker }
277
-
278
- def symbol_after_roundtrip
279
- packed_symbol = packer.pack(:symbol).to_s
280
- unpacker.feed(packed_symbol).unpack
289
+ def roundtrip(object, options = nil)
290
+ subject.load(subject.dump(object), options)
281
291
  end
282
292
 
283
293
  context 'using the optimized symbol unpacker' do
@@ -293,13 +303,25 @@ describe MessagePack::Factory do
293
303
  end
294
304
 
295
305
  it 'lets symbols survive a roundtrip' do
296
- expect(symbol_after_roundtrip).to be :symbol
306
+ expect(roundtrip(:symbol)).to be :symbol
307
+ end
308
+
309
+ it 'preserves encoding for ASCII symbols' do
310
+ expect(:symbol.encoding).to be Encoding::US_ASCII
311
+ expect(roundtrip(:symbol)).to be :symbol
312
+ expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
313
+ end
314
+
315
+ it 'preserves encoding for UTF-8 symbols' do
316
+ expect(:"fée".encoding).to be Encoding::UTF_8
317
+ expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
318
+ expect(roundtrip(:"fée")).to be :"fée"
297
319
  end
298
320
  end
299
321
 
300
322
  context 'if no ext type is registered for symbols' do
301
323
  it 'converts symbols to string' do
302
- expect(symbol_after_roundtrip).to eq 'symbol'
324
+ expect(roundtrip(:symbol)).to eq 'symbol'
303
325
  end
304
326
  end
305
327
 
@@ -308,7 +330,41 @@ describe MessagePack::Factory do
308
330
  before { subject.register_type(0x00, ::Symbol) }
309
331
 
310
332
  it 'lets symbols survive a roundtrip' do
311
- expect(symbol_after_roundtrip).to be :symbol
333
+ expect(roundtrip(:symbol)).to be :symbol
334
+ end
335
+
336
+ it 'works with hash keys' do
337
+ expect(roundtrip(symbol: 1)).to be == { symbol: 1 }
338
+ end
339
+
340
+ it 'works with frozen: true option' do
341
+ expect(roundtrip(:symbol, freeze: true)).to be :symbol
342
+ end
343
+
344
+ it 'preserves encoding for ASCII symbols' do
345
+ expect(:symbol.encoding).to be Encoding::US_ASCII
346
+ expect(roundtrip(:symbol)).to be :symbol
347
+ expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
348
+ end
349
+
350
+ it 'preserves encoding for UTF-8 symbols' do
351
+ expect(:"fée".encoding).to be Encoding::UTF_8
352
+ expect(roundtrip(:"fée")).to be :"fée"
353
+ expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
354
+ end
355
+
356
+ it 'does not handle symbols in other encodings' do
357
+ symbol = "fàe".encode(Encoding::ISO_8859_1).to_sym
358
+ expect(symbol.encoding).to be Encoding::ISO_8859_1
359
+
360
+ if IS_JRUBY
361
+ # JRuby doesn't quite behave like MRI here.
362
+ # "fàe".force_encoding(Encoding::BINARY).to_sym is able to lookup the existing ISO-8859-1 symbol
363
+ # It likely is a JRuby bug.
364
+ expect(roundtrip(symbol).encoding).to be Encoding::ISO_8859_1
365
+ else
366
+ expect(roundtrip(symbol).encoding).to be Encoding::BINARY
367
+ end
312
368
  end
313
369
  end
314
370
 
@@ -332,7 +388,7 @@ describe MessagePack::Factory do
332
388
  before { subject.register_type(0x00, ::Symbol) }
333
389
 
334
390
  it 'lets symbols survive a roundtrip' do
335
- expect(symbol_after_roundtrip).to be :symbol
391
+ expect(roundtrip(:symbol)).to be :symbol
336
392
  end
337
393
 
338
394
  after do
data/spec/spec_helper.rb CHANGED
@@ -25,9 +25,7 @@ if GC.respond_to?(:auto_compact=)
25
25
  GC.auto_compact = true
26
26
  end
27
27
 
28
- def java?
29
- /java/ =~ RUBY_PLATFORM
30
- end
28
+ IS_JRUBY = RUBY_ENGINE == 'jruby'
31
29
 
32
30
  # checking if Hash#[]= (rb_hash_aset) dedupes string keys
33
31
  def automatic_string_keys_deduplication?
@@ -46,7 +44,7 @@ def string_deduplication?
46
44
  (-r1).equal?(-r2)
47
45
  end
48
46
 
49
- if java?
47
+ if IS_JRUBY
50
48
  RSpec.configure do |c|
51
49
  c.treat_symbols_as_metadata_keys_with_true_values = true
52
50
  c.filter_run_excluding :encodings => !(defined? Encoding)
@@ -2,8 +2,6 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- IS_JRUBY = Kernel.const_defined?(:JRUBY_VERSION)
6
-
7
5
  describe MessagePack::Timestamp do
8
6
  describe 'malformed format' do
9
7
  it do
@@ -1,5 +1,3 @@
1
- # encoding: ascii-8bit
2
-
3
1
  require 'stringio'
4
2
  require 'tempfile'
5
3
  require 'zlib'
@@ -302,6 +300,21 @@ describe MessagePack::Unpacker do
302
300
  MessagePack.unpack(MessagePack.pack(symbolized_hash), :symbolize_keys => true).should == symbolized_hash
303
301
  end
304
302
 
303
+ it 'MessagePack.unpack symbolize_keys preserve encoding' do
304
+ hash = { :ascii => 1, :utf8_é => 2}
305
+ loaded_hash = MessagePack.load(MessagePack.pack(hash), :symbolize_keys => true)
306
+
307
+ hash.keys[0].encoding.should == Encoding::US_ASCII # Ruby coerce symbols to US-ASCII when possible.
308
+ loaded_hash.keys[0].should == hash.keys[0]
309
+ loaded_hash.keys[0].encoding.should == hash.keys[0].encoding
310
+
311
+ hash.keys[1].encoding.should == Encoding::UTF_8
312
+ loaded_hash.keys[1].should == hash.keys[1]
313
+ loaded_hash.keys[1].encoding.should == hash.keys[1].encoding
314
+
315
+ MessagePack.unpack(MessagePack.pack(hash), :symbolize_keys => true).should == hash
316
+ end
317
+
305
318
  it 'Unpacker#unpack symbolize_keys' do
306
319
  unpacker = MessagePack::Unpacker.new(:symbolize_keys => true)
307
320
  symbolized_hash = {:a => 'b', :c => 'd'}
@@ -765,7 +778,13 @@ describe MessagePack::Unpacker do
765
778
 
766
779
  context 'binary encoding', :encodings do
767
780
  let :buffer do
768
- MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
781
+ MessagePack.pack({
782
+ 'hello'.b => 'world'.b,
783
+ 'nested'.b => [
784
+ 'object'.b,
785
+ {'structure'.b => true},
786
+ ]
787
+ })
769
788
  end
770
789
 
771
790
  let :unpacker do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msgpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.4
4
+ version: 1.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-01-22 00:00:00.000000000 Z
13
+ date: 2022-02-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler