diff options
| author | dearblue <[email protected]> | 2021-01-28 21:40:38 +0900 |
|---|---|---|
| committer | dearblue <[email protected]> | 2021-01-29 22:27:36 +0900 |
| commit | 9c36499e311a62f92127829d96f7eb638b49001f (patch) | |
| tree | 6ac71c4ba5e8131f1cfb874796d1a7a61b24809d /mrbgems/mruby-pack/src | |
| parent | 825241205f07d387ea2490e43de58658cbc35ab6 (diff) | |
| download | mruby-9c36499e311a62f92127829d96f7eb638b49001f.tar.gz mruby-9c36499e311a62f92127829d96f7eb638b49001f.zip | |
Fixed `String#unpack` to handle the highest range of integer values
Previously, problems occurred when the `fixnum` was exceeded.
- 32-bit cpu mode with `MRB_WORD_BOXING` and `MRB_INT32`:
```console
% bin/mruby -e 'p [0x7fffffff].pack("N").unpack("N")'
trace (most recent call last):
-e:1: cannot unpack to Integer: 2147483647 (RangeError)
```
- 64-bit cpu mode with `MRB_WORD_BOXING` and `MRB_INT64`:
```console
% bin/mruby -e 'p [0x7fffffff_ffffffff].pack("q").unpack("q")'
trace (most recent call last):
-e:1: cannot unpack to Integer: 9223372036854775807 (RangeError)
```
Diffstat (limited to 'mrbgems/mruby-pack/src')
| -rw-r--r-- | mrbgems/mruby-pack/src/pack.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 014679a5d..58c2a3be7 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -15,6 +15,9 @@ #include <errno.h> #include <string.h> +#define INT_OVERFLOW_P(n) ((n) < MRB_INT_MIN || (n) > MRB_INT_MAX) +#define UINT_OVERFLOW_P(n) ((n) > MRB_INT_MAX) + struct tmpl { mrb_value str; int idx; @@ -258,7 +261,7 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un if (flags & PACK_FLAG_SIGNED) { int32_t sl = ul; #ifndef MRB_INT64 - if (!FIXABLE(sl)) { + if (INT_OVERFLOW_P(sl)) { i32tostr(msg, sizeof(msg), sl); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); } @@ -266,14 +269,14 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un n = sl; } else { #ifndef MRB_INT64 - if (!POSFIXABLE(ul)) { + if (UINT_OVERFLOW_P(ul)) { u32tostr(msg, sizeof(msg), ul); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); } #endif n = ul; } - mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); + mrb_ary_push(mrb, ary, mrb_int_value(mrb, n)); return 4; } @@ -379,19 +382,19 @@ unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un } if (flags & PACK_FLAG_SIGNED) { int64_t sll = ull; - if (!FIXABLE(sll)) { + if (INT_OVERFLOW_P(sll)) { i64tostr(msg, sizeof(msg), sll); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); } n = (mrb_int)sll; } else { - if (!POSFIXABLE(ull)) { + if (UINT_OVERFLOW_P(ull)) { u64tostr(msg, sizeof(msg), ull); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); } n = (mrb_int)ull; } - mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); + mrb_ary_push(mrb, ary, mrb_int_value(mrb, n)); return 8; } |
