aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-09-15 01:09:10 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-12-16 16:49:16 +0000
commit5b18872c7a4df0b9a01af5c86ee6969018985e69 (patch)
treed7846299bd1759582a6a844f15c1a26c5999e8c6
parent05e4733b0075191587c38810f5e85d46f6ebaebb (diff)
downloadruby-5b18872c7a4df0b9a01af5c86ee6969018985e69.tar.gz
pack.c: avoid signed integer overflowwip-topic/signed-integer-overflow
Avoid 'x > y * n' pattern because 'y * n' may cause a signed integer overflow.
-rw-r--r--pack.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/pack.c b/pack.c
index a8339c7219..3423bfc135 100644
--- a/pack.c
+++ b/pack.c
@@ -1191,8 +1191,11 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
int bits;
long i;
- if (p[-1] == '*' || len > (send - s) * 8)
+ if (p[-1] == '*' || len / 8 >= send - s) {
+ if (send - s > LONG_MAX / 8)
+ rb_raise(rb_eRuntimeError, "string size too big");
len = (send - s) * 8;
+ }
bits = 0;
UNPACK_PUSH(bitstr = rb_usascii_str_new(0, len));
t = RSTRING_PTR(bitstr);
@@ -1211,8 +1214,11 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
int bits;
long i;
- if (p[-1] == '*' || len > (send - s) * 8)
+ if (p[-1] == '*' || len / 8 >= send - s) {
+ if (send - s > LONG_MAX / 8)
+ rb_raise(rb_eRuntimeError, "string size too big");
len = (send - s) * 8;
+ }
bits = 0;
UNPACK_PUSH(bitstr = rb_usascii_str_new(0, len));
t = RSTRING_PTR(bitstr);
@@ -1231,8 +1237,11 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
int bits;
long i;
- if (p[-1] == '*' || len > (send - s) * 2)
+ if (p[-1] == '*' || len / 2 >= send - s) {
+ if (send - s > LONG_MAX / 2)
+ rb_raise(rb_eRuntimeError, "string size too big");
len = (send - s) * 2;
+ }
bits = 0;
UNPACK_PUSH(bitstr = rb_usascii_str_new(0, len));
t = RSTRING_PTR(bitstr);
@@ -1253,8 +1262,11 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
int bits;
long i;
- if (p[-1] == '*' || len > (send - s) * 2)
+ if (p[-1] == '*' || len / 2 >= send - s) {
+ if (send - s > LONG_MAX / 2)
+ rb_raise(rb_eRuntimeError, "string size too big");
len = (send - s) * 2;
+ }
bits = 0;
UNPACK_PUSH(bitstr = rb_usascii_str_new(0, len));
t = RSTRING_PTR(bitstr);
@@ -1522,7 +1534,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
case 'm':
{
- VALUE buf = infected_str_new(0, (send - s + 3)*3/4, str); /* +3 is for skipping paddings */
+ VALUE buf = infected_str_new(0, (send - s + 3) / 4 * 3, str); /* +3 is for skipping paddings */
char *ptr = RSTRING_PTR(buf);
int a = -1,b = -1,c = 0,d = 0;
static signed char b64_xtable[256];