msgpack 1.5.4 → 1.5.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: 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