msgpack 1.5.4 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec6ef147d4d948d86915dd5ed06893bd281bcba60a1a48869e0f1b895e1a4d7e
4
- data.tar.gz: 49f4753d9ce5fc686c529a97b8fb409283cde4521c8e28a3f61d92fedc717148
3
+ metadata.gz: e2f5a7cb55341aa8e930c92374b3aeb7bc74b1ccdfe0dede04e36169ce63354f
4
+ data.tar.gz: 42d92aff731b1a0ba35d775390c381bcff95fdb25ad8993248ca61753fb4b9e3
5
5
  SHA512:
6
- metadata.gz: b094e3408d3d7411af91e81e3e59dfb23875696d2415b8759fa9d11476de795a98d7a2d1b9eee60a603157a3139614e5a349169c75d3737faabacbf4975bc31d
7
- data.tar.gz: 27e8b222d6a20253b341e3dc5fe1f656e2698af47e95d2e1c40abb43c22a26c231cc680519e7464ba9b45745cd550f9a7ab649015311c69468f93944fd9dfc6a
6
+ metadata.gz: 3cae7bc28afab9c63303d2aab6eb66e892fdacb0a5ba21113d7d4f8deac7647a18e2f2e708c66764671e78221a04b388c0bda93a3c8b2d2732c4b66d805408c5
7
+ data.tar.gz: d7fb26c1078340d7eed9d3589500c0fd4fcbb3aa995af82fbe632167494bd2400c9247f3d8c8b5091a3b0ad0e77a9f2624a154adc1781dbf611d6dc50f682afe
data/ChangeLog CHANGED
@@ -1,4 +1,8 @@
1
- 2022-07-25
1
+ 2022-08-22 1.5.5:
2
+
3
+ * Fix a segfault when GC triggers inside a recursive extension.
4
+
5
+ 2022-07-25 1.5.4:
2
6
 
3
7
  * Fix a segfault when deserializing empty symbol (`:""`).
4
8
  * Improve compilation flags to not strip debug symbols.
data/ext/msgpack/buffer.c CHANGED
@@ -613,9 +613,11 @@ size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b)
613
613
 
614
614
  size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length)
615
615
  {
616
+ #define MIN(x, y) (((x) < (y)) ? (x) : (y))
617
+
616
618
  if(RSTRING_LEN(string) == 0) {
617
619
  /* direct read */
618
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(length), string);
620
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), string);
619
621
  if(ret == Qnil) {
620
622
  return 0;
621
623
  }
@@ -627,7 +629,7 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
627
629
  b->io_buffer = rb_str_buf_new(0);
628
630
  }
629
631
 
630
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(length), b->io_buffer);
632
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), b->io_buffer);
631
633
  if(ret == Qnil) {
632
634
  return 0;
633
635
  }
@@ -635,6 +637,8 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
635
637
 
636
638
  rb_str_buf_cat(string, (const void*)RSTRING_PTR(b->io_buffer), rl);
637
639
  return rl;
640
+
641
+ #undef MIN
638
642
  }
639
643
 
640
644
  size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length)
@@ -60,13 +60,16 @@ void msgpack_unpacker_static_destroy()
60
60
  #define HEAD_BYTE_REQUIRED 0xc1
61
61
 
62
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;
63
65
  #ifdef UNPACKER_STACK_RMEM
64
- return msgpack_rmem_alloc(&s_stack_rmem);
66
+ stack->data = msgpack_rmem_alloc(&s_stack_rmem);
65
67
  /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
66
68
  #else
67
- /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
68
- 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));
69
71
  #endif
72
+ return stack;
70
73
  }
71
74
 
72
75
  msgpack_unpacker_t* _msgpack_unpacker_new(void)
@@ -81,17 +84,17 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
81
84
  uk->reading_raw = Qnil;
82
85
 
83
86
  uk->stack = _msgpack_unpacker_new_stack();
84
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
85
87
 
86
88
  return uk;
87
89
  }
88
90
 
89
91
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
90
92
  #ifdef UNPACKER_STACK_RMEM
91
- msgpack_rmem_free(&s_stack_rmem, stack);
93
+ msgpack_rmem_free(&s_stack_rmem, stack->data);
92
94
  #else
93
- xfree(stack);
95
+ xfree(stack->data);
94
96
  #endif
97
+ xfree(stack);
95
98
  }
96
99
 
97
100
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
@@ -100,18 +103,24 @@ void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
100
103
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
101
104
  }
102
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
+
103
119
  void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
104
120
  {
105
121
  rb_gc_mark(uk->last_object);
106
122
  rb_gc_mark(uk->reading_raw);
107
-
108
- msgpack_unpacker_stack_t* s = uk->stack;
109
- msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
110
- for(; s < send; s++) {
111
- rb_gc_mark(s->object);
112
- rb_gc_mark(s->key);
113
- }
114
-
123
+ msgpack_unpacker_mark_stack(uk->stack);
115
124
  /* See MessagePack_Buffer_wrap */
116
125
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
117
126
  rb_gc_mark(uk->buffer_ref);
@@ -123,9 +132,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
123
132
 
124
133
  uk->head_byte = HEAD_BYTE_REQUIRED;
125
134
 
126
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack_depth);*/
127
- uk->stack_depth = 0;
128
-
135
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
136
+ uk->stack->depth = 0;
129
137
  uk->last_object = Qnil;
130
138
  uk->reading_raw = Qnil;
131
139
  uk->reading_raw_remaining = 0;
@@ -201,37 +209,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
201
209
  }
202
210
 
203
211
  /* stack funcs */
204
- 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)
205
213
  {
206
- return &uk->stack[uk->stack_depth-1];
214
+ return &uk->stack->data[uk->stack->depth-1];
207
215
  }
208
216
 
209
217
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
210
218
  {
211
219
  reset_head_byte(uk);
212
220
 
213
- if(uk->stack_capacity - uk->stack_depth <= 0) {
221
+ if(uk->stack->capacity - uk->stack->depth <= 0) {
214
222
  return PRIMITIVE_STACK_TOO_DEEP;
215
223
  }
216
224
 
217
- msgpack_unpacker_stack_t* next = &uk->stack[uk->stack_depth];
225
+ msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
218
226
  next->count = count;
219
227
  next->type = type;
220
228
  next->object = object;
221
229
  next->key = Qnil;
222
230
 
223
- uk->stack_depth++;
231
+ uk->stack->depth++;
224
232
  return PRIMITIVE_CONTAINER_START;
225
233
  }
226
234
 
227
235
  static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
228
236
  {
229
- return --uk->stack_depth;
237
+ return --uk->stack->depth;
230
238
  }
231
239
 
232
240
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
233
241
  {
234
- return uk->stack_depth == 0;
242
+ return uk->stack->depth == 0;
235
243
  }
236
244
 
237
245
  #ifdef USE_CASE_RANGE
@@ -259,8 +267,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
259
267
 
260
268
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
261
269
  {
262
- if(uk->stack_depth > 0) {
263
- 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);
264
272
  if(top->type == STACK_TYPE_MAP_KEY) {
265
273
  return true;
266
274
  }
@@ -314,20 +322,14 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
314
322
  reset_head_byte(uk);
315
323
  uk->reading_raw_remaining = 0;
316
324
 
317
- msgpack_unpacker_stack_t* stack = uk->stack;
318
- size_t stack_depth = uk->stack_depth;
319
- size_t stack_capacity = uk->stack_capacity;
320
-
321
- uk->stack = _msgpack_unpacker_new_stack();
322
- uk->stack_depth = 0;
323
- 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;
324
328
 
325
329
  obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
326
330
 
327
- _msgpack_unpacker_free_stack(uk->stack);
328
- uk->stack = stack;
329
- uk->stack_depth = stack_depth;
330
- uk->stack_capacity = stack_capacity;
331
+ uk->stack = child_stack->parent;
332
+ _msgpack_unpacker_free_stack(child_stack);
331
333
 
332
334
  return object_complete(uk, obj);
333
335
  }
@@ -737,7 +739,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
737
739
 
738
740
  container_completed:
739
741
  {
740
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
742
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
741
743
  switch(top->type) {
742
744
  case STACK_TYPE_ARRAY:
743
745
  rb_ary_push(top->object, uk->last_object);
@@ -787,7 +789,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
787
789
 
788
790
  container_completed:
789
791
  {
790
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
792
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
791
793
 
792
794
  /* this section optimized out */
793
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;
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.5.4"
2
+ VERSION = "1.5.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
@@ -587,6 +587,30 @@ describe MessagePack::Factory do
587
587
  GC.stress = false
588
588
  end
589
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
590
614
  end
591
615
 
592
616
  describe 'DefaultFactory' 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.5.4
4
+ version: 1.5.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-07-25 00:00:00.000000000 Z
13
+ date: 2022-08-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler