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 +4 -4
- data/ChangeLog +5 -1
- data/ext/msgpack/buffer.c +6 -2
- data/ext/msgpack/unpacker.c +41 -39
- data/ext/msgpack/unpacker.h +10 -6
- data/lib/msgpack/version.rb +1 -1
- data/spec/factory_spec.rb +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2f5a7cb55341aa8e930c92374b3aeb7bc74b1ccdfe0dede04e36169ce63354f
|
4
|
+
data.tar.gz: 42d92aff731b1a0ba35d775390c381bcff95fdb25ad8993248ca61753fb4b9e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cae7bc28afab9c63303d2aab6eb66e892fdacb0a5ba21113d7d4f8deac7647a18e2f2e708c66764671e78221a04b388c0bda93a3c8b2d2732c4b66d805408c5
|
7
|
+
data.tar.gz: d7fb26c1078340d7eed9d3589500c0fd4fcbb3aa995af82fbe632167494bd2400c9247f3d8c8b5091a3b0ad0e77a9f2624a154adc1781dbf611d6dc50f682afe
|
data/ChangeLog
CHANGED
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)
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -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
|
-
|
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(
|
68
|
-
|
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->
|
127
|
-
uk->
|
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
|
212
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
205
213
|
{
|
206
|
-
return &uk->stack[uk->
|
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->
|
221
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
214
222
|
return PRIMITIVE_STACK_TOO_DEEP;
|
215
223
|
}
|
216
224
|
|
217
|
-
|
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->
|
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->
|
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->
|
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->
|
263
|
-
|
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*
|
318
|
-
|
319
|
-
|
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
|
-
|
328
|
-
|
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
|
-
|
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
|
-
|
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
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -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
|
-
}
|
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;
|
data/lib/msgpack/version.rb
CHANGED
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
|
+
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-
|
13
|
+
date: 2022-08-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|