summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-pack
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-01-28 21:40:38 +0900
committerdearblue <[email protected]>2021-01-29 22:27:36 +0900
commit9c36499e311a62f92127829d96f7eb638b49001f (patch)
tree6ac71c4ba5e8131f1cfb874796d1a7a61b24809d /mrbgems/mruby-pack
parent825241205f07d387ea2490e43de58658cbc35ab6 (diff)
downloadmruby-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')
-rw-r--r--mrbgems/mruby-pack/src/pack.c15
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;
}