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 +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
|