diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-03-09 01:28:31 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-03-09 01:28:31 +0900 |
| commit | ee57789c724cb8bb86ebeda2dfd2ef585e996f68 (patch) | |
| tree | 88ac5cdfa6e37967467ee13fc7b39794e4b7e6c5 | |
| parent | 452bf73c2317cc4c9cf69b4dbf3ff82c3bde89c3 (diff) | |
| parent | 270d25bf2db157c9d1cdcc57bccefabbb1341524 (diff) | |
| download | mruby-ee57789c724cb8bb86ebeda2dfd2ef585e996f68.tar.gz mruby-ee57789c724cb8bb86ebeda2dfd2ef585e996f68.zip | |
Merge pull request #1831 from monaka/pr-make-type-casts-safer
Make type casts safer
| -rw-r--r-- | include/mruby/dump.h | 6 | ||||
| -rw-r--r-- | include/mruby/string.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-proc-ext/src/proc.c | 2 | ||||
| -rw-r--r-- | src/class.c | 5 | ||||
| -rw-r--r-- | src/codegen.c | 7 | ||||
| -rw-r--r-- | src/dump.c | 255 | ||||
| -rw-r--r-- | src/load.c | 113 | ||||
| -rw-r--r-- | src/string.c | 6 |
8 files changed, 245 insertions, 151 deletions
diff --git a/include/mruby/dump.h b/include/mruby/dump.h index 69fd776b3..35546f9de 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -92,14 +92,14 @@ struct rite_binary_footer { RITE_SECTION_HEADER; }; -static inline int +static inline size_t uint8_to_bin(uint8_t s, uint8_t *bin) { *bin = s; return sizeof(uint8_t); } -static inline int +static inline size_t uint16_to_bin(uint16_t s, uint8_t *bin) { *bin++ = (s >> 8) & 0xff; @@ -107,7 +107,7 @@ uint16_to_bin(uint16_t s, uint8_t *bin) return sizeof(uint16_t); } -static inline int +static inline size_t uint32_to_bin(uint32_t l, uint8_t *bin) { *bin++ = (l >> 24) & 0xff; diff --git a/include/mruby/string.h b/include/mruby/string.h index 9ccbae56c..8a26192e6 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -15,7 +15,7 @@ extern "C" { extern const char mrb_digitmap[]; -#define RSTRING_EMBED_LEN_MAX (sizeof(void*) * 3 - 1) +#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1)) struct RString { MRB_OBJECT_HEADER; diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index 0bf1204f5..4e41891a4 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -21,7 +21,7 @@ mrb_proc_source_location(mrb_state *mrb, mrb_value self) } else { mrb_irep *irep = p->body.irep; - uint32_t line; + int32_t line; const char *filename; filename = mrb_debug_get_filename(irep, 0); diff --git a/src/class.c b/src/class.c index 5a084b016..d880e3627 100644 --- a/src/class.c +++ b/src/class.c @@ -540,9 +540,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ps = va_arg(ap, char**); if (i < argc) { + size_t size_t_len; ss = to_str(mrb, *sp++); s = mrb_str_ptr(ss); - len = (mrb_int)strlen(RSTRING_PTR(ss)); + size_t_len = strlen(RSTRING_PTR(ss)); + mrb_assert(size_t_len <= MRB_INT_MAX); + len = (mrb_int)size_t_len; if (len < RSTRING_LEN(ss)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); } diff --git a/src/codegen.c b/src/codegen.c index 0b4d18bba..700cfdbf8 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -5,6 +5,7 @@ */ #include <ctype.h> +#include <limits.h> #include <stdlib.h> #include <string.h> #include "mruby.h" @@ -2582,14 +2583,16 @@ static void codedump(mrb_state *mrb, mrb_irep *irep) { #ifdef ENABLE_STDIO - uint32_t i; + int i; int ai; mrb_code c; if (!irep) return; printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", irep, irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen); - for (i=0; i<irep->ilen; i++) { + + mrb_assert(irep->ilen <= INT_MAX); + for (i = 0; i < (int)(irep->ilen); i++) { ai = mrb_gc_arena_save(mrb); printf("%03d ", i); c = irep->iseq[i]; diff --git a/src/dump.c b/src/dump.c index 72d1ffcbe..b9e02fe77 100644 --- a/src/dump.c +++ b/src/dump.c @@ -12,12 +12,16 @@ #include "mruby/numeric.h" #include "mruby/debug.h" -static uint32_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); +static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); -static uint32_t +#if UINT32_MAX > SIZE_MAX +# error This code cannot be built on your environment. +#endif + +static size_t get_irep_header_size(mrb_state *mrb) { - uint32_t size = 0; + size_t size = 0; size += sizeof(uint32_t) * 1; size += sizeof(uint16_t) * 3; @@ -25,7 +29,7 @@ get_irep_header_size(mrb_state *mrb) return size; } -static uint32_t +static ptrdiff_t write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { uint8_t *cur = buf; @@ -35,20 +39,22 @@ write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */ - return (cur - buf); + return cur - buf; } -static uint32_t +static size_t get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; + size_t size = 0; + size += sizeof(uint32_t); /* ilen */ size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */ + return size; } -static uint32_t +static ptrdiff_t write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { uint8_t *cur = buf; @@ -59,16 +65,15 @@ write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ } - return (cur - buf); + return cur - buf; } -static uint32_t +static size_t get_pool_block_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; - uint32_t pool_no; - int len; + size_t size = 0; + size_t pool_no; mrb_value str; char buf[32]; @@ -81,16 +86,31 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); - size += RSTRING_LEN(str); + { + mrb_int len = RSTRING_LEN(str); + mrb_assert(len >= 0); + mrb_assert((size_t)len <= SIZE_MAX); + size += (size_t)len; + } break; case MRB_TT_FLOAT: - len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no])); - size += len; + { + int len; + len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no])); + mrb_assert(len >= 0); + mrb_assert((size_t)len <= SIZE_MAX); + size += (size_t)len; + } break; case MRB_TT_STRING: - size += RSTRING_LEN(irep->pool[pool_no]); + { + mrb_int len = RSTRING_LEN(irep->pool[pool_no]); + mrb_assert(len >= 0); + mrb_assert((size_t)len <= SIZE_MAX); + size += (size_t)len; + } break; default: @@ -102,12 +122,12 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) return size; } -static uint32_t +static ptrdiff_t write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { - uint32_t pool_no; + size_t pool_no; uint8_t *cur = buf; - uint32_t len; + uint16_t len; mrb_value str; const char *char_ptr; char char_buf[30]; @@ -122,19 +142,37 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */ str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); char_ptr = RSTRING_PTR(str); - len = RSTRING_LEN(str); + { + mrb_int tlen; + tlen = RSTRING_LEN(str); + mrb_assert(tlen >= 0); + mrb_assert(tlen <= INT16_MAX); + len = (uint16_t)tlen; + } break; case MRB_TT_FLOAT: cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ - len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); + { + int tlen; + tlen = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); + mrb_assert(tlen >= 0); + mrb_assert(tlen <= INT16_MAX); + len = (uint16_t)tlen; + } char_ptr = &char_buf[0]; break; case MRB_TT_STRING: cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ char_ptr = RSTRING_PTR(irep->pool[pool_no]); - len = RSTRING_LEN(irep->pool[pool_no]); + { + mrb_int tlen; + tlen = RSTRING_LEN(irep->pool[pool_no]); + mrb_assert(tlen >= 0); + mrb_assert(tlen <= INT16_MAX); + len = (uint16_t)tlen; + } break; default: @@ -142,20 +180,20 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) } cur += uint16_to_bin(len, cur); /* data length */ - memcpy(cur, char_ptr, len); + memcpy(cur, char_ptr, (size_t)len); cur += len; mrb_gc_arena_restore(mrb, ai); } - return (uint32_t)(cur - buf); + return cur - buf; } -static uint32_t +static size_t get_syms_block_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; + size_t size = 0; uint32_t sym_no; size_t len; @@ -171,7 +209,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep) return size; } -static uint32_t +static ptrdiff_t write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { uint32_t sym_no; @@ -185,10 +223,8 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) size_t len; name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); - if (len > UINT16_MAX) { - return MRB_DUMP_GENERAL_FAILURE; - } + mrb_assert(len <= UINT16_MAX); cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ memcpy(cur, name, len); /* symbol name */ cur += (uint16_t)len; @@ -199,13 +235,13 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) } } - return (uint32_t)(cur - buf); + return cur - buf; } -static uint32_t +static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; + size_t size = 0; size += get_irep_header_size(mrb); size += get_iseq_block_size(mrb, irep); @@ -214,11 +250,11 @@ get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) return size; } -static uint32_t +static size_t get_irep_record_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; - uint32_t irep_no; + size_t size = 0; + size_t irep_no; size = get_irep_record_size_1(mrb, irep); for (irep_no = 0; irep_no < irep->rlen; irep_no++) { @@ -228,7 +264,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep) } static int -write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size) +write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size) { uint32_t i; @@ -250,14 +286,14 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_r for (i = 0; i < irep->rlen; i++) { int result; - uint32_t rlen; + size_t rsize; - result = write_irep_record(mrb, irep->reps[i], bin, &rlen); + result = write_irep_record(mrb, irep->reps[i], bin, &rsize); if (result != MRB_DUMP_OK) { return result; } - *irep_record_size += rlen; - bin += rlen; + *irep_record_size += rsize; + bin += rsize; } return MRB_DUMP_OK; } @@ -276,12 +312,13 @@ write_footer(mrb_state *mrb, uint8_t *bin) static int -write_section_irep_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin) +write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) { struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify)); - uint32_to_bin(section_size, header->section_size); + mrb_assert(section_size <= UINT32_MAX); + uint32_to_bin((uint32_t)section_size, header->section_size); memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); return MRB_DUMP_OK; @@ -291,7 +328,8 @@ static int write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) { int result; - uint32_t section_size = 0, rlen = 0; /* size of irep record */ + size_t section_size = 0; /* size of irep record */ + size_t rsize = 0; uint8_t *cur = bin; if (mrb == NULL || bin == NULL) { @@ -301,33 +339,32 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) cur += sizeof(struct rite_section_irep_header); section_size += sizeof(struct rite_section_irep_header); - result = write_irep_record(mrb, irep, cur, &rlen); + result = write_irep_record(mrb, irep, cur, &rsize); if (result != MRB_DUMP_OK) { return result; } - cur += rlen; - section_size += rlen; + cur += rsize; + section_size += rsize; write_section_irep_header(mrb, section_size, bin); return MRB_DUMP_OK; } static int -write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin) +write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin) { struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; - /* TODO */ memcpy(header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(header->section_identify)); - uint32_to_bin(section_size, header->section_size); + uint32_to_bin((uint32_t)section_size, header->section_size); return MRB_DUMP_OK; } -static uint32_t +static size_t get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; + size_t size = 0; size += sizeof(uint32_t); /* record size */ size += sizeof(uint16_t); /* filename size */ @@ -338,21 +375,27 @@ get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) if (irep->lines) { size += sizeof(uint16_t) * irep->ilen; /* lineno */ } + return size; } -static int +static size_t write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) { uint8_t *cur = bin; - uint32_t filename_len = 0, iseq_no; + size_t iseq_no; + size_t filename_len; + ptrdiff_t diff; cur += sizeof(uint32_t); /* record size */ if (irep->filename) { filename_len = strlen(irep->filename); + } else { + filename_len = 0; } - cur += uint16_to_bin(filename_len, cur); /* filename size */ + mrb_assert(filename_len <= UINT16_MAX); + cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */ if (filename_len) { memcpy(cur, irep->filename, filename_len); @@ -360,7 +403,8 @@ write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) } if (irep->lines) { - cur += uint32_to_bin(irep->ilen, cur); /* niseq */ + mrb_assert(irep->ilen <= UINT32_MAX); + cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */ for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */ } @@ -369,16 +413,21 @@ write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) cur += uint32_to_bin(0, cur); /* niseq */ } - uint32_to_bin(cur - bin, bin); /* record size */ + diff = cur - bin; + mrb_assert(diff >= 0); + mrb_assert(diff <= UINT32_MAX); + + uint32_to_bin((uint32_t)diff, bin); /* record size */ - return (cur - bin); + mrb_assert((size_t)diff <= SIZE_MAX); + return (size_t)diff; } -static int +static size_t write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) { - uint32_t i; - uint32_t rlen, size = 0; + size_t i; + size_t rlen, size = 0; rlen = write_lineno_record_1(mrb, irep, bin); bin += rlen; @@ -394,7 +443,8 @@ write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) static int write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) { - uint32_t section_size = 0, rlen = 0; /* size of irep record */ + size_t section_size = 0; + size_t rlen = 0; /* size of irep record */ uint8_t *cur = bin; if (mrb == NULL || bin == NULL) { @@ -412,11 +462,12 @@ write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) return MRB_DUMP_OK; } -static uint32_t +static size_t get_debug_record_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t ret = 0, f_idx; - uint32_t i; + size_t ret = 0; + uint16_t f_idx; + size_t i; ret += sizeof(uint32_t); /* record size */ ret += sizeof(uint16_t); /* file count */ @@ -432,11 +483,11 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep) ret += sizeof(uint8_t); /* line type */ switch(file->line_type) { case mrb_debug_line_ary: - ret += sizeof(uint16_t) * file->line_entry_count; + ret += sizeof(uint16_t) * (size_t)(file->line_entry_count); break; case mrb_debug_line_flat_map: - ret += (sizeof(uint32_t) + sizeof(uint16_t)) * file->line_entry_count; + ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count); break; default: mrb_assert(0); break; @@ -450,9 +501,9 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep) } static int -find_filename_index(const mrb_sym *ary, uint32_t ary_len, mrb_sym s) +find_filename_index(const mrb_sym *ary, uint16_t ary_len, mrb_sym s) { - uint32_t i; + int i; for (i = 0; i < ary_len; ++i) { if (ary[i] == s) { return i; } @@ -460,13 +511,13 @@ find_filename_index(const mrb_sym *ary, uint32_t ary_len, mrb_sym s) return -1; } -static uint32_t -get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint32_t *lp) +static size_t +get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) { mrb_sym *filenames = *fp; - uint32_t tsize = 0; + uint16_t tsize = 0; uint32_t file_i; - uint32_t size = 0; + size_t size = 0; mrb_irep_debug_info *di = irep->debug_info; if (lp == NULL) { @@ -496,12 +547,12 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint32_t * return size; } -static int -write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint32_t filenames_len) +static size_t +write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) { uint8_t *cur; - uint32_t f_idx; - uint32_t ret; + uint16_t f_idx; + ptrdiff_t ret; cur = bin + sizeof(uint32_t); /* skip record size */ cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */ @@ -516,8 +567,9 @@ write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const /* filename index */ filename_idx = find_filename_index(filenames, filenames_len, file->filename_sym); - mrb_assert(filename_idx != -1); - cur += uint16_to_bin(filename_idx, cur); + mrb_assert(filename_idx >= 0); + mrb_assert(filename_idx <= UINT16_MAX); + cur += uint16_to_bin((uint16_t)filename_idx, cur); /* lines */ cur += uint32_to_bin(file->line_entry_count, cur); @@ -543,16 +595,19 @@ write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const } ret = cur - bin; + mrb_assert(ret >= 0); + mrb_assert(ret <= UINT32_MAX); uint32_to_bin(ret, bin); - return ret; + mrb_assert((size_t)ret <= SIZE_MAX); + return (size_t)ret; } -static uint32_t -write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint32_t filenames_len) +static size_t +write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) { - uint32_t size, len; - uint32_t irep_no; + size_t size, len; + size_t irep_no; size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); bin += len; @@ -566,14 +621,14 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* return size; } -static uint32_t -write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, uint32_t *lp) +static size_t +write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, uint16_t *lp) { uint8_t *cur = *cp; mrb_sym *filenames = *fp; uint32_t file_i; uint16_t fn_len; - uint32_t size = 0; + size_t size = 0; mrb_irep_debug_info *debug_info = irep->debug_info; for (file_i = 0; file_i < debug_info->flen; ++file_i) { @@ -603,13 +658,13 @@ write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, static int write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur) { - uint32_t section_size = 0; + size_t section_size = 0; const uint8_t *bin = cur; struct rite_section_debug_header *header; mrb_sym *filenames; - uint32_t filenames_len = 0; + uint16_t filenames_len = 0; uint8_t *filenames_len_out; - uint32_t dlen; + size_t dlen; if (mrb == NULL || cur == NULL) { return MRB_DUMP_INVALID_ARGUMENT; @@ -632,6 +687,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur) section_size += dlen; memcpy(header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(header->section_identify)); + mrb_assert(section_size <= INT32_MAX); uint32_to_bin(section_size, header->section_size); mrb_free(mrb, filenames); @@ -640,7 +696,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur) } static int -write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin) +write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin) { struct rite_binary_header *header = (struct rite_binary_header *)bin; uint16_t crc; @@ -650,7 +706,8 @@ write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin) memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)); memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); - uint32_to_bin(binary_size, header->binary_size); + mrb_assert(binary_size <= UINT32_MAX); + uint32_to_bin((uint32_t)binary_size, header->binary_size); offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t); crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); @@ -662,7 +719,7 @@ write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin) static mrb_bool is_debug_info_defined(mrb_irep *irep) { - uint32_t i; + size_t i; if (!irep->debug_info) return 0; for (i=0; i<irep->rlen; i++) { @@ -672,11 +729,11 @@ is_debug_info_defined(mrb_irep *irep) } static int -dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, uint32_t *bin_size) +dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; - uint32_t section_irep_size; - uint32_t section_lineno_size = 0; + size_t section_irep_size; + size_t section_lineno_size = 0; uint8_t *cur = NULL; mrb_bool const debug_info_defined = is_debug_info_defined(irep); @@ -757,7 +814,7 @@ int mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) { uint8_t *bin = NULL; - uint32_t bin_size = 0; + size_t bin_size = 0; int result; if (fp == NULL) { @@ -793,7 +850,7 @@ int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, const char *initname) { uint8_t *bin = NULL; - uint32_t bin_size = 0, bin_idx = 0; + size_t bin_size = 0, bin_idx = 0; int result; if (fp == NULL || initname == NULL || !is_valid_c_symbol_name(initname)) { diff --git a/src/load.c b/src/load.c index de517f89f..aa39efba4 100644 --- a/src/load.c +++ b/src/load.c @@ -26,6 +26,10 @@ # error This code assumes CHAR_BIT == 8 #endif +#if UINT32_MAX > SIZE_MAX +# error This code cannot be built on your environment. +#endif + static size_t offset_crc_body(void) { @@ -34,10 +38,11 @@ offset_crc_body(void) } static mrb_irep* -read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc) +read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) { size_t i; const uint8_t *src = bin; + ptrdiff_t diff; uint16_t tt, pool_data_len, snl; size_t plen; int ai = mrb_gc_arena_save(mrb); @@ -55,12 +60,12 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a src += sizeof(uint16_t); /* number of child irep */ - irep->rlen = bin_to_uint16(src); + irep->rlen = (size_t)bin_to_uint16(src); src += sizeof(uint16_t); /* Binary Data Section */ /* ISEQ BLOCK */ - irep->ilen = bin_to_uint32(src); + irep->ilen = (size_t)bin_to_uint32(src); src += sizeof(uint32_t); if (irep->ilen > 0) { if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) { @@ -71,13 +76,13 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a return NULL; } for (i = 0; i < irep->ilen; i++) { - irep->iseq[i] = bin_to_uint32(src); /* iseq */ + irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */ src += sizeof(uint32_t); } } /* POOL BLOCK */ - plen = bin_to_uint32(src); /* number of pool */ + plen = (size_t)bin_to_uint32(src); /* number of pool */ src += sizeof(uint32_t); if (plen > 0) { if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) { @@ -125,7 +130,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a } /* SYMS BLOCK */ - irep->slen = bin_to_uint32(src); /* syms length */ + irep->slen = (size_t)bin_to_uint32(src); /* syms length */ src += sizeof(uint32_t); if (irep->slen > 0) { if (SIZE_ERROR_MUL(sizeof(mrb_sym), irep->slen)) { @@ -158,20 +163,24 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a } irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen); - *len = src - bin; + + diff = src - bin; + mrb_assert(diff >= 0); + mrb_assert((size_t)diff <= SIZE_MAX); + *len = (size_t)diff; return irep; } static mrb_irep* -read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc) +read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) { mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc); size_t i; bin += *len; for (i=0; i<irep->rlen; i++) { - uint32_t rlen; + size_t rlen; irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc); bin += rlen; @@ -183,14 +192,14 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool all static mrb_irep* read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc) { - uint32_t len; + size_t len; bin += sizeof(struct rite_section_irep_header); return read_irep_record(mrb, bin, &len, alloc); } static int -read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t *len) +read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len) { int ret; size_t i, fname_len, niseq; @@ -216,7 +225,7 @@ read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_ bin += fname_len; *len += fname_len; - niseq = bin_to_uint32(bin); + niseq = (size_t)bin_to_uint32(bin); bin += sizeof(uint32_t); /* niseq */ *len += sizeof(uint32_t); @@ -239,14 +248,14 @@ read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_ } static int -read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t *lenp) +read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp) { int result = read_lineno_record_1(mrb, bin, irep, lenp); size_t i; if (result != MRB_DUMP_OK) return result; for (i = 0; i < irep->rlen; i++) { - uint32_t len; + size_t len; result = read_lineno_record(mrb, bin, irep->reps[i], &len); if (result != MRB_DUMP_OK) break; @@ -259,7 +268,7 @@ read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t static int read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep) { - uint32_t len; + size_t len; len = 0; bin += sizeof(struct rite_section_lineno_header); @@ -269,9 +278,10 @@ read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep) } static int -read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t *len, const mrb_sym *filenames, size_t filenames_len) +read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) { const uint8_t *bin = start; + ptrdiff_t diff; size_t record_size, i; uint16_t f_idx; @@ -280,7 +290,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); irep->debug_info->pc_count = irep->ilen; - record_size = bin_to_uint32(bin); + record_size = (size_t)bin_to_uint32(bin); bin += sizeof(uint32_t); irep->debug_info->flen = bin_to_uint16(bin); @@ -295,7 +305,8 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); irep->debug_info->files[f_idx] = file; - file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); + file->start_pos = bin_to_uint32(bin); + bin += sizeof(uint32_t); /* filename */ filename_idx = bin_to_uint16(bin); @@ -305,26 +316,31 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t len = 0; file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); - file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t); - file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); bin += sizeof(uint8_t); + file->line_entry_count = bin_to_uint32(bin); + bin += sizeof(uint32_t); + file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); + bin += sizeof(uint8_t); switch(file->line_type) { case mrb_debug_line_ary: { - size_t l; + uint32_t l; - file->line_ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * file->line_entry_count); + file->line_ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count)); for(l = 0; l < file->line_entry_count; ++l) { - file->line_ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); + file->line_ary[l] = bin_to_uint16(bin); + bin += sizeof(uint16_t); } } break; case mrb_debug_line_flat_map: { - size_t l; + uint32_t l; file->line_flat_map = (mrb_irep_debug_info_line*)mrb_malloc( - mrb, sizeof(mrb_irep_debug_info_line) * file->line_entry_count); + mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count)); for(l = 0; l < file->line_entry_count; ++l) { - file->line_flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); - file->line_flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); + file->line_flat_map[l].start_pos = bin_to_uint32(bin); + bin += sizeof(uint32_t); + file->line_flat_map[l].line = bin_to_uint16(bin); + bin += sizeof(uint16_t); } } break; @@ -332,12 +348,16 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t } } - if((long)record_size != (bin - start)) { + diff = bin - start; + mrb_assert(diff >= 0); + mrb_assert((size_t)diff <= SIZE_MAX); + + if(record_size != (size_t)diff) { return MRB_DUMP_GENERAL_FAILURE; } for (i = 0; i < irep->rlen; i++) { - uint32_t len; + size_t len; int ret; ret =read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len); @@ -345,7 +365,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t bin += len; } - *len = bin - start; + diff = bin - start; + mrb_assert(diff >= 0); + mrb_assert((size_t)diff <= SIZE_MAX); + *record_len = (size_t)diff; return MRB_DUMP_OK; } @@ -354,11 +377,12 @@ static int read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) { const uint8_t *bin; + ptrdiff_t diff; struct rite_section_debug_header *header; uint16_t i; - uint32_t len = 0; + size_t len = 0; int result; - size_t filenames_len; + uint16_t filenames_len; mrb_sym *filenames; bin = start; @@ -367,15 +391,15 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo filenames_len = bin_to_uint16(bin); bin += sizeof(uint16_t); - filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * filenames_len); + filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len); for(i = 0; i < filenames_len; ++i) { uint16_t f_len = bin_to_uint16(bin); bin += sizeof(uint16_t); if (alloc) { - filenames[i] = mrb_intern(mrb, (const char *)bin, f_len); + filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); } else { - filenames[i] = mrb_intern_static(mrb, (const char *)bin, f_len); + filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); } bin += f_len; } @@ -384,7 +408,10 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo if (result != MRB_DUMP_OK) goto debug_exit; bin += len; - if ((bin - start) != bin_to_uint32(header->section_size)) { + diff = bin - start; + mrb_assert(diff >= 0); + mrb_assert(diff <= UINT32_MAX); + if ((uint32_t)diff != bin_to_uint32(header->section_size)) { result = MRB_DUMP_GENERAL_FAILURE; } @@ -408,7 +435,7 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) *crc = bin_to_uint16(header->binary_crc); if (bin_size) { - *bin_size = bin_to_uint32(header->binary_size); + *bin_size = (size_t)bin_to_uint32(header->binary_size); } return MRB_DUMP_OK; @@ -504,14 +531,14 @@ read_lineno_record_file(mrb_state *mrb, FILE *fp, mrb_irep *irep) const size_t record_header_size = sizeof(header); int result; size_t i, buf_size; - uint32_t len; + size_t len; void *ptr; uint8_t *buf; if (fread(header, record_header_size, 1, fp) == 0) { return MRB_DUMP_READ_FAULT; } - buf_size = bin_to_uint32(&header[0]); + buf_size = (size_t)bin_to_uint32(&header[0]); if (SIZE_ERROR(buf_size)) { return MRB_DUMP_GENERAL_FAILURE; } @@ -553,7 +580,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp) uint8_t header[1 + 4]; const size_t record_header_size = sizeof(header); size_t buf_size, i; - uint32_t len; + size_t len; mrb_irep *irep = NULL; void *ptr; uint8_t *buf; @@ -561,7 +588,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp) if (fread(header, record_header_size, 1, fp) == 0) { return NULL; } - buf_size = bin_to_uint32(&header[0]); + buf_size = (size_t)bin_to_uint32(&header[0]); if (SIZE_ERROR(buf_size)) { return NULL; } @@ -600,7 +627,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) int result; uint8_t *buf; uint16_t crc, crcwk = 0; - uint32_t section_size = 0; + size_t section_size = 0; size_t nbytes; struct rite_section_header section_header; long fpos; @@ -657,7 +684,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) if (fread(§ion_header, sizeof(struct rite_section_header), 1, fp) == 0) { return NULL; } - section_size = bin_to_uint32(section_header.section_size); + section_size = (size_t)bin_to_uint32(section_header.section_size); if (memcmp(section_header.section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header.section_identify)) == 0) { fseek(fp, fpos, SEEK_SET); diff --git a/src/string.c b/src/string.c index 85a3cc2a7..123a1dcb5 100644 --- a/src/string.c +++ b/src/string.c @@ -2067,8 +2067,12 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) { struct RString *ps = mrb_str_ptr(*ptr); char *s = STR_PTR(ps); + mrb_int len; - if (!s || STR_LEN(ps) != strlen(s)) { + len = STR_LEN(ps); + mrb_assert(len >= 0); + mrb_assert((size_t)len <= SIZE_MAX); + if (!s || (size_t)len != strlen(s)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); } return s; |
