msgpack 1.7.3 → 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: fe6adcd787be2f8c3e9459d46c3baa4ad81c5b08bdcaeb9bfec9a80c9a4540c6
4
- data.tar.gz: 76d6be5a37a2b6e225ad995e6b0f670d0489839a98b678c9332837bd082e7d7e
3
+ metadata.gz: fa4847fba5fd9dfbed01473471b038a0b06a0ee131395c9724a5bceeab7e9823
4
+ data.tar.gz: e80a7dfd7c92a1eaa76b3604027094f1dff4d65ba46babcf739019423dd37fad
5
5
  SHA512:
6
- metadata.gz: 36b0e748e7b54baad2ecef8c1c071a82cf3e6bd26540fd433a3c71f1e77afe341188594a26bfed817f84af10ef4f613ded14fc0a8448a77dc4978683cf7c35d1
7
- data.tar.gz: 45ce3770a12b3580945ba3dd42d40ab8ba24a167f675f71d57bb42af6cf4ab204d7cc7960925ea78556988f523886fd92b431789a174e0529143ab0908d52418
6
+ metadata.gz: 8f6cbd005ef5d490a2d99ccf45208984a6450ed797f8835884ff758bf71e41e02e397dc174801972386728216f147d09d375763fcc4d9eb853b99520ea40eb19
7
+ data.tar.gz: e0f6aafd4c147075fe7dcde2f54775cbd84b0d4b8c85b660f2569f4f790dfec979ecbef3da032e8a236558678a54dd8fa1e7ce5346c6cb042936d94037b1ec80
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ 2024-11-11 1.7.4
2
+
3
+ * Fixed a potental memory leak when recursive unpacker raise.
4
+
1
5
  2024-10-03 1.7.3
2
6
 
3
7
  * Limit initial containers pre-allocation to `SHRT_MAX` (32k) entries.
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;
@@ -26,6 +26,27 @@
26
26
  #define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
27
27
  #endif
28
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
+
29
50
  static int RAW_TYPE_STRING = 256;
30
51
  static int RAW_TYPE_BINARY = 257;
31
52
  static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
@@ -58,12 +79,9 @@ void msgpack_unpacker_static_destroy(void)
58
79
 
59
80
  #define HEAD_BYTE_REQUIRED 0xc1
60
81
 
61
- static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
62
- msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
82
+ static inline void _msgpack_unpacker_stack_init(msgpack_unpacker_stack_t *stack) {
63
83
  stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
64
84
  stack->data = msgpack_rmem_alloc(&s_stack_rmem);
65
- /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
66
- return stack;
67
85
  }
68
86
 
69
87
  void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
@@ -75,32 +93,32 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
75
93
  uk->last_object = Qnil;
76
94
  uk->reading_raw = Qnil;
77
95
 
78
- uk->stack = _msgpack_unpacker_new_stack();
96
+ _msgpack_unpacker_stack_init(&uk->stack);
79
97
  }
80
98
 
81
99
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
82
100
  if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
83
101
  rb_bug("Failed to free an rmem pointer, memory leak?");
84
102
  }
85
- xfree(stack);
103
+ stack->data = NULL;
104
+ stack->depth = 0;
86
105
  }
87
106
 
88
107
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
89
108
  {
90
- _msgpack_unpacker_free_stack(uk->stack);
109
+ _msgpack_unpacker_free_stack(&uk->stack);
91
110
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
92
111
  }
93
112
 
94
113
  void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
95
114
  {
96
- while (stack) {
115
+ if (stack->data) {
97
116
  msgpack_unpacker_stack_entry_t* s = stack->data;
98
117
  msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
99
118
  for(; s < send; s++) {
100
119
  rb_gc_mark(s->object);
101
120
  rb_gc_mark(s->key);
102
121
  }
103
- stack = stack->parent;
104
122
  }
105
123
  }
106
124
 
@@ -108,7 +126,7 @@ void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
108
126
  {
109
127
  rb_gc_mark(uk->last_object);
110
128
  rb_gc_mark(uk->reading_raw);
111
- msgpack_unpacker_mark_stack(uk->stack);
129
+ msgpack_unpacker_mark_stack(&uk->stack);
112
130
  /* See MessagePack_Buffer_wrap */
113
131
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
114
132
  rb_gc_mark(uk->buffer_ref);
@@ -121,8 +139,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
121
139
 
122
140
  uk->head_byte = HEAD_BYTE_REQUIRED;
123
141
 
124
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
125
- uk->stack->depth = 0;
142
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack.depth);*/
143
+ uk->stack.depth = 0;
126
144
  uk->last_object = Qnil;
127
145
  uk->reading_raw = Qnil;
128
146
  uk->reading_raw_remaining = 0;
@@ -186,7 +204,12 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
186
204
  if(proc != Qnil) {
187
205
  VALUE obj;
188
206
  VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
189
- 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
+ }
190
213
  return object_complete(uk, obj);
191
214
  }
192
215
 
@@ -201,35 +224,35 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
201
224
  /* stack funcs */
202
225
  static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
203
226
  {
204
- return &uk->stack->data[uk->stack->depth-1];
227
+ return &uk->stack.data[uk->stack.depth-1];
205
228
  }
206
229
 
207
230
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
208
231
  {
209
232
  reset_head_byte(uk);
210
233
 
211
- if(uk->stack->capacity - uk->stack->depth <= 0) {
234
+ if(uk->stack.capacity - uk->stack.depth <= 0) {
212
235
  return PRIMITIVE_STACK_TOO_DEEP;
213
236
  }
214
237
 
215
- 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];
216
239
  next->count = count;
217
240
  next->type = type;
218
241
  next->object = object;
219
242
  next->key = Qnil;
220
243
 
221
- uk->stack->depth++;
244
+ uk->stack.depth++;
222
245
  return PRIMITIVE_CONTAINER_START;
223
246
  }
224
247
 
225
- static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
248
+ static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
226
249
  {
227
- return --uk->stack->depth;
250
+ return --uk->stack.depth;
228
251
  }
229
252
 
230
253
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
231
254
  {
232
- return uk->stack->depth == 0;
255
+ return uk->stack.depth == 0;
233
256
  }
234
257
 
235
258
  #ifdef USE_CASE_RANGE
@@ -248,16 +271,29 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
248
271
 
249
272
  #endif
250
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
+ };
251
287
 
252
288
  #define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
253
- union msgpack_buffer_cast_block_t* cb = msgpack_buffer_read_cast_block(UNPACKER_BUFFER_(uk), n); \
254
- if(cb == NULL) { \
289
+ union msgpack_buffer_cast_block_t cb; \
290
+ if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
255
291
  return PRIMITIVE_EOF; \
256
292
  }
257
293
 
258
294
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
259
295
  {
260
- if(uk->stack->depth > 0) {
296
+ if(uk->stack.depth > 0) {
261
297
  msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
262
298
  if(top->type == STACK_TYPE_MAP_KEY) {
263
299
  return true;
@@ -312,14 +348,15 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
312
348
  reset_head_byte(uk);
313
349
  uk->reading_raw_remaining = 0;
314
350
 
315
- msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
316
- child_stack->parent = uk->stack;
317
- uk->stack = child_stack;
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);
318
355
 
319
- obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
320
-
321
- uk->stack = child_stack->parent;
322
- _msgpack_unpacker_free_stack(child_stack);
356
+ if (raised) {
357
+ uk->last_object = rb_errinfo();
358
+ return PRIMITIVE_RECURSIVE_RAISED;
359
+ }
323
360
 
324
361
  return object_complete(uk, obj);
325
362
  }
@@ -407,8 +444,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
407
444
  case 0xc7: // ext 8
408
445
  {
409
446
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
410
- uint8_t length = cb->u8;
411
- int ext_type = (signed char) cb->buffer[1];
447
+ uint8_t length = cb.u8;
448
+ int ext_type = (signed char) cb.buffer[1];
412
449
  if(length == 0) {
413
450
  return object_complete_ext(uk, ext_type, Qnil);
414
451
  }
@@ -419,8 +456,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
419
456
  case 0xc8: // ext 16
420
457
  {
421
458
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
422
- uint16_t length = _msgpack_be16(cb->u16);
423
- 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];
424
461
  if(length == 0) {
425
462
  return object_complete_ext(uk, ext_type, Qnil);
426
463
  }
@@ -431,8 +468,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
431
468
  case 0xc9: // ext 32
432
469
  {
433
470
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
434
- uint32_t length = _msgpack_be32(cb->u32);
435
- 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];
436
473
  if(length == 0) {
437
474
  return object_complete_ext(uk, ext_type, Qnil);
438
475
  }
@@ -443,77 +480,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
443
480
  case 0xca: // float
444
481
  {
445
482
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
446
- cb->u32 = _msgpack_be_float(cb->u32);
447
- 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));
448
485
  }
449
486
 
450
487
  case 0xcb: // double
451
488
  {
452
489
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
453
- cb->u64 = _msgpack_be_double(cb->u64);
454
- 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));
455
492
  }
456
493
 
457
494
  case 0xcc: // unsigned int 8
458
495
  {
459
496
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
460
- uint8_t u8 = cb->u8;
497
+ uint8_t u8 = cb.u8;
461
498
  return object_complete(uk, INT2NUM((int)u8));
462
499
  }
463
500
 
464
501
  case 0xcd: // unsigned int 16
465
502
  {
466
503
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
467
- uint16_t u16 = _msgpack_be16(cb->u16);
504
+ uint16_t u16 = _msgpack_be16(cb.u16);
468
505
  return object_complete(uk, INT2NUM((int)u16));
469
506
  }
470
507
 
471
508
  case 0xce: // unsigned int 32
472
509
  {
473
510
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
474
- uint32_t u32 = _msgpack_be32(cb->u32);
511
+ uint32_t u32 = _msgpack_be32(cb.u32);
475
512
  return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
476
513
  }
477
514
 
478
515
  case 0xcf: // unsigned int 64
479
516
  {
480
517
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
481
- uint64_t u64 = _msgpack_be64(cb->u64);
518
+ uint64_t u64 = _msgpack_be64(cb.u64);
482
519
  return object_complete(uk, rb_ull2inum(u64));
483
520
  }
484
521
 
485
522
  case 0xd0: // signed int 8
486
523
  {
487
524
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
488
- int8_t i8 = cb->i8;
525
+ int8_t i8 = cb.i8;
489
526
  return object_complete(uk, INT2NUM((int)i8));
490
527
  }
491
528
 
492
529
  case 0xd1: // signed int 16
493
530
  {
494
531
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
495
- int16_t i16 = _msgpack_be16(cb->i16);
532
+ int16_t i16 = _msgpack_be16(cb.i16);
496
533
  return object_complete(uk, INT2NUM((int)i16));
497
534
  }
498
535
 
499
536
  case 0xd2: // signed int 32
500
537
  {
501
538
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
502
- int32_t i32 = _msgpack_be32(cb->i32);
539
+ int32_t i32 = _msgpack_be32(cb.i32);
503
540
  return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
504
541
  }
505
542
 
506
543
  case 0xd3: // signed int 64
507
544
  {
508
545
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
509
- int64_t i64 = _msgpack_be64(cb->i64);
546
+ int64_t i64 = _msgpack_be64(cb.i64);
510
547
  return object_complete(uk, rb_ll2inum(i64));
511
548
  }
512
549
 
513
550
  case 0xd4: // fixext 1
514
551
  {
515
552
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
516
- int ext_type = cb->i8;
553
+ int ext_type = cb.i8;
517
554
  uk->reading_raw_remaining = 1;
518
555
  return read_raw_body_begin(uk, ext_type);
519
556
  }
@@ -521,7 +558,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
521
558
  case 0xd5: // fixext 2
522
559
  {
523
560
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
524
- int ext_type = cb->i8;
561
+ int ext_type = cb.i8;
525
562
  uk->reading_raw_remaining = 2;
526
563
  return read_raw_body_begin(uk, ext_type);
527
564
  }
@@ -529,7 +566,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
529
566
  case 0xd6: // fixext 4
530
567
  {
531
568
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
532
- int ext_type = cb->i8;
569
+ int ext_type = cb.i8;
533
570
  uk->reading_raw_remaining = 4;
534
571
  return read_raw_body_begin(uk, ext_type);
535
572
  }
@@ -537,7 +574,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
537
574
  case 0xd7: // fixext 8
538
575
  {
539
576
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
540
- int ext_type = cb->i8;
577
+ int ext_type = cb.i8;
541
578
  uk->reading_raw_remaining = 8;
542
579
  return read_raw_body_begin(uk, ext_type);
543
580
  }
@@ -545,7 +582,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
545
582
  case 0xd8: // fixext 16
546
583
  {
547
584
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
548
- int ext_type = cb->i8;
585
+ int ext_type = cb.i8;
549
586
  uk->reading_raw_remaining = 16;
550
587
  return read_raw_body_begin(uk, ext_type);
551
588
  }
@@ -554,7 +591,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
554
591
  case 0xd9: // raw 8 / str 8
555
592
  {
556
593
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
557
- uint8_t count = cb->u8;
594
+ uint8_t count = cb.u8;
558
595
  /* read_raw_body_begin sets uk->reading_raw */
559
596
  uk->reading_raw_remaining = count;
560
597
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -563,7 +600,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
563
600
  case 0xda: // raw 16 / str 16
564
601
  {
565
602
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
566
- uint16_t count = _msgpack_be16(cb->u16);
603
+ uint16_t count = _msgpack_be16(cb.u16);
567
604
  /* read_raw_body_begin sets uk->reading_raw */
568
605
  uk->reading_raw_remaining = count;
569
606
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -572,7 +609,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
572
609
  case 0xdb: // raw 32 / str 32
573
610
  {
574
611
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
575
- uint32_t count = _msgpack_be32(cb->u32);
612
+ uint32_t count = _msgpack_be32(cb.u32);
576
613
  /* read_raw_body_begin sets uk->reading_raw */
577
614
  uk->reading_raw_remaining = count;
578
615
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -581,7 +618,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
581
618
  case 0xc4: // bin 8
582
619
  {
583
620
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
584
- uint8_t count = cb->u8;
621
+ uint8_t count = cb.u8;
585
622
  /* read_raw_body_begin sets uk->reading_raw */
586
623
  uk->reading_raw_remaining = count;
587
624
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -590,7 +627,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
590
627
  case 0xc5: // bin 16
591
628
  {
592
629
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
593
- uint16_t count = _msgpack_be16(cb->u16);
630
+ uint16_t count = _msgpack_be16(cb.u16);
594
631
  /* read_raw_body_begin sets uk->reading_raw */
595
632
  uk->reading_raw_remaining = count;
596
633
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -599,7 +636,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
599
636
  case 0xc6: // bin 32
600
637
  {
601
638
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
602
- uint32_t count = _msgpack_be32(cb->u32);
639
+ uint32_t count = _msgpack_be32(cb.u32);
603
640
  /* read_raw_body_begin sets uk->reading_raw */
604
641
  uk->reading_raw_remaining = count;
605
642
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -608,7 +645,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
608
645
  case 0xdc: // array 16
609
646
  {
610
647
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
611
- uint16_t count = _msgpack_be16(cb->u16);
648
+ uint16_t count = _msgpack_be16(cb.u16);
612
649
  if(count == 0) {
613
650
  return object_complete(uk, rb_ary_new());
614
651
  }
@@ -618,7 +655,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
618
655
  case 0xdd: // array 32
619
656
  {
620
657
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
621
- uint32_t count = _msgpack_be32(cb->u32);
658
+ uint32_t count = _msgpack_be32(cb.u32);
622
659
  if(count == 0) {
623
660
  return object_complete(uk, rb_ary_new());
624
661
  }
@@ -628,7 +665,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
628
665
  case 0xde: // map 16
629
666
  {
630
667
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
631
- uint16_t count = _msgpack_be16(cb->u16);
668
+ uint16_t count = _msgpack_be16(cb.u16);
632
669
  if(count == 0) {
633
670
  return object_complete(uk, rb_hash_new());
634
671
  }
@@ -638,7 +675,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
638
675
  case 0xdf: // map 32
639
676
  {
640
677
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
641
- uint32_t count = _msgpack_be32(cb->u32);
678
+ uint32_t count = _msgpack_be32(cb.u32);
642
679
  if(count == 0) {
643
680
  return object_complete(uk, rb_hash_new());
644
681
  }
@@ -668,12 +705,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
668
705
  } else if(b == 0xdc) {
669
706
  /* array 16 */
670
707
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
671
- *result_size = _msgpack_be16(cb->u16);
708
+ *result_size = _msgpack_be16(cb.u16);
672
709
 
673
710
  } else if(b == 0xdd) {
674
711
  /* array 32 */
675
712
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
676
- *result_size = _msgpack_be32(cb->u32);
713
+ *result_size = _msgpack_be32(cb.u32);
677
714
 
678
715
  } else {
679
716
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -696,12 +733,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
696
733
  } else if(b == 0xde) {
697
734
  /* map 16 */
698
735
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
699
- *result_size = _msgpack_be16(cb->u16);
736
+ *result_size = _msgpack_be16(cb.u16);
700
737
 
701
738
  } else if(b == 0xdf) {
702
739
  /* map 32 */
703
740
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
704
- *result_size = _msgpack_be32(cb->u32);
741
+ *result_size = _msgpack_be32(cb.u32);
705
742
 
706
743
  } else {
707
744
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -747,6 +784,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
747
784
  }
748
785
  top->type = STACK_TYPE_MAP_KEY;
749
786
  break;
787
+ case STACK_TYPE_RECURSIVE:
788
+ return PRIMITIVE_OBJECT_COMPLETE;
750
789
  }
751
790
  size_t count = --top->count;
752
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.3"
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.3
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: 2024-10-04 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