diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-04-26 11:00:48 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-04-26 11:00:48 +0900 |
| commit | 5c5101809b561e7f1b822b016c7b51150cb519a8 (patch) | |
| tree | 608ec48d7b235fbee5f1997498e7348599452b5b /src | |
| parent | bcf120494090ff379307a65da49703d3628f7fb9 (diff) | |
| parent | 0c55eac01122c3011496709ddebde4414b70d2b8 (diff) | |
| download | mruby-5c5101809b561e7f1b822b016c7b51150cb519a8.tar.gz mruby-5c5101809b561e7f1b822b016c7b51150cb519a8.zip | |
Merge branch 'master' of github.com:mruby/mruby
Diffstat (limited to 'src')
| -rw-r--r-- | src/load.c | 99 |
1 files changed, 87 insertions, 12 deletions
diff --git a/src/load.c b/src/load.c index 213d8f899..303cd3881 100644 --- a/src/load.c +++ b/src/load.c @@ -17,10 +17,12 @@ #include "mruby/proc.h" #include "mruby/string.h" -#ifndef _WIN32 -# if SIZE_MAX < UINT32_MAX -# error "It can't be run this code on this environment (SIZE_MAX < UINT32_MAX)" -# endif +#if !defined(_WIN32) && SIZE_MAX < UINT32_MAX +# define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y)) +# define SIZE_ERROR(x) ((x) > SIZE_MAX) +#else +# define SIZE_ERROR_MUL(x, y) (0) +# define SIZE_ERROR(x) (0) #endif #if CHAR_BIT != 8 @@ -78,7 +80,7 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) src += sizeof(uint16_t); // number of register variable - irep->nregs = bin_to_uint16(src); + irep->nregs = bin_to_uint16(src); src += sizeof(uint16_t); // Binary Data Section @@ -86,6 +88,10 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) irep->ilen = bin_to_uint32(src); src += sizeof(uint32_t); if (irep->ilen > 0) { + if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); if (irep->iseq == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; @@ -101,6 +107,10 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) plen = bin_to_uint32(src); /* number of pool */ src += sizeof(uint32_t); if (plen > 0) { + if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * plen); if (irep->pool == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; @@ -140,6 +150,10 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) irep->slen = bin_to_uint32(src); //syms length src += sizeof(uint32_t); if (irep->slen > 0) { + if (SIZE_ERROR_MUL(sizeof(mrb_sym), irep->slen)) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); if (irep->syms == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; @@ -216,6 +230,10 @@ read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint3 fname_len = bin_to_uint16(bin); bin += sizeof(uint16_t); *len += sizeof(uint16_t); + if (SIZE_ERROR(fname_len + 1)) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } fname = (char *)mrb_malloc(mrb, fname_len + 1); if (fname == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; @@ -230,7 +248,15 @@ read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint3 bin += sizeof(uint32_t); // niseq *len += sizeof(uint32_t); + if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t)); + if (lines == NULL) { + ret = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } for (i = 0; i < niseq; i++) { lines[i] = bin_to_uint16(bin); bin += sizeof(uint16_t); // niseq @@ -241,6 +267,10 @@ read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint3 mrb->irep[irepno]->lines = lines; error_exit: + if (fname) { + mrb_free(mrb, fname); + } + return ret; } @@ -282,7 +312,7 @@ read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) if (memcmp(header->binary_identify, RITE_BINARY_IDENFIFIER, sizeof(header->binary_identify)) != 0) { return MRB_DUMP_INVALID_FILE_HEADER; } - + if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { return MRB_DUMP_INVALID_FILE_HEADER; } @@ -385,16 +415,32 @@ read_rite_section_lineno_file(mrb_state *mrb, FILE *fp, size_t sirep) nirep = bin_to_uint16(header.nirep); buf_size = record_header_size; + /* We don't need to check buf_size. As it is enough small. */ buf = (uint8_t *)mrb_malloc(mrb, buf_size); - + if (!buf) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + //Read Binary Data Section for (n = 0, i = sirep; n < nirep; n++, i++) { + void *ptr; + if (fread(buf, record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; goto error_exit; } buf_size = bin_to_uint32(&buf[0]); - buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size); + if (SIZE_ERROR(buf_size)) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + ptr = mrb_realloc(mrb, buf, buf_size); + if (!ptr) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + buf = (uint8_t *)ptr; if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; @@ -407,7 +453,9 @@ read_rite_section_lineno_file(mrb_state *mrb, FILE *fp, size_t sirep) result = sirep + bin_to_uint16(header.sirep); error_exit: - mrb_free(mrb, buf); + if (buf) { + mrb_free(mrb, buf); + } if (result < MRB_DUMP_OK) { irep_free(sirep, mrb); } @@ -435,16 +483,33 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp) nirep = bin_to_uint16(header.nirep); buf_size = record_header_size; + /* You don't need use SIZE_ERROR as buf_size is enough small. */ buf = (uint8_t *)mrb_malloc(mrb, buf_size); - + if (!buf) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + //Read Binary Data Section for (n = 0, i = sirep; n < nirep; n++, i++) { + void *ptr; + if (fread(buf, record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; goto error_exit; } buf_size = bin_to_uint32(&buf[0]); - buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size); + if (SIZE_ERROR(buf_size)) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + ptr = mrb_realloc(mrb, buf, buf_size); + if (!ptr) { + result = MRB_DUMP_GENERAL_FAILURE; + goto error_exit; + } + buf = (uint8_t *)ptr; + if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; goto error_exit; @@ -456,7 +521,9 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp) result = sirep + bin_to_uint16(header.sirep); error_exit: - mrb_free(mrb, buf); + if (buf) { + mrb_free(mrb, buf); + } if (result < MRB_DUMP_OK) { irep_free(sirep, mrb); } @@ -482,7 +549,11 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) return MRB_DUMP_INVALID_ARGUMENT; } + /* You don't need use SIZE_ERROR as buf_size is enough small. */ buf = mrb_malloc(mrb, buf_size); + if (!buf) { + return MRB_DUMP_GENERAL_FAILURE; + } if (fread(buf, buf_size, 1, fp) == 0) { mrb_free(mrb, buf); return MRB_DUMP_READ_FAULT; @@ -495,7 +566,11 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) /* verify CRC */ fpos = ftell(fp); + /* You don't need use SIZE_ERROR as block_size is enough small. */ buf = mrb_malloc(mrb, block_size); + if (!buf) { + return MRB_DUMP_GENERAL_FAILURE; + } fseek(fp, offset_crc_body(), SEEK_SET); while ((nbytes = fread(buf, 1, block_size, fp)) > 0) { crcwk = calc_crc_16_ccitt(buf, nbytes, crcwk); |
