summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-03-12 16:21:32 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-03-12 16:21:32 +0900
commit4ae5ae353564291cdb28108c26382c32242966a8 (patch)
tree6cb495e5c3c59a0c9f46b8e4548f17e7082443d2 /src
parent84e27d3b519d8fba87c6ffdf318ccadf67d5318f (diff)
downloadmruby-4ae5ae353564291cdb28108c26382c32242966a8.tar.gz
mruby-4ae5ae353564291cdb28108c26382c32242966a8.zip
codegen.c: no integer overflow error in `codegen`; close #5376
Add new pool value type `IREP_TT_BIGINT` and generate integer overflow error in the VM. In the future, `mruby` will support `Bignum` for integers bigger than `mrb_int` (probably using `mpz`).
Diffstat (limited to 'src')
-rw-r--r--src/codedump.c2
-rw-r--r--src/dump.c29
-rw-r--r--src/load.c13
-rw-r--r--src/state.c3
-rw-r--r--src/vm.c2
5 files changed, 46 insertions, 3 deletions
diff --git a/src/codedump.c b/src/codedump.c
index f382bb7eb..3a5f0eadb 100644
--- a/src/codedump.c
+++ b/src/codedump.c
@@ -6,7 +6,7 @@
#include <mruby/proc.h>
#include <mruby/dump.h>
-#ifndef MRB_NO_STDIO
+#ifndef MRB_NOP_STDIO
static void
print_r(mrb_state *mrb, const mrb_irep *irep, size_t n)
{
diff --git a/src/dump.c b/src/dump.c
index 51e8dca4e..0822b2fac 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -129,6 +129,15 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep)
size += 4; /* 32bits = 4bytes */
break;
+ case IREP_TT_BIGINT:
+ {
+ mrb_int len = irep->pool[pool_no].u.str[0];
+ mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+ size += sizeof(uint8_t);
+ size += (size_t)len+2;
+ }
+ break;
+
case IREP_TT_FLOAT:
#ifndef MRB_NO_FLOAT
{
@@ -187,6 +196,14 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf)
cur += uint32_to_bin(irep->pool[pool_no].u.i32, cur); /* i32 */
break;
+ case IREP_TT_BIGINT:
+ cur += uint8_to_bin(IREP_TT_BIGINT, cur); /* data type */
+ len = irep->pool[pool_no].u.str[0];
+ memcpy(cur, irep->pool[pool_no].u.str, (size_t)len+2);
+ cur += len+2;
+ *cur++ = '\0';
+ break;
+
case IREP_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
#ifndef MRB_NO_FLOAT
@@ -216,7 +233,6 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf)
return cur - buf;
}
-
static size_t
get_syms_block_size(mrb_state *mrb, const mrb_irep *irep)
{
@@ -941,6 +957,17 @@ dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp)
}
#endif
break;
+ case IREP_TT_BIGINT:
+ {
+ const char *s = p->u.str;
+ int len = s[0]+2;
+ fputs("{IREP_TT_BIGINT, {\"", fp);
+ for (int i=0; i<len; i++) {
+ fprintf(fp, "\\x%02x", (int)s[i]&0xff);
+ }
+ fputs("\"}},\n", fp);
+ }
+ break;
}
}
else { /* string */
diff --git a/src/load.c b/src/load.c
index 68be23546..f370dc67e 100644
--- a/src/load.c
+++ b/src/load.c
@@ -161,6 +161,19 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
return FALSE; /* INT64 not supported on MRB_32BIT */
#endif
+ case IREP_TT_BIGINT:
+ pool_data_len = bin_to_uint8(src); /* pool data length */
+ src += sizeof(uint8_t);
+ {
+ char *p;
+ pool[i].tt = IREP_TT_BIGINT;
+ p = (char*)mrb_malloc(mrb, pool_data_len+2);
+ memcpy(p, src, pool_data_len+2);
+ pool[i].u.str = (const char*)p;
+ }
+ src += pool_data_len + 2;
+ break;
+
case IREP_TT_FLOAT:
#ifndef MRB_NO_FLOAT
pool[i].tt = tt;
diff --git a/src/state.c b/src/state.c
index 0ba6db6ce..1b50eec34 100644
--- a/src/state.c
+++ b/src/state.c
@@ -154,7 +154,8 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
mrb_free(mrb, (void*)irep->iseq);
if (irep->pool) {
for (i=0; i<irep->plen; i++) {
- if ((irep->pool[i].tt & 3) == IREP_TT_STR) {
+ if ((irep->pool[i].tt & 3) == IREP_TT_STR ||
+ irep->pool[i].tt == IREP_TT_BIGINT) {
mrb_free(mrb, (void*)irep->pool[i].u.str);
}
}
diff --git a/src/vm.c b/src/vm.c
index 2607ba308..1009fb638 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1143,6 +1143,8 @@ RETRY_TRY_BLOCK:
#endif
goto L_INT_OVERFLOW;
#endif
+ case IREP_TT_BIGINT:
+ goto L_INT_OVERFLOW;
#ifndef MRB_NO_FLOAT
case IREP_TT_FLOAT:
regs[a] = mrb_float_value(mrb, pool[b].u.f);