msgpack 1.7.2 → 1.7.4

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: 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.
OSZAR »