msgpack 1.7.2 → 1.7.4

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: 2f5b1af6b3a51f5ccc6bcf67c94c1fc6193b02fe01b123e2cfb06a6df9607116
4
- data.tar.gz: cc057f24e1ffa4cdc3e331499eb04de4c2383b0657dcf0baeba08300fd20862e
3
+ metadata.gz: fa4847fba5fd9dfbed01473471b038a0b06a0ee131395c9724a5bceeab7e9823
4
+ data.tar.gz: e80a7dfd7c92a1eaa76b3604027094f1dff4d65ba46babcf739019423dd37fad
5
5
  SHA512:
6
- metadata.gz: 3eb06321a534ca9b16e321cc4a71458532578dafe7967314a662223b1fbf4aa93449c98177fa982aa532ce3732ddda4a6d497704df0e9c874da07f378c73595c
7
- data.tar.gz: 8e540755e3db9e21d7dfa4354854e8b0486f5a1bbf82c3994c6095022205f7873153d364df9310d8072c481de38ca2b4c3e088e4221c3451ceb9438312489419
6
+ metadata.gz: 8f6cbd005ef5d490a2d99ccf45208984a6450ed797f8835884ff758bf71e41e02e397dc174801972386728216f147d09d375763fcc4d9eb853b99520ea40eb19
7
+ data.tar.gz: e0f6aafd4c147075fe7dcde2f54775cbd84b0d4b8c85b660f2569f4f790dfec979ecbef3da032e8a236558678a54dd8fa1e7ce5346c6cb042936d94037b1ec80
data/ChangeLog CHANGED
@@ -1,3 +1,11 @@
1
+ 2024-11-11 1.7.4
2
+
3
+ * Fixed a potental memory leak when recursive unpacker raise.
4
+
5
+ 2024-10-03 1.7.3
6
+
7
+ * Limit initial containers pre-allocation to `SHRT_MAX` (32k) entries.
8
+
1
9
  2023-07-18 1.7.2:
2
10
 
3
11
  * Fix a potential GC bug when packing data using recursive extensions and buffers containing over 512KkiB of data (See #341).
data/README.md CHANGED
@@ -8,15 +8,24 @@ and typical short strings only require an extra byte in addition to the strings
8
8
  If you ever wished to use JSON for convenience (storing an image with metadata) but could
9
9
  not for technical reasons (binary data, size, speed...), MessagePack is a perfect replacement.
10
10
 
11
- require 'msgpack'
12
- msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
13
- MessagePack.unpack(msg) #=> [1,2,3]
11
+ ```ruby
12
+ require 'msgpack'
13
+ msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
14
+ MessagePack.unpack(msg) #=> [1,2,3]
15
+ ```
16
+
17
+ Add msgpack to your Gemfile to install with Bundler:
18
+
19
+ ```ruby
20
+ # Gemfile
21
+ gem 'msgpack'
22
+ ```
14
23
 
15
- Use RubyGems to install:
24
+ Or, use RubyGems to install:
16
25
 
17
26
  gem install msgpack
18
27
 
19
- or build msgpack-ruby and install:
28
+ Or, build msgpack-ruby and install from a checked-out msgpack-ruby repository:
20
29
 
21
30
  bundle
22
31
  rake
@@ -27,11 +36,11 @@ or build msgpack-ruby and install:
27
36
 
28
37
  * Create REST API returing MessagePack using Rails + [RABL](https://github.com/nesquena/rabl)
29
38
  * Store objects efficiently serialized by msgpack on memcached or Redis
30
- * In fact Redis supports msgpack in [EVAL-scripts](http://redis.io/commands/eval)
39
+ * In fact Redis supports msgpack in [EVAL-scripts](https://redis.io/docs/latest/commands/eval/)
31
40
  * Upload data in efficient format from mobile devices such as smartphones
32
41
  * MessagePack works on iPhone/iPad and Android. See also [Objective-C](https://github.com/msgpack/msgpack-objectivec) and [Java](https://github.com/msgpack/msgpack-java) implementations
33
42
  * Design a portable protocol to communicate with embedded devices
34
- * Check also [Fluentd](http://fluentd.org/) which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON)
43
+ * Check also [Fluentd](https://www.fluentd.org) which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON)
35
44
  * Exchange objects between software components written in different languages
36
45
  * You'll need a flexible but efficient format so that components exchange objects while keeping compatibility
37
46
 
@@ -128,9 +137,9 @@ being serialized altogether by throwing an exception:
128
137
 
129
138
  ```ruby
130
139
  class Symbol
131
- def to_msgpack_ext
132
- raise "Serialization of symbols prohibited"
133
- end
140
+ def to_msgpack_ext
141
+ raise "Serialization of symbols prohibited"
142
+ end
134
143
  end
135
144
 
136
145
  MessagePack::DefaultFactory.register_type(0x00, Symbol)
@@ -276,8 +285,8 @@ If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
276
285
 
277
286
  ## Updating documents
278
287
 
279
- Online documents (http://ruby.msgpack.org) is generated from gh-pages branch.
280
- Following commands update documents in gh-pages branch:
288
+ Online documentation (https://ruby.msgpack.org) is generated from the gh-pages branch.
289
+ To update documents in gh-pages branch:
281
290
 
282
291
  bundle exec rake doc
283
292
  git checkout gh-pages
data/ext/msgpack/buffer.h CHANGED
@@ -81,20 +81,6 @@ struct msgpack_buffer_chunk_t {
81
81
  bool rmem;
82
82
  };
83
83
 
84
- union msgpack_buffer_cast_block_t {
85
- char buffer[8];
86
- uint8_t u8;
87
- uint16_t u16;
88
- uint32_t u32;
89
- uint64_t u64;
90
- int8_t i8;
91
- int16_t i16;
92
- int32_t i32;
93
- int64_t i64;
94
- float f;
95
- double d;
96
- };
97
-
98
84
  struct msgpack_buffer_t {
99
85
  char* read_buffer;
100
86
  char* tail_buffer_end;
@@ -107,8 +93,6 @@ struct msgpack_buffer_t {
107
93
  char* rmem_end;
108
94
  void** rmem_owner;
109
95
 
110
- union msgpack_buffer_cast_block_t cast_block;
111
-
112
96
  VALUE io;
113
97
  VALUE io_buffer;
114
98
  ID io_write_all_method;
@@ -383,14 +367,6 @@ static inline size_t msgpack_buffer_skip_nonblock(msgpack_buffer_t* b, size_t le
383
367
  return length;
384
368
  }
385
369
 
386
- static inline union msgpack_buffer_cast_block_t* msgpack_buffer_read_cast_block(msgpack_buffer_t* b, size_t n)
387
- {
388
- if(!msgpack_buffer_read_all(b, b->cast_block.buffer, n)) {
389
- return NULL;
390
- }
391
- return &b->cast_block;
392
- }
393
-
394
370
  size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string, size_t length);
395
371
 
396
372
  static inline size_t msgpack_buffer_read_to_string(msgpack_buffer_t* b, VALUE string, size_t length)
data/ext/msgpack/packer.h CHANGED
@@ -31,15 +31,15 @@ typedef struct msgpack_packer_t msgpack_packer_t;
31
31
  struct msgpack_packer_t {
32
32
  msgpack_buffer_t buffer;
33
33
 
34
- bool compatibility_mode;
35
- bool has_bigint_ext_type;
36
- bool has_symbol_ext_type;
37
-
38
34
  ID to_msgpack_method;
39
35
  VALUE to_msgpack_arg;
40
36
 
41
37
  VALUE buffer_ref;
42
38
 
39
+ bool compatibility_mode;
40
+ bool has_bigint_ext_type;
41
+ bool has_symbol_ext_type;
42
+
43
43
  /* options */
44
44
  bool comaptibility_mode;
45
45
  msgpack_packer_ext_registry_t ext_registry;
@@ -20,13 +20,36 @@
20
20
  #include "rmem.h"
21
21
  #include "extension_value_class.h"
22
22
  #include <assert.h>
23
+ #include <limits.h>
23
24
 
24
25
  #if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
25
26
  #define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
26
27
  #endif
27
28
 
29
+ struct protected_proc_call_args {
30
+ VALUE proc;
31
+ int argc;
32
+ VALUE *argv;
33
+ };
34
+
35
+ static VALUE protected_proc_call_safe(VALUE _args) {
36
+ struct protected_proc_call_args *args = (struct protected_proc_call_args *)_args;
37
+
38
+ return rb_proc_call_with_block(args->proc, args->argc, args->argv, Qnil);
39
+ }
40
+
41
+ static VALUE protected_proc_call(VALUE proc, int argc, VALUE *argv, int *raised) {
42
+ struct protected_proc_call_args args = {
43
+ .proc = proc,
44
+ .argc = argc,
45
+ .argv = argv,
46
+ };
47
+ return rb_protect(protected_proc_call_safe, (VALUE)&args, raised);
48
+ }
49
+
28
50
  static int RAW_TYPE_STRING = 256;
29
51
  static int RAW_TYPE_BINARY = 257;
52
+ static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
30
53
 
31
54
  static msgpack_rmem_t s_stack_rmem;
32
55
 
@@ -37,6 +60,11 @@ static inline VALUE rb_hash_new_capa(long capa)
37
60
  }
38
61
  #endif
39
62
 
63
+ static inline int16_t initial_buffer_size(long size)
64
+ {
65
+ return (size > INITIAL_BUFFER_CAPACITY_MAX) ? INITIAL_BUFFER_CAPACITY_MAX : size;
66
+ }
67
+
40
68
  void msgpack_unpacker_static_init(void)
41
69
  {
42
70
  assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
@@ -51,12 +79,9 @@ void msgpack_unpacker_static_destroy(void)
51
79
 
52
80
  #define HEAD_BYTE_REQUIRED 0xc1
53
81
 
54
- static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
55
- msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
82
+ static inline void _msgpack_unpacker_stack_init(msgpack_unpacker_stack_t *stack) {
56
83
  stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
57
84
  stack->data = msgpack_rmem_alloc(&s_stack_rmem);
58
- /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
59
- return stack;
60
85
  }
61
86
 
62
87
  void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
@@ -68,32 +93,32 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
68
93
  uk->last_object = Qnil;
69
94
  uk->reading_raw = Qnil;
70
95
 
71
- uk->stack = _msgpack_unpacker_new_stack();
96
+ _msgpack_unpacker_stack_init(&uk->stack);
72
97
  }
73
98
 
74
99
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
75
100
  if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
76
101
  rb_bug("Failed to free an rmem pointer, memory leak?");
77
102
  }
78
- xfree(stack);
103
+ stack->data = NULL;
104
+ stack->depth = 0;
79
105
  }
80
106
 
81
107
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
82
108
  {
83
- _msgpack_unpacker_free_stack(uk->stack);
109
+ _msgpack_unpacker_free_stack(&uk->stack);
84
110
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
85
111
  }
86
112
 
87
113
  void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
88
114
  {
89
- while (stack) {
115
+ if (stack->data) {
90
116
  msgpack_unpacker_stack_entry_t* s = stack->data;
91
117
  msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
92
118
  for(; s < send; s++) {
93
119
  rb_gc_mark(s->object);
94
120
  rb_gc_mark(s->key);
95
121
  }
96
- stack = stack->parent;
97
122
  }
98
123
  }
99
124
 
@@ -101,7 +126,7 @@ void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
101
126
  {
102
127
  rb_gc_mark(uk->last_object);
103
128
  rb_gc_mark(uk->reading_raw);
104
- msgpack_unpacker_mark_stack(uk->stack);
129
+ msgpack_unpacker_mark_stack(&uk->stack);
105
130
  /* See MessagePack_Buffer_wrap */
106
131
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
107
132
  rb_gc_mark(uk->buffer_ref);
@@ -114,8 +139,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
114
139
 
115
140
  uk->head_byte = HEAD_BYTE_REQUIRED;
116
141
 
117
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
118
- uk->stack->depth = 0;
142
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack.depth);*/
143
+ uk->stack.depth = 0;
119
144
  uk->last_object = Qnil;
120
145
  uk->reading_raw = Qnil;
121
146
  uk->reading_raw_remaining = 0;
@@ -179,7 +204,12 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
179
204
  if(proc != Qnil) {
180
205
  VALUE obj;
181
206
  VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
182
- obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
207
+ int raised;
208
+ obj = protected_proc_call(proc, 1, &arg, &raised);
209
+ if (raised) {
210
+ uk->last_object = rb_errinfo();
211
+ return PRIMITIVE_RECURSIVE_RAISED;
212
+ }
183
213
  return object_complete(uk, obj);
184
214
  }
185
215
 
@@ -194,35 +224,35 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
194
224
  /* stack funcs */
195
225
  static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
196
226
  {
197
- return &uk->stack->data[uk->stack->depth-1];
227
+ return &uk->stack.data[uk->stack.depth-1];
198
228
  }
199
229
 
200
230
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
201
231
  {
202
232
  reset_head_byte(uk);
203
233
 
204
- if(uk->stack->capacity - uk->stack->depth <= 0) {
234
+ if(uk->stack.capacity - uk->stack.depth <= 0) {
205
235
  return PRIMITIVE_STACK_TOO_DEEP;
206
236
  }
207
237
 
208
- msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
238
+ msgpack_unpacker_stack_entry_t* next = &uk->stack.data[uk->stack.depth];
209
239
  next->count = count;
210
240
  next->type = type;
211
241
  next->object = object;
212
242
  next->key = Qnil;
213
243
 
214
- uk->stack->depth++;
244
+ uk->stack.depth++;
215
245
  return PRIMITIVE_CONTAINER_START;
216
246
  }
217
247
 
218
- static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
248
+ static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
219
249
  {
220
- return --uk->stack->depth;
250
+ return --uk->stack.depth;
221
251
  }
222
252
 
223
253
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
224
254
  {
225
- return uk->stack->depth == 0;
255
+ return uk->stack.depth == 0;
226
256
  }
227
257
 
228
258
  #ifdef USE_CASE_RANGE
@@ -241,16 +271,29 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
241
271
 
242
272
  #endif
243
273
 
274
+ union msgpack_buffer_cast_block_t {
275
+ char buffer[8];
276
+ uint8_t u8;
277
+ uint16_t u16;
278
+ uint32_t u32;
279
+ uint64_t u64;
280
+ int8_t i8;
281
+ int16_t i16;
282
+ int32_t i32;
283
+ int64_t i64;
284
+ float f;
285
+ double d;
286
+ };
244
287
 
245
288
  #define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
246
- union msgpack_buffer_cast_block_t* cb = msgpack_buffer_read_cast_block(UNPACKER_BUFFER_(uk), n); \
247
- if(cb == NULL) { \
289
+ union msgpack_buffer_cast_block_t cb; \
290
+ if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
248
291
  return PRIMITIVE_EOF; \
249
292
  }
250
293
 
251
294
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
252
295
  {
253
- if(uk->stack->depth > 0) {
296
+ if(uk->stack.depth > 0) {
254
297
  msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
255
298
  if(top->type == STACK_TYPE_MAP_KEY) {
256
299
  return true;
@@ -305,14 +348,15 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
305
348
  reset_head_byte(uk);
306
349
  uk->reading_raw_remaining = 0;
307
350
 
308
- msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
309
- child_stack->parent = uk->stack;
310
- uk->stack = child_stack;
311
-
312
- obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
351
+ _msgpack_unpacker_stack_push(uk, STACK_TYPE_RECURSIVE, 1, Qnil);
352
+ int raised;
353
+ obj = protected_proc_call(proc, 1, &uk->self, &raised);
354
+ msgpack_unpacker_stack_pop(uk);
313
355
 
314
- uk->stack = child_stack->parent;
315
- _msgpack_unpacker_free_stack(child_stack);
356
+ if (raised) {
357
+ uk->last_object = rb_errinfo();
358
+ return PRIMITIVE_RECURSIVE_RAISED;
359
+ }
316
360
 
317
361
  return object_complete(uk, obj);
318
362
  }
@@ -375,14 +419,14 @@ static int read_primitive(msgpack_unpacker_t* uk)
375
419
  if(count == 0) {
376
420
  return object_complete(uk, rb_ary_new());
377
421
  }
378
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
422
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
379
423
 
380
424
  SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
381
425
  int count = b & 0x0f;
382
426
  if(count == 0) {
383
427
  return object_complete(uk, rb_hash_new());
384
428
  }
385
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
429
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
386
430
 
387
431
  SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
388
432
  switch(b) {
@@ -400,8 +444,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
400
444
  case 0xc7: // ext 8
401
445
  {
402
446
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
403
- uint8_t length = cb->u8;
404
- int ext_type = (signed char) cb->buffer[1];
447
+ uint8_t length = cb.u8;
448
+ int ext_type = (signed char) cb.buffer[1];
405
449
  if(length == 0) {
406
450
  return object_complete_ext(uk, ext_type, Qnil);
407
451
  }
@@ -412,8 +456,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
412
456
  case 0xc8: // ext 16
413
457
  {
414
458
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
415
- uint16_t length = _msgpack_be16(cb->u16);
416
- int ext_type = (signed char) cb->buffer[2];
459
+ uint16_t length = _msgpack_be16(cb.u16);
460
+ int ext_type = (signed char) cb.buffer[2];
417
461
  if(length == 0) {
418
462
  return object_complete_ext(uk, ext_type, Qnil);
419
463
  }
@@ -424,8 +468,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
424
468
  case 0xc9: // ext 32
425
469
  {
426
470
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
427
- uint32_t length = _msgpack_be32(cb->u32);
428
- int ext_type = (signed char) cb->buffer[4];
471
+ uint32_t length = _msgpack_be32(cb.u32);
472
+ int ext_type = (signed char) cb.buffer[4];
429
473
  if(length == 0) {
430
474
  return object_complete_ext(uk, ext_type, Qnil);
431
475
  }
@@ -436,77 +480,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
436
480
  case 0xca: // float
437
481
  {
438
482
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
439
- cb->u32 = _msgpack_be_float(cb->u32);
440
- return object_complete(uk, rb_float_new(cb->f));
483
+ cb.u32 = _msgpack_be_float(cb.u32);
484
+ return object_complete(uk, rb_float_new(cb.f));
441
485
  }
442
486
 
443
487
  case 0xcb: // double
444
488
  {
445
489
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
446
- cb->u64 = _msgpack_be_double(cb->u64);
447
- return object_complete(uk, rb_float_new(cb->d));
490
+ cb.u64 = _msgpack_be_double(cb.u64);
491
+ return object_complete(uk, rb_float_new(cb.d));
448
492
  }
449
493
 
450
494
  case 0xcc: // unsigned int 8
451
495
  {
452
496
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
453
- uint8_t u8 = cb->u8;
497
+ uint8_t u8 = cb.u8;
454
498
  return object_complete(uk, INT2NUM((int)u8));
455
499
  }
456
500
 
457
501
  case 0xcd: // unsigned int 16
458
502
  {
459
503
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
460
- uint16_t u16 = _msgpack_be16(cb->u16);
504
+ uint16_t u16 = _msgpack_be16(cb.u16);
461
505
  return object_complete(uk, INT2NUM((int)u16));
462
506
  }
463
507
 
464
508
  case 0xce: // unsigned int 32
465
509
  {
466
510
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
467
- uint32_t u32 = _msgpack_be32(cb->u32);
511
+ uint32_t u32 = _msgpack_be32(cb.u32);
468
512
  return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
469
513
  }
470
514
 
471
515
  case 0xcf: // unsigned int 64
472
516
  {
473
517
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
474
- uint64_t u64 = _msgpack_be64(cb->u64);
518
+ uint64_t u64 = _msgpack_be64(cb.u64);
475
519
  return object_complete(uk, rb_ull2inum(u64));
476
520
  }
477
521
 
478
522
  case 0xd0: // signed int 8
479
523
  {
480
524
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
481
- int8_t i8 = cb->i8;
525
+ int8_t i8 = cb.i8;
482
526
  return object_complete(uk, INT2NUM((int)i8));
483
527
  }
484
528
 
485
529
  case 0xd1: // signed int 16
486
530
  {
487
531
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
488
- int16_t i16 = _msgpack_be16(cb->i16);
532
+ int16_t i16 = _msgpack_be16(cb.i16);
489
533
  return object_complete(uk, INT2NUM((int)i16));
490
534
  }
491
535
 
492
536
  case 0xd2: // signed int 32
493
537
  {
494
538
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
495
- int32_t i32 = _msgpack_be32(cb->i32);
539
+ int32_t i32 = _msgpack_be32(cb.i32);
496
540
  return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
497
541
  }
498
542
 
499
543
  case 0xd3: // signed int 64
500
544
  {
501
545
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
502
- int64_t i64 = _msgpack_be64(cb->i64);
546
+ int64_t i64 = _msgpack_be64(cb.i64);
503
547
  return object_complete(uk, rb_ll2inum(i64));
504
548
  }
505
549
 
506
550
  case 0xd4: // fixext 1
507
551
  {
508
552
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
509
- int ext_type = cb->i8;
553
+ int ext_type = cb.i8;
510
554
  uk->reading_raw_remaining = 1;
511
555
  return read_raw_body_begin(uk, ext_type);
512
556
  }
@@ -514,7 +558,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
514
558
  case 0xd5: // fixext 2
515
559
  {
516
560
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
517
- int ext_type = cb->i8;
561
+ int ext_type = cb.i8;
518
562
  uk->reading_raw_remaining = 2;
519
563
  return read_raw_body_begin(uk, ext_type);
520
564
  }
@@ -522,7 +566,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
522
566
  case 0xd6: // fixext 4
523
567
  {
524
568
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
525
- int ext_type = cb->i8;
569
+ int ext_type = cb.i8;
526
570
  uk->reading_raw_remaining = 4;
527
571
  return read_raw_body_begin(uk, ext_type);
528
572
  }
@@ -530,7 +574,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
530
574
  case 0xd7: // fixext 8
531
575
  {
532
576
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
533
- int ext_type = cb->i8;
577
+ int ext_type = cb.i8;
534
578
  uk->reading_raw_remaining = 8;
535
579
  return read_raw_body_begin(uk, ext_type);
536
580
  }
@@ -538,7 +582,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
538
582
  case 0xd8: // fixext 16
539
583
  {
540
584
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
541
- int ext_type = cb->i8;
585
+ int ext_type = cb.i8;
542
586
  uk->reading_raw_remaining = 16;
543
587
  return read_raw_body_begin(uk, ext_type);
544
588
  }
@@ -547,7 +591,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
547
591
  case 0xd9: // raw 8 / str 8
548
592
  {
549
593
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
550
- uint8_t count = cb->u8;
594
+ uint8_t count = cb.u8;
551
595
  /* read_raw_body_begin sets uk->reading_raw */
552
596
  uk->reading_raw_remaining = count;
553
597
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -556,7 +600,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
556
600
  case 0xda: // raw 16 / str 16
557
601
  {
558
602
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
559
- uint16_t count = _msgpack_be16(cb->u16);
603
+ uint16_t count = _msgpack_be16(cb.u16);
560
604
  /* read_raw_body_begin sets uk->reading_raw */
561
605
  uk->reading_raw_remaining = count;
562
606
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -565,7 +609,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
565
609
  case 0xdb: // raw 32 / str 32
566
610
  {
567
611
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
568
- uint32_t count = _msgpack_be32(cb->u32);
612
+ uint32_t count = _msgpack_be32(cb.u32);
569
613
  /* read_raw_body_begin sets uk->reading_raw */
570
614
  uk->reading_raw_remaining = count;
571
615
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -574,7 +618,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
574
618
  case 0xc4: // bin 8
575
619
  {
576
620
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
577
- uint8_t count = cb->u8;
621
+ uint8_t count = cb.u8;
578
622
  /* read_raw_body_begin sets uk->reading_raw */
579
623
  uk->reading_raw_remaining = count;
580
624
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -583,7 +627,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
583
627
  case 0xc5: // bin 16
584
628
  {
585
629
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
586
- uint16_t count = _msgpack_be16(cb->u16);
630
+ uint16_t count = _msgpack_be16(cb.u16);
587
631
  /* read_raw_body_begin sets uk->reading_raw */
588
632
  uk->reading_raw_remaining = count;
589
633
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -592,7 +636,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
592
636
  case 0xc6: // bin 32
593
637
  {
594
638
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
595
- uint32_t count = _msgpack_be32(cb->u32);
639
+ uint32_t count = _msgpack_be32(cb.u32);
596
640
  /* read_raw_body_begin sets uk->reading_raw */
597
641
  uk->reading_raw_remaining = count;
598
642
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -601,41 +645,41 @@ static int read_primitive(msgpack_unpacker_t* uk)
601
645
  case 0xdc: // array 16
602
646
  {
603
647
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
604
- uint16_t count = _msgpack_be16(cb->u16);
648
+ uint16_t count = _msgpack_be16(cb.u16);
605
649
  if(count == 0) {
606
650
  return object_complete(uk, rb_ary_new());
607
651
  }
608
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
652
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
609
653
  }
610
654
 
611
655
  case 0xdd: // array 32
612
656
  {
613
657
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
614
- uint32_t count = _msgpack_be32(cb->u32);
658
+ uint32_t count = _msgpack_be32(cb.u32);
615
659
  if(count == 0) {
616
660
  return object_complete(uk, rb_ary_new());
617
661
  }
618
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
662
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
619
663
  }
620
664
 
621
665
  case 0xde: // map 16
622
666
  {
623
667
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
624
- uint16_t count = _msgpack_be16(cb->u16);
668
+ uint16_t count = _msgpack_be16(cb.u16);
625
669
  if(count == 0) {
626
670
  return object_complete(uk, rb_hash_new());
627
671
  }
628
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
672
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
629
673
  }
630
674
 
631
675
  case 0xdf: // map 32
632
676
  {
633
677
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
634
- uint32_t count = _msgpack_be32(cb->u32);
678
+ uint32_t count = _msgpack_be32(cb.u32);
635
679
  if(count == 0) {
636
680
  return object_complete(uk, rb_hash_new());
637
681
  }
638
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
682
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
639
683
  }
640
684
 
641
685
  default:
@@ -661,12 +705,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
661
705
  } else if(b == 0xdc) {
662
706
  /* array 16 */
663
707
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
664
- *result_size = _msgpack_be16(cb->u16);
708
+ *result_size = _msgpack_be16(cb.u16);
665
709
 
666
710
  } else if(b == 0xdd) {
667
711
  /* array 32 */
668
712
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
669
- *result_size = _msgpack_be32(cb->u32);
713
+ *result_size = _msgpack_be32(cb.u32);
670
714
 
671
715
  } else {
672
716
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -689,12 +733,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
689
733
  } else if(b == 0xde) {
690
734
  /* map 16 */
691
735
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
692
- *result_size = _msgpack_be16(cb->u16);
736
+ *result_size = _msgpack_be16(cb.u16);
693
737
 
694
738
  } else if(b == 0xdf) {
695
739
  /* map 32 */
696
740
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
697
- *result_size = _msgpack_be32(cb->u32);
741
+ *result_size = _msgpack_be32(cb.u32);
698
742
 
699
743
  } else {
700
744
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -740,6 +784,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
740
784
  }
741
785
  top->type = STACK_TYPE_MAP_KEY;
742
786
  break;
787
+ case STACK_TYPE_RECURSIVE:
788
+ return PRIMITIVE_OBJECT_COMPLETE;
743
789
  }
744
790
  size_t count = --top->count;
745
791
 
@@ -31,6 +31,7 @@ enum stack_type_t {
31
31
  STACK_TYPE_ARRAY,
32
32
  STACK_TYPE_MAP_KEY,
33
33
  STACK_TYPE_MAP_VALUE,
34
+ STACK_TYPE_RECURSIVE,
34
35
  };
35
36
 
36
37
  typedef struct {
@@ -44,31 +45,31 @@ struct msgpack_unpacker_stack_t {
44
45
  size_t depth;
45
46
  size_t capacity;
46
47
  msgpack_unpacker_stack_entry_t *data;
47
- msgpack_unpacker_stack_t *parent;
48
48
  };
49
49
 
50
50
  struct msgpack_unpacker_t {
51
51
  msgpack_buffer_t buffer;
52
- msgpack_unpacker_stack_t *stack;
53
- unsigned int head_byte;
52
+ msgpack_unpacker_stack_t stack;
54
53
 
55
54
  VALUE self;
56
55
  VALUE last_object;
57
56
 
58
57
  VALUE reading_raw;
59
58
  size_t reading_raw_remaining;
60
- int reading_raw_type;
61
59
 
62
60
  VALUE buffer_ref;
63
61
 
64
62
  msgpack_unpacker_ext_registry_t *ext_registry;
65
63
 
64
+ int reading_raw_type;
65
+ unsigned int head_byte;
66
+
66
67
  /* options */
68
+ int symbol_ext_type;
67
69
  bool symbolize_keys;
68
70
  bool freeze;
69
71
  bool allow_unknown_ext;
70
72
  bool optimized_symbol_ext_type;
71
- int symbol_ext_type;
72
73
  };
73
74
 
74
75
  #define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
@@ -119,6 +120,7 @@ static inline void msgpack_unpacker_set_allow_unknown_ext(msgpack_unpacker_t* uk
119
120
  #define PRIMITIVE_STACK_TOO_DEEP -3
120
121
  #define PRIMITIVE_UNEXPECTED_TYPE -4
121
122
  #define PRIMITIVE_UNEXPECTED_EXT_TYPE -5
123
+ #define PRIMITIVE_RECURSIVE_RAISED -6
122
124
 
123
125
  int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth);
124
126
 
@@ -58,14 +58,17 @@ static void Unpacker_mark(void *ptr)
58
58
 
59
59
  static size_t Unpacker_memsize(const void *ptr)
60
60
  {
61
+ const msgpack_unpacker_t* uk = ptr;
62
+
61
63
  size_t total_size = sizeof(msgpack_unpacker_t);
62
64
 
63
- const msgpack_unpacker_t* uk = ptr;
64
65
  if (uk->ext_registry) {
65
66
  total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
66
67
  }
67
68
 
68
- total_size += (uk->stack->depth + 1) * sizeof(msgpack_unpacker_stack_t);
69
+ if (uk->stack.data) {
70
+ total_size += (uk->stack.depth + 1) * sizeof(msgpack_unpacker_stack_t);
71
+ }
69
72
 
70
73
  return total_size + msgpack_buffer_memsize(&uk->buffer);
71
74
  }
@@ -156,20 +159,28 @@ static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
156
159
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
157
160
  }
158
161
 
159
- NORETURN(static void raise_unpacker_error(int r))
162
+ NORETURN(static void raise_unpacker_error(msgpack_unpacker_t *uk, int r))
160
163
  {
164
+ uk->stack.depth = 0;
161
165
  switch(r) {
162
166
  case PRIMITIVE_EOF:
163
167
  rb_raise(rb_eEOFError, "end of buffer reached");
168
+ break;
164
169
  case PRIMITIVE_INVALID_BYTE:
165
170
  rb_raise(eMalformedFormatError, "invalid byte");
171
+ break;
166
172
  case PRIMITIVE_STACK_TOO_DEEP:
167
173
  rb_raise(eStackError, "stack level too deep");
174
+ break;
168
175
  case PRIMITIVE_UNEXPECTED_TYPE:
169
176
  rb_raise(eUnexpectedTypeError, "unexpected type");
177
+ break;
170
178
  case PRIMITIVE_UNEXPECTED_EXT_TYPE:
171
- // rb_bug("unexpected extension type");
172
179
  rb_raise(eUnknownExtTypeError, "unexpected extension type");
180
+ break;
181
+ case PRIMITIVE_RECURSIVE_RAISED:
182
+ rb_exc_raise(msgpack_unpacker_get_last_object(uk));
183
+ break;
173
184
  default:
174
185
  rb_raise(eUnpackError, "logically unknown error %d", r);
175
186
  }
@@ -190,7 +201,7 @@ static VALUE Unpacker_read(VALUE self)
190
201
 
191
202
  int r = msgpack_unpacker_read(uk, 0);
192
203
  if(r < 0) {
193
- raise_unpacker_error(r);
204
+ raise_unpacker_error(uk, r);
194
205
  }
195
206
 
196
207
  return msgpack_unpacker_get_last_object(uk);
@@ -202,7 +213,7 @@ static VALUE Unpacker_skip(VALUE self)
202
213
 
203
214
  int r = msgpack_unpacker_skip(uk, 0);
204
215
  if(r < 0) {
205
- raise_unpacker_error(r);
216
+ raise_unpacker_error(uk, r);
206
217
  }
207
218
 
208
219
  return Qnil;
@@ -214,7 +225,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
214
225
 
215
226
  int r = msgpack_unpacker_skip_nil(uk);
216
227
  if(r < 0) {
217
- raise_unpacker_error(r);
228
+ raise_unpacker_error(uk, r);
218
229
  }
219
230
 
220
231
  if(r) {
@@ -230,7 +241,7 @@ static VALUE Unpacker_read_array_header(VALUE self)
230
241
  uint32_t size;
231
242
  int r = msgpack_unpacker_read_array_header(uk, &size);
232
243
  if(r < 0) {
233
- raise_unpacker_error(r);
244
+ raise_unpacker_error(uk, r);
234
245
  }
235
246
 
236
247
  return ULONG2NUM(size); // long at least 32 bits
@@ -243,7 +254,7 @@ static VALUE Unpacker_read_map_header(VALUE self)
243
254
  uint32_t size;
244
255
  int r = msgpack_unpacker_read_map_header(uk, &size);
245
256
  if(r < 0) {
246
- raise_unpacker_error((int)r);
257
+ raise_unpacker_error(uk, r);
247
258
  }
248
259
 
249
260
  return ULONG2NUM(size); // long at least 32 bits
@@ -270,7 +281,7 @@ static VALUE Unpacker_each_impl(VALUE self)
270
281
  if(r == PRIMITIVE_EOF) {
271
282
  return Qnil;
272
283
  }
273
- raise_unpacker_error(r);
284
+ raise_unpacker_error(uk, r);
274
285
  }
275
286
  VALUE v = msgpack_unpacker_get_last_object(uk);
276
287
  #ifdef JRUBY
@@ -369,7 +380,7 @@ static VALUE Unpacker_full_unpack(VALUE self)
369
380
 
370
381
  int r = msgpack_unpacker_read(uk, 0);
371
382
  if(r < 0) {
372
- raise_unpacker_error(r);
383
+ raise_unpacker_error(uk, r);
373
384
  }
374
385
 
375
386
  /* raise if extra bytes follow */
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.7.2"
2
+ VERSION = "1.7.4"
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.
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.7.2
4
+ version: 1.7.4
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: 2023-07-18 00:00:00.000000000 Z
13
+ date: 2024-11-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -208,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  - !ruby/object:Gem::Version
209
209
  version: '0'
210
210
  requirements: []
211
- rubygems_version: 3.3.7
211
+ rubygems_version: 3.5.11
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: MessagePack, a binary-based efficient data interchange format.