msgpack 1.5.1 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,6 +34,13 @@ static ID s_call;
34
34
  static msgpack_rmem_t s_stack_rmem;
35
35
  #endif
36
36
 
37
+ #if !defined(HAVE_RB_HASH_NEW_CAPA)
38
+ static inline VALUE rb_hash_new_capa(long capa)
39
+ {
40
+ return rb_hash_new();
41
+ }
42
+ #endif
43
+
37
44
  void msgpack_unpacker_static_init()
38
45
  {
39
46
  #ifdef UNPACKER_STACK_RMEM
@@ -53,13 +60,16 @@ void msgpack_unpacker_static_destroy()
53
60
  #define HEAD_BYTE_REQUIRED 0xc1
54
61
 
55
62
  static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
63
+ msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
64
+ stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
56
65
  #ifdef UNPACKER_STACK_RMEM
57
- return msgpack_rmem_alloc(&s_stack_rmem);
66
+ stack->data = msgpack_rmem_alloc(&s_stack_rmem);
58
67
  /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
59
68
  #else
60
- /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
61
- return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
69
+ /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
70
+ stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
62
71
  #endif
72
+ return stack;
63
73
  }
64
74
 
65
75
  msgpack_unpacker_t* _msgpack_unpacker_new(void)
@@ -74,17 +84,17 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
74
84
  uk->reading_raw = Qnil;
75
85
 
76
86
  uk->stack = _msgpack_unpacker_new_stack();
77
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
78
87
 
79
88
  return uk;
80
89
  }
81
90
 
82
91
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
83
92
  #ifdef UNPACKER_STACK_RMEM
84
- msgpack_rmem_free(&s_stack_rmem, stack);
93
+ msgpack_rmem_free(&s_stack_rmem, stack->data);
85
94
  #else
86
- xfree(stack);
95
+ xfree(stack->data);
87
96
  #endif
97
+ xfree(stack);
88
98
  }
89
99
 
90
100
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
@@ -93,18 +103,24 @@ void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
93
103
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
94
104
  }
95
105
 
106
+ void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
107
+ {
108
+ while (stack) {
109
+ msgpack_unpacker_stack_entry_t* s = stack->data;
110
+ msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
111
+ for(; s < send; s++) {
112
+ rb_gc_mark(s->object);
113
+ rb_gc_mark(s->key);
114
+ }
115
+ stack = stack->parent;
116
+ }
117
+ }
118
+
96
119
  void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
97
120
  {
98
121
  rb_gc_mark(uk->last_object);
99
122
  rb_gc_mark(uk->reading_raw);
100
-
101
- msgpack_unpacker_stack_t* s = uk->stack;
102
- msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
103
- for(; s < send; s++) {
104
- rb_gc_mark(s->object);
105
- rb_gc_mark(s->key);
106
- }
107
-
123
+ msgpack_unpacker_mark_stack(uk->stack);
108
124
  /* See MessagePack_Buffer_wrap */
109
125
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
110
126
  rb_gc_mark(uk->buffer_ref);
@@ -116,9 +132,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
116
132
 
117
133
  uk->head_byte = HEAD_BYTE_REQUIRED;
118
134
 
119
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack_depth);*/
120
- uk->stack_depth = 0;
121
-
135
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
136
+ uk->stack->depth = 0;
122
137
  uk->last_object = Qnil;
123
138
  uk->reading_raw = Qnil;
124
139
  uk->reading_raw_remaining = 0;
@@ -170,6 +185,9 @@ static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
170
185
  static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
171
186
  {
172
187
  if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
188
+ if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
189
+ return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
190
+ }
173
191
  return object_complete_symbol(uk, rb_str_intern(str));
174
192
  }
175
193
 
@@ -191,37 +209,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
191
209
  }
192
210
 
193
211
  /* stack funcs */
194
- static inline msgpack_unpacker_stack_t* _msgpack_unpacker_stack_top(msgpack_unpacker_t* uk)
212
+ static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
195
213
  {
196
- return &uk->stack[uk->stack_depth-1];
214
+ return &uk->stack->data[uk->stack->depth-1];
197
215
  }
198
216
 
199
217
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
200
218
  {
201
219
  reset_head_byte(uk);
202
220
 
203
- if(uk->stack_capacity - uk->stack_depth <= 0) {
221
+ if(uk->stack->capacity - uk->stack->depth <= 0) {
204
222
  return PRIMITIVE_STACK_TOO_DEEP;
205
223
  }
206
224
 
207
- msgpack_unpacker_stack_t* next = &uk->stack[uk->stack_depth];
225
+ msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
208
226
  next->count = count;
209
227
  next->type = type;
210
228
  next->object = object;
211
229
  next->key = Qnil;
212
230
 
213
- uk->stack_depth++;
231
+ uk->stack->depth++;
214
232
  return PRIMITIVE_CONTAINER_START;
215
233
  }
216
234
 
217
235
  static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
218
236
  {
219
- return --uk->stack_depth;
237
+ return --uk->stack->depth;
220
238
  }
221
239
 
222
240
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
223
241
  {
224
- return uk->stack_depth == 0;
242
+ return uk->stack->depth == 0;
225
243
  }
226
244
 
227
245
  #ifdef USE_CASE_RANGE
@@ -249,8 +267,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
249
267
 
250
268
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
251
269
  {
252
- if(uk->stack_depth > 0) {
253
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
270
+ if(uk->stack->depth > 0) {
271
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
254
272
  if(top->type == STACK_TYPE_MAP_KEY) {
255
273
  return true;
256
274
  }
@@ -302,25 +320,17 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
302
320
  VALUE obj;
303
321
  uk->last_object = Qnil;
304
322
  reset_head_byte(uk);
305
- size_t ext_size = uk->reading_raw_remaining;
306
323
  uk->reading_raw_remaining = 0;
307
324
 
308
- msgpack_unpacker_stack_t* stack = uk->stack;
309
- size_t stack_depth = uk->stack_depth;
310
- size_t stack_capacity = uk->stack_capacity;
311
-
312
- uk->stack = _msgpack_unpacker_new_stack();
313
- uk->stack_depth = 0;
314
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
325
+ msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
326
+ child_stack->parent = uk->stack;
327
+ uk->stack = child_stack;
315
328
 
316
329
  obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
317
330
 
318
- _msgpack_unpacker_free_stack(uk->stack);
319
- uk->stack = stack;
320
- uk->stack_depth = stack_depth;
321
- uk->stack_capacity = stack_capacity;
331
+ uk->stack = child_stack->parent;
332
+ _msgpack_unpacker_free_stack(child_stack);
322
333
 
323
- msgpack_buffer_skip(UNPACKER_BUFFER_(uk), ext_size);
324
334
  return object_complete(uk, obj);
325
335
  }
326
336
  }
@@ -373,9 +383,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
373
383
 
374
384
  SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
375
385
  int count = b & 0x1f;
376
- if(count == 0) {
377
- return object_complete(uk, rb_utf8_str_new_static("", 0));
378
- }
379
386
  /* read_raw_body_begin sets uk->reading_raw */
380
387
  uk->reading_raw_remaining = count;
381
388
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -392,7 +399,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
392
399
  if(count == 0) {
393
400
  return object_complete(uk, rb_hash_new());
394
401
  }
395
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new());
402
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
396
403
 
397
404
  SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
398
405
  switch(b) {
@@ -475,7 +482,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
475
482
  {
476
483
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
477
484
  uint32_t u32 = _msgpack_be32(cb->u32);
478
- return object_complete(uk, ULONG2NUM((unsigned long)u32));
485
+ return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
479
486
  }
480
487
 
481
488
  case 0xcf: // unsigned int 64
@@ -503,7 +510,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
503
510
  {
504
511
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
505
512
  int32_t i32 = _msgpack_be32(cb->i32);
506
- return object_complete(uk, LONG2NUM((long)i32));
513
+ return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
507
514
  }
508
515
 
509
516
  case 0xd3: // signed int 64
@@ -558,9 +565,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
558
565
  {
559
566
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
560
567
  uint8_t count = cb->u8;
561
- if(count == 0) {
562
- return object_complete(uk, rb_utf8_str_new_static("", 0));
563
- }
564
568
  /* read_raw_body_begin sets uk->reading_raw */
565
569
  uk->reading_raw_remaining = count;
566
570
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -570,9 +574,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
570
574
  {
571
575
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
572
576
  uint16_t count = _msgpack_be16(cb->u16);
573
- if(count == 0) {
574
- return object_complete(uk, rb_utf8_str_new_static("", 0));
575
- }
576
577
  /* read_raw_body_begin sets uk->reading_raw */
577
578
  uk->reading_raw_remaining = count;
578
579
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -582,9 +583,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
582
583
  {
583
584
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
584
585
  uint32_t count = _msgpack_be32(cb->u32);
585
- if(count == 0) {
586
- return object_complete(uk, rb_utf8_str_new_static("", 0));
587
- }
588
586
  /* read_raw_body_begin sets uk->reading_raw */
589
587
  uk->reading_raw_remaining = count;
590
588
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -594,9 +592,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
594
592
  {
595
593
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
596
594
  uint8_t count = cb->u8;
597
- if(count == 0) {
598
- return object_complete(uk, rb_str_new_static("", 0));
599
- }
600
595
  /* read_raw_body_begin sets uk->reading_raw */
601
596
  uk->reading_raw_remaining = count;
602
597
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -606,9 +601,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
606
601
  {
607
602
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
608
603
  uint16_t count = _msgpack_be16(cb->u16);
609
- if(count == 0) {
610
- return object_complete(uk, rb_str_new_static("", 0));
611
- }
612
604
  /* read_raw_body_begin sets uk->reading_raw */
613
605
  uk->reading_raw_remaining = count;
614
606
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -618,9 +610,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
618
610
  {
619
611
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
620
612
  uint32_t count = _msgpack_be32(cb->u32);
621
- if(count == 0) {
622
- return object_complete(uk, rb_str_new_static("", 0));
623
- }
624
613
  /* read_raw_body_begin sets uk->reading_raw */
625
614
  uk->reading_raw_remaining = count;
626
615
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -653,7 +642,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
653
642
  if(count == 0) {
654
643
  return object_complete(uk, rb_hash_new());
655
644
  }
656
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new());
645
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
657
646
  }
658
647
 
659
648
  case 0xdf: // map 32
@@ -663,7 +652,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
663
652
  if(count == 0) {
664
653
  return object_complete(uk, rb_hash_new());
665
654
  }
666
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new());
655
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
667
656
  }
668
657
 
669
658
  default:
@@ -750,7 +739,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
750
739
 
751
740
  container_completed:
752
741
  {
753
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
742
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
754
743
  switch(top->type) {
755
744
  case STACK_TYPE_ARRAY:
756
745
  rb_ary_push(top->object, uk->last_object);
@@ -800,7 +789,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
800
789
 
801
790
  container_completed:
802
791
  {
803
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
792
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
804
793
 
805
794
  /* this section optimized out */
806
795
  // TODO object_complete still creates objects which should be optimized out
@@ -27,6 +27,7 @@
27
27
 
28
28
  struct msgpack_unpacker_t;
29
29
  typedef struct msgpack_unpacker_t msgpack_unpacker_t;
30
+ typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
30
31
 
31
32
  enum stack_type_t {
32
33
  STACK_TYPE_ARRAY,
@@ -39,19 +40,22 @@ typedef struct {
39
40
  enum stack_type_t type;
40
41
  VALUE object;
41
42
  VALUE key;
42
- } msgpack_unpacker_stack_t;
43
+ } msgpack_unpacker_stack_entry_t;
44
+
45
+ struct msgpack_unpacker_stack_t {
46
+ size_t depth;
47
+ size_t capacity;
48
+ msgpack_unpacker_stack_entry_t *data;
49
+ msgpack_unpacker_stack_t *parent;
50
+ };
43
51
 
44
52
  #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
45
53
 
46
54
  struct msgpack_unpacker_t {
47
55
  msgpack_buffer_t buffer;
48
-
56
+ msgpack_unpacker_stack_t *stack;
49
57
  unsigned int head_byte;
50
58
 
51
- msgpack_unpacker_stack_t* stack;
52
- size_t stack_depth;
53
- size_t stack_capacity;
54
-
55
59
  VALUE last_object;
56
60
 
57
61
  VALUE reading_raw;
@@ -209,7 +209,7 @@ static VALUE Unpacker_read_array_header(VALUE self)
209
209
  raise_unpacker_error(r);
210
210
  }
211
211
 
212
- return ULONG2NUM(size);
212
+ return ULONG2NUM(size); // long at least 32 bits
213
213
  }
214
214
 
215
215
  static VALUE Unpacker_read_map_header(VALUE self)
@@ -222,7 +222,7 @@ static VALUE Unpacker_read_map_header(VALUE self)
222
222
  raise_unpacker_error((int)r);
223
223
  }
224
224
 
225
- return ULONG2NUM(size);
225
+ return ULONG2NUM(size); // long at least 32 bits
226
226
  }
227
227
 
228
228
 
@@ -450,4 +450,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
450
450
 
451
451
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
452
452
  }
453
-
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.5.1"
2
+ VERSION = "1.5.6"
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/msgpack.gemspec CHANGED
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'rspec', ['~> 3.3']
28
28
  s.add_development_dependency 'yard'
29
29
  s.add_development_dependency 'json'
30
+ s.add_development_dependency 'benchmark-ips', ['~> 2.10.0']
30
31
  end
data/spec/factory_spec.rb CHANGED
@@ -422,6 +422,12 @@ describe MessagePack::Factory do
422
422
  MessagePack::ExtensionValue.new(1, factory.dump(x: 1, y: 2, z: 3)),
423
423
  3,
424
424
  ]
425
+
426
+ expect(factory.load(payload)).to be == [
427
+ 1,
428
+ Point.new(1, 2, 3),
429
+ 3,
430
+ ]
425
431
  end
426
432
 
427
433
  it 'can be nested' do
@@ -468,6 +474,10 @@ describe MessagePack::Factory do
468
474
  expect(roundtrip(:symbol)).to be :symbol
469
475
  end
470
476
 
477
+ it 'works with empty symbol' do
478
+ expect(roundtrip(:"")).to be :""
479
+ end
480
+
471
481
  it 'preserves encoding for ASCII symbols' do
472
482
  expect(:symbol.encoding).to be Encoding::US_ASCII
473
483
  expect(roundtrip(:symbol)).to be :symbol
@@ -577,6 +587,30 @@ describe MessagePack::Factory do
577
587
  GC.stress = false
578
588
  end
579
589
  end
590
+
591
+ it 'does not crash in recursive extensions' do
592
+ my_hash_type = Class.new(Hash)
593
+ factory = MessagePack::Factory.new
594
+ factory.register_type(7,
595
+ my_hash_type,
596
+ packer: ->(value, packer) do
597
+ packer.write(value.to_h)
598
+ end,
599
+ unpacker: ->(unpacker) { my_hash_type.new(unpacker.read) },
600
+ recursive: true,
601
+ )
602
+
603
+ payload = factory.dump(
604
+ [my_hash_type.new]
605
+ )
606
+
607
+ begin
608
+ GC.stress = true
609
+ factory.load(payload)
610
+ ensure
611
+ GC.stress = false
612
+ end
613
+ end
580
614
  end
581
615
 
582
616
  describe 'DefaultFactory' do
data/spec/spec_helper.rb CHANGED
@@ -20,7 +20,11 @@ require "msgpack/bigint"
20
20
  if GC.respond_to?(:verify_compaction_references)
21
21
  # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
22
22
  # move objects around, helping to find object movement bugs.
23
- GC.verify_compaction_references(double_heap: true, toward: :empty)
23
+ begin
24
+ GC.verify_compaction_references(double_heap: true, toward: :empty)
25
+ rescue NotImplementedError
26
+ # Some platforms don't support compaction
27
+ end
24
28
  end
25
29
 
26
30
  if GC.respond_to?(:auto_compact=)
@@ -29,6 +33,8 @@ end
29
33
 
30
34
  IS_JRUBY = RUBY_ENGINE == 'jruby'
31
35
 
36
+ IS_TRUFFLERUBY = RUBY_ENGINE == 'truffleruby'
37
+
32
38
  # checking if Hash#[]= (rb_hash_aset) dedupes string keys
33
39
  def automatic_string_keys_deduplication?
34
40
  h = {}
@@ -87,14 +87,14 @@ describe MessagePack::Timestamp do
87
87
 
88
88
  let(:time96_min) { Time.at(-2**63).utc }
89
89
  it 'is serialized into timestamp96' do
90
- skip if IS_JRUBY # JRuby cannot handle numerics larger than long
90
+ skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
91
91
  expect(factory.pack(time96_min).size).to be 15
92
92
  expect(factory.unpack(factory.pack(time96_min)).utc).to eq(time96_min)
93
93
  end
94
94
 
95
95
  let(:time96_max) { Time.at(2**63 - 1).utc }
96
96
  it 'is serialized into timestamp96' do
97
- skip if IS_JRUBY # JRuby cannot handle numerics larger than long
97
+ skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
98
98
  expect(factory.pack(time96_max).size).to be 15
99
99
  expect(factory.unpack(factory.pack(time96_max)).utc).to eq(time96_max)
100
100
  end
@@ -707,6 +707,18 @@ describe MessagePack::Unpacker do
707
707
  described_class.new(:freeze => true)
708
708
  end
709
709
 
710
+ if (-"test").equal?(-"test") # RUBY_VERSION >= "2.5"
711
+ it 'dedups strings' do
712
+ interned_str = -"test"
713
+ roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
714
+ expect(roundtrip).to be interned_str
715
+
716
+ interned_str = -""
717
+ roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
718
+ expect(roundtrip).to be interned_str
719
+ end
720
+ end
721
+
710
722
  it 'can freeze objects when using .unpack' do
711
723
  parsed_struct = MessagePack.unpack(buffer, freeze: true)
712
724
  parsed_struct.should == struct
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.5.1
4
+ version: 1.5.6
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-04-07 00:00:00.000000000 Z
13
+ date: 2022-08-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -96,6 +96,20 @@ dependencies:
96
96
  - - ">="
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: benchmark-ips
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: 2.10.0
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: 2.10.0
99
113
  description: MessagePack is a binary-based efficient object serialization library.
100
114
  It enables to exchange structured objects between many languages like JSON. But
101
115
  unlike JSON, it is very fast and small.
@@ -117,16 +131,7 @@ files:
117
131
  - README.md
118
132
  - Rakefile
119
133
  - appveyor.yml
120
- - bench/pack.rb
121
- - bench/pack_log.rb
122
- - bench/pack_log_long.rb
123
- - bench/pack_symbols.rb
124
- - bench/run.sh
125
- - bench/run_long.sh
126
- - bench/run_symbols.sh
127
- - bench/unpack.rb
128
- - bench/unpack_log.rb
129
- - bench/unpack_log_long.rb
134
+ - bench/bench.rb
130
135
  - doclib/msgpack.rb
131
136
  - doclib/msgpack/buffer.rb
132
137
  - doclib/msgpack/core_ext.rb
@@ -231,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
236
  - !ruby/object:Gem::Version
232
237
  version: '0'
233
238
  requirements: []
234
- rubygems_version: 3.3.3
239
+ rubygems_version: 3.1.2
235
240
  signing_key:
236
241
  specification_version: 4
237
242
  summary: MessagePack, a binary-based efficient data interchange format.
data/bench/pack.rb DELETED
@@ -1,23 +0,0 @@
1
- require 'viiite'
2
- require 'msgpack'
3
-
4
- data = { 'hello' => 'world', 'nested' => ['structure', {value: 42}] }
5
- data_sym = { hello: 'world', nested: ['structure', {value: 42}] }
6
-
7
- data = MessagePack.pack(:hello => 'world', :nested => ['structure', {:value => 42}])
8
-
9
- Viiite.bench do |b|
10
- b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
11
- b.report(:strings) do
12
- runs.times do
13
- MessagePack.pack(data)
14
- end
15
- end
16
-
17
- b.report(:symbols) do
18
- runs.times do
19
- MessagePack.pack(data_sym)
20
- end
21
- end
22
- end
23
- end
data/bench/pack_log.rb DELETED
@@ -1,33 +0,0 @@
1
- require 'viiite'
2
- require 'msgpack'
3
-
4
- data_plain = { 'message' => '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"' }
5
- data_structure = {
6
- 'remote_host' => '127.0.0.1',
7
- 'remote_user' => '-',
8
- 'date' => '10/Oct/2000:13:55:36 -0700',
9
- 'request' => 'GET /apache_pb.gif HTTP/1.0',
10
- 'method' => 'GET',
11
- 'path' => '/apache_pb.gif',
12
- 'protocol' => 'HTTP/1.0',
13
- 'status' => 200,
14
- 'bytes' => 2326,
15
- 'referer' => 'http://www.example.com/start.html',
16
- 'agent' => 'Mozilla/4.08 [en] (Win98; I ;Nav)',
17
- }
18
-
19
- Viiite.bench do |b|
20
- b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
21
- b.report(:plain) do
22
- runs.times do
23
- MessagePack.pack(data_plain)
24
- end
25
- end
26
-
27
- b.report(:structure) do
28
- runs.times do
29
- MessagePack.pack(data_structure)
30
- end
31
- end
32
- end
33
- end