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 /src/dump.c | |
| 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
Diffstat (limited to 'src/dump.c')
| -rw-r--r-- | src/dump.c | 255 |
1 files changed, 156 insertions, 99 deletions
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)) { |
