From 2087526342e3fe3f74e5a609d3025ee964d58e4a Mon Sep 17 00:00:00 2001 From: Masamitsu MURASE Date: Sun, 3 Feb 2013 16:29:46 +0900 Subject: Modify handling of integer literal. Do not assume that significand of `double` is larger than `mrb_int`. --- src/codegen.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 5803a9c25..1f6d16477 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -959,6 +959,48 @@ readint_float(codegen_scope *s, const char *p, int base) return f; } +static mrb_int +readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflow) +{ + const char *e = p + strlen(p); + mrb_int result = 0; + int n; + + if (*p == '+') p++; + while (p < e) { + char c = *p; + c = tolower((unsigned char)c); + for (n=0; n result) { + *overflow = TRUE; + return 0; + } + result *= base; + result -= n; + } + else { + if ((MRB_INT_MAX - n)/base < result) { + *overflow = TRUE; + return 0; + } + result *= base; + result += n; + } + p++; + } + *overflow = FALSE; + return result; +} + static void codegen(codegen_scope *s, node *tree, int val) { @@ -1733,18 +1775,18 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { char *p = (char*)tree->car; int base = (intptr_t)tree->cdr->car; - double f; mrb_int i; mrb_code co; + int overflow; - f = readint_float(s, p, base); - if (!FIXABLE(f)) { + i = readint_mrb_int(s, p, base, FALSE, &overflow); + if (overflow) { + double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } else { - i = (mrb_int)f; if (i < MAXARG_sBx && i > -MAXARG_sBx) { co = MKOP_AsBx(OP_LOADI, cursp(), i); } @@ -1789,18 +1831,18 @@ codegen(codegen_scope *s, node *tree, int val) { char *p = (char*)tree->car; int base = (intptr_t)tree->cdr->car; - mrb_float f; mrb_int i; mrb_code co; + int overflow; - f = readint_float(s, p, base); - if (!FIXABLE(f)) { + i = readint_mrb_int(s, p, base, TRUE, &overflow); + if (overflow) { + double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(-f)); - + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } else { - i = (mrb_int)-f; if (i < MAXARG_sBx && i > -MAXARG_sBx) { co = MKOP_AsBx(OP_LOADI, cursp(), i); } -- cgit v1.2.3 From 641fc9902f6dd8c7b647a1bd61ee6fd9243acb34 Mon Sep 17 00:00:00 2001 From: Masamitsu MURASE Date: Sun, 3 Feb 2013 16:32:30 +0900 Subject: Prevent overflow of `Fixnum#to_s`. --- src/numeric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numeric.c b/src/numeric.c index 8bf2b3382..f6894a57b 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -1160,7 +1160,7 @@ fix_minus(mrb_state *mrb, mrb_value self) mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base) { - char buf[64], *b = buf + sizeof buf; + char buf[sizeof(mrb_int)*CHAR_BIT+2], *b = buf + sizeof buf; mrb_int val = mrb_fixnum(x); int neg = 0; -- cgit v1.2.3