From 07c03bc30984a496558d9e830bc4fb2f8cfb1854 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 23 Oct 2020 13:27:21 +0900 Subject: check isolated Proc more strictly Isolated Proc prohibit to access outer local variables, but it was violated by binding and so on, so they should be error. --- iseq.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'iseq.c') diff --git a/iseq.c b/iseq.c index 85ced1212c..449d3385cc 100644 --- a/iseq.c +++ b/iseq.c @@ -130,6 +130,7 @@ rb_iseq_free(const rb_iseq_t *iseq) ruby_xfree((void *)body->param.keyword); } compile_data_free(ISEQ_COMPILE_DATA(iseq)); + if (body->outer_variables) rb_id_table_free(body->outer_variables); ruby_xfree(body); } @@ -575,8 +576,7 @@ new_arena(void) static VALUE prepare_iseq_build(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_location_t *code_location, const int node_id, - const rb_iseq_t *parent, enum iseq_type type, - const rb_compile_option_t *option) + const rb_iseq_t *parent, int isolated_depth, enum iseq_type type, const rb_compile_option_t *option) { VALUE coverage = Qfalse; VALUE err_info = Qnil; @@ -603,11 +603,11 @@ prepare_iseq_build(rb_iseq_t *iseq, ISEQ_COMPILE_DATA(iseq)->node.storage_head = ISEQ_COMPILE_DATA(iseq)->node.storage_current = new_arena(); ISEQ_COMPILE_DATA(iseq)->insn.storage_head = ISEQ_COMPILE_DATA(iseq)->insn.storage_current = new_arena(); + ISEQ_COMPILE_DATA(iseq)->isolated_depth = isolated_depth; ISEQ_COMPILE_DATA(iseq)->option = option; - ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL; - ISEQ_COMPILE_DATA(iseq)->builtin_function_table = GET_VM()->builtin_function_table; + if (option->coverage_enabled) { VALUE coverages = rb_get_coverages(); @@ -794,8 +794,8 @@ rb_iseq_t * rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum iseq_type type) { - return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, type, - &COMPILE_OPTION_DEFAULT); + return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, + 0, type, &COMPILE_OPTION_DEFAULT); } rb_iseq_t * @@ -810,8 +810,8 @@ rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath } } - return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, ISEQ_TYPE_TOP, - &COMPILE_OPTION_DEFAULT); + return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, 0, + ISEQ_TYPE_TOP, &COMPILE_OPTION_DEFAULT); } rb_iseq_t * @@ -819,7 +819,14 @@ rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_ { return rb_iseq_new_with_opt(ast, rb_fstring_lit("
"), path, realpath, INT2FIX(0), - parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT); + parent, 0, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT); +} + +rb_iseq_t * +rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth) +{ + return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno, + parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT); } static inline rb_iseq_t * @@ -838,8 +845,8 @@ iseq_translate(rb_iseq_t *iseq) rb_iseq_t * rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, - VALUE first_lineno, const rb_iseq_t *parent, - enum iseq_type type, const rb_compile_option_t *option) + VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth, + enum iseq_type type, const rb_compile_option_t *option) { const NODE *node = ast ? ast->root : 0; /* TODO: argument check */ @@ -854,7 +861,7 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea } if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option); - prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1, parent, type, &new_opt); + prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1, parent, isolated_depth, type, &new_opt); rb_iseq_compile_node(iseq, node); finish_iseq_build(iseq); @@ -873,7 +880,7 @@ rb_iseq_new_with_callback( rb_iseq_t *iseq = iseq_alloc(); if (!option) option = &COMPILE_OPTION_DEFAULT; - prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, type, option); + prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, 0, type, option); rb_iseq_compile_callback(iseq, ifunc); finish_iseq_build(iseq); @@ -986,7 +993,7 @@ iseq_load(VALUE data, const rb_iseq_t *parent, VALUE opt) make_compile_option(&option, opt); option.peephole_optimization = FALSE; /* because peephole optimization can modify original iseq */ prepare_iseq_build(iseq, name, path, realpath, first_lineno, &tmp_loc, NUM2INT(node_id), - parent, (enum iseq_type)iseq_type, &option); + parent, 0, (enum iseq_type)iseq_type, &option); rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body); @@ -1054,7 +1061,7 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V else { INITIALIZED VALUE label = rb_fstring_lit(""); iseq = rb_iseq_new_with_opt(&ast->body, label, file, realpath, line, - 0, ISEQ_TYPE_TOP, &option); + NULL, 0, ISEQ_TYPE_TOP, &option); rb_ast_dispose(ast); } @@ -1310,7 +1317,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self) ret = iseqw_new(rb_iseq_new_with_opt(&ast->body, rb_fstring_lit("
"), file, rb_realpath_internal(Qnil, file, 1), - line, NULL, ISEQ_TYPE_TOP, &option)); + line, NULL, 0, ISEQ_TYPE_TOP, &option)); rb_ast_dispose(ast); return ret; } -- cgit v1.2.3