diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-04-01 14:13:06 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-04-01 14:13:06 +0900 |
| commit | 2871d0cdc5e5ef952d27187b5488888bbd18c5b0 (patch) | |
| tree | 8167e5b1914548d62bcb14ac32b0f1411fe39172 /src | |
| parent | 6ec855a38e8116e4f0d04f188e948046b47af74f (diff) | |
| download | mruby-2871d0cdc5e5ef952d27187b5488888bbd18c5b0.tar.gz mruby-2871d0cdc5e5ef952d27187b5488888bbd18c5b0.zip | |
Avoid keeping pointers from `mrb_sym2name_len()`; fix #4342
The addresses for packed inline symbols reference `mrb->symbuf` that
could be overridden by the later call of `mrb_sym2name_len`. Since
file names in call stack information are kept as symbols, keeping the
address in the C structures could cause problems like #4342.
This changes small incompatible changes in function prototypes:
* `mrb_parser_get_filename`: return value changed to `mrb_sym`.
* `mrb_debug_get_filename`: add `mrb_state*` as a first argument.
* `mrb_debug_get_line`: ditto.
I believe above functions are almost internal, and no third-party
mrbgem use them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/backtrace.c | 4 | ||||
| -rw-r--r-- | src/class.c | 14 | ||||
| -rw-r--r-- | src/codedump.c | 14 | ||||
| -rw-r--r-- | src/debug.c | 15 | ||||
| -rw-r--r-- | src/error.c | 4 | ||||
| -rw-r--r-- | src/load.c | 3 | ||||
| -rw-r--r-- | src/symbol.c | 9 |
7 files changed, 29 insertions, 34 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index efca2562f..e4f5a3064 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -58,10 +58,10 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, mrb_code *pc0, each_backtrace_fu pc = pc0; } - loc.lineno = mrb_debug_get_line(irep, pc - irep->iseq); + loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq); if (loc.lineno == -1) continue; - loc.filename = mrb_debug_get_filename(irep, pc - irep->iseq); + loc.filename = mrb_debug_get_filename(mrb, irep, pc - irep->iseq); if (!loc.filename) { loc.filename = "(unknown)"; } diff --git a/src/class.c b/src/class.c index 3354617bb..5c5ee9d17 100644 --- a/src/class.c +++ b/src/class.c @@ -484,15 +484,11 @@ mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t MRB_API void mrb_notimplement(mrb_state *mrb) { - const char *str; - mrb_int len; mrb_callinfo *ci = mrb->c->ci; if (ci->mid) { - str = mrb_sym2name_len(mrb, ci->mid, &len); - mrb_raisef(mrb, E_NOTIMP_ERROR, - "%S() function is unimplemented on this machine", - mrb_str_new_static(mrb, str, (size_t)len)); + mrb_value str = mrb_sym2str(mrb, ci->mid); + mrb_raisef(mrb, E_NOTIMP_ERROR, "%S() function is unimplemented on this machine", str); } } @@ -1686,11 +1682,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c) } else if (mrb_symbol_p(path)) { /* toplevel class/module */ - const char *str; - mrb_int len; - - str = mrb_sym2name_len(mrb, mrb_symbol(path), &len); - return mrb_str_new(mrb, str, len); + return mrb_sym2str(mrb, mrb_symbol(path)); } return mrb_str_dup(mrb, path); } diff --git a/src/codedump.c b/src/codedump.c index c9c3b25ef..5bffefddb 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -48,11 +48,11 @@ print_lv_ab(mrb_state *mrb, mrb_irep *irep, uint16_t a, uint16_t b) } static void -print_header(mrb_irep *irep, ptrdiff_t i) +print_header(mrb_state *mrb, mrb_irep *irep, ptrdiff_t i) { int32_t line; - line = mrb_debug_get_line(irep, i); + line = mrb_debug_get_line(mrb, irep, i); if (line < 0) { printf(" "); } @@ -99,12 +99,12 @@ codedump(mrb_state *mrb, mrb_irep *irep) ai = mrb_gc_arena_save(mrb); i = pc - irep->iseq; - next_file = mrb_debug_get_filename(irep, i); + next_file = mrb_debug_get_filename(mrb, irep, i); if (next_file && file != next_file) { printf("file: %s\n", next_file); file = next_file; } - print_header(irep, i); + print_header(mrb, irep, i); ins = READ_B(); switch (ins) { CASE(OP_NOP, Z): @@ -491,7 +491,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) CASE(OP_EXT1, Z): ins = READ_B(); printf("OP_EXT1\n"); - print_header(irep, pc-irep->iseq-2); + print_header(mrb, irep, pc-irep->iseq-2); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i; #include "mruby/ops.h" @@ -501,7 +501,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) CASE(OP_EXT2, Z): ins = READ_B(); printf("OP_EXT2\n"); - print_header(irep, pc-irep->iseq-2); + print_header(mrb, irep, pc-irep->iseq-2); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i; #include "mruby/ops.h" @@ -511,7 +511,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) CASE(OP_EXT3, Z): ins = READ_B(); printf("OP_EXT3\n"); - print_header(irep, pc-irep->iseq-2); + print_header(mrb, irep, pc-irep->iseq-2); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i; #include "mruby/ops.h" diff --git a/src/debug.c b/src/debug.c index 2949131e4..0dc02a1e3 100644 --- a/src/debug.c +++ b/src/debug.c @@ -51,20 +51,20 @@ select_line_type(const uint16_t *lines, size_t lines_len) } MRB_API char const* -mrb_debug_get_filename(mrb_irep *irep, ptrdiff_t pc) +mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc) { if (irep && pc >= 0 && pc < irep->ilen) { mrb_irep_debug_info_file* f = NULL; if (!irep->debug_info) return NULL; else if ((f = get_file(irep->debug_info, (uint32_t)pc))) { - return f->filename; + return mrb_sym2name_len(mrb, f->filename_sym, NULL); } } return NULL; } MRB_API int32_t -mrb_debug_get_line(mrb_irep *irep, ptrdiff_t pc) +mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc) { if (irep && pc >= 0 && pc < irep->ilen) { mrb_irep_debug_info_file* f = NULL; @@ -129,7 +129,6 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, mrb_irep_debug_info_file *f; uint32_t file_pc_count; size_t fn_len; - mrb_int len; uint32_t i; if (!d) return NULL; @@ -138,8 +137,10 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, mrb_assert(filename); mrb_assert(lines); - if (d->flen > 0 && strcmp(filename, d->files[d->flen - 1]->filename) == 0) { - return NULL; + if (d->flen > 0) { + const char *fn = mrb_sym2name_len(mrb, d->files[d->flen - 1]->filename_sym, NULL); + if (strcmp(filename, fn) == 0) + return NULL; } f = (mrb_irep_debug_info_file*)mrb_malloc(mrb, sizeof(*f)); @@ -156,8 +157,6 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, fn_len = strlen(filename); f->filename_sym = mrb_intern(mrb, filename, fn_len); - len = 0; - f->filename = mrb_sym2name_len(mrb, f->filename_sym, &len); f->line_type = select_line_type(lines + start_pos, end_pos - start_pos); f->lines.ptr = NULL; diff --git a/src/error.c b/src/error.c index 50d1ab6f9..e69812dda 100644 --- a/src/error.c +++ b/src/error.c @@ -208,8 +208,8 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { mrb_irep *irep = ci->proc->body.irep; - int32_t const line = mrb_debug_get_line(irep, err - irep->iseq); - char const* file = mrb_debug_get_filename(irep, err - irep->iseq); + int32_t const line = mrb_debug_get_line(mrb, irep, err - irep->iseq); + char const* file = mrb_debug_get_filename(mrb, irep, err - irep->iseq); if (line != -1 && file) { mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file)); mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line)); diff --git a/src/load.c b/src/load.c index 55e0845f3..ab0346750 100644 --- a/src/load.c +++ b/src/load.c @@ -317,7 +317,6 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t * for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { mrb_irep_debug_info_file *file; uint16_t filename_idx; - mrb_int len; file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); irep->debug_info->files[f_idx] = file; @@ -330,8 +329,6 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t * bin += sizeof(uint16_t); mrb_assert(filename_idx < filenames_len); file->filename_sym = filenames[filename_idx]; - len = 0; - file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t); diff --git a/src/symbol.c b/src/symbol.c index 8ca03344c..96ca9dd17 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -520,7 +520,14 @@ mrb_sym2name(mrb_state *mrb, mrb_sym sym) return name; } else { - mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len)); + mrb_value str; + if (sym&1) { /* inline symbol */ + str = mrb_str_new(mrb, name, len); + } + else { + str = mrb_str_new_static(mrb, name, len); + } + str = mrb_str_dump(mrb, str); return RSTRING_PTR(str); } } |
