From ac3c46901c3d1f75e5b66505056a1d1fa50e5343 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 29 Jun 2004 01:31:37 +0000 Subject: [PATCH] * eval.c (rb_eval_cmd, rb_thread_trap_eval): restore safe level. * gc.c (define_final, run_final): preserve and restore safe level for finalizers. [ruby-core:03058] * signal.c (signal_exec, rb_trap_exit, trap): preserve and restore safe level for signal handlers. [ruby-dev:23829] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++++++++ eval.c | 35 ++++++++++++++++++++++------------- gc.c | 13 ++++++++++--- intern.h | 2 +- signal.c | 28 ++++++++++++++++------------ 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index c914443900..3f8719f087 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Tue Jun 29 10:31:19 2004 Nobuyoshi Nakada + + * eval.c (rb_eval_cmd, rb_thread_trap_eval): restore safe level. + + * gc.c (define_final, run_final): preserve and restore safe level for + finalizers. [ruby-core:03058] + + * signal.c (signal_exec, rb_trap_exit, trap): preserve and restore + safe level for signal handlers. [ruby-dev:23829] + Mon Jun 28 14:57:56 2004 Jeff Mitchell * configure.in, lib/mkmf.rb (LIBPATHFLAG): use double quotes due to diff --git a/eval.c b/eval.c index f42be098a8..c81cd19305 100644 --- a/eval.c +++ b/eval.c @@ -1667,19 +1667,29 @@ jump_tag_but_local_jump(state, val) } VALUE -rb_eval_cmd(cmd, arg, tcheck) +rb_eval_cmd(cmd, arg, level) VALUE cmd, arg; - int tcheck; + int level; { int state; VALUE val = Qnil; /* OK */ struct SCOPE *saved_scope; volatile int safe = ruby_safe_level; + if (OBJ_TAINTED(cmd)) { + level = 4; + } if (TYPE(cmd) != T_STRING) { PUSH_ITER(ITER_NOT); - val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr); + PUSH_TAG(PROT_NONE); + ruby_safe_level = level; + if ((state = EXEC_TAG()) == 0) { + val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr); + } + ruby_safe_level = safe; + POP_TAG(); POP_ITER(); + if (state) JUMP_TAG(state); return val; } @@ -1692,9 +1702,7 @@ rb_eval_cmd(cmd, arg, tcheck) ruby_frame->self = ruby_top_self; PUSH_CREF(ruby_wrapper ? ruby_wrapper : rb_cObject); - if (tcheck && OBJ_TAINTED(cmd)) { - ruby_safe_level = 4; - } + ruby_safe_level = level; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { @@ -9537,9 +9545,9 @@ thread_reset_raised() static void rb_thread_ready _((rb_thread_t)); static VALUE -rb_trap_eval(cmd, sig) +rb_trap_eval(cmd, sig, safe) VALUE cmd; - int sig; + int sig, safe; { int state; VALUE val = Qnil; /* OK */ @@ -9550,7 +9558,7 @@ rb_trap_eval(cmd, sig) PUSH_TAG(PROT_NONE); PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { - val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0); + val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), safe); } POP_ITER(); POP_TAG(); @@ -9760,7 +9768,7 @@ static int th_raise_argc; static VALUE th_raise_argv[2]; static NODE *th_raise_node; static VALUE th_cmd; -static int th_sig; +static int th_sig, th_safe; static char *th_signm; #define RESTORE_NORMAL 1 @@ -9852,7 +9860,7 @@ rb_thread_switch(n) rb_interrupt(); break; case RESTORE_TRAP: - rb_trap_eval(th_cmd, th_sig); + rb_trap_eval(th_cmd, th_sig, th_safe); break; case RESTORE_RAISE: ruby_frame->last_func = 0; @@ -11784,9 +11792,9 @@ rb_thread_signal_raise(sig) } void -rb_thread_trap_eval(cmd, sig) +rb_thread_trap_eval(cmd, sig, safe) VALUE cmd; - int sig; + int sig, safe; { rb_thread_critical = 0; if (!rb_thread_dead(curr_thread)) { @@ -11796,6 +11804,7 @@ rb_thread_trap_eval(cmd, sig) } th_cmd = cmd; th_sig = sig; + th_safe = safe; curr_thread = main_thread; rb_thread_restore_context(curr_thread, RESTORE_TRAP); } diff --git a/gc.c b/gc.c index 8816193f26..c1f761f5ef 100644 --- a/gc.c +++ b/gc.c @@ -1674,6 +1674,8 @@ undefine_final(os, obj) return obj; } +#define NODE_FINAL NODE_LIT + /* * call-seq: * ObjectSpace.define_finalizer(obj, aProc=proc()) @@ -1702,6 +1704,8 @@ define_final(argc, argv, os) need_call_final = 1; FL_SET(obj, FL_FINALIZE); + block = (VALUE)rb_node_newnode(NODE_FINAL, block, ruby_safe_level, 0); + if (!finalizer_table) { finalizer_table = st_init_numtable(); } @@ -1732,7 +1736,7 @@ static VALUE run_single_final(args) VALUE *args; { - rb_eval_cmd(args[0], args[1], 0); + rb_eval_cmd(args[0], args[1], (int)args[2]); return Qnil; } @@ -1742,17 +1746,20 @@ run_final(obj) { long i; int status, critical_save = rb_thread_critical; - VALUE args[2], table; + VALUE args[3], table; rb_thread_critical = Qtrue; args[1] = rb_ary_new3(1, rb_obj_id(obj)); /* make obj into id */ + args[2] = (VALUE)ruby_safe_level; for (i=0; ilen; i++) { args[0] = RARRAY(finalizers)->ptr[i]; rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); } if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) { for (i=0; ilen; i++) { - args[0] = RARRAY(table)->ptr[i]; + NODE *final = (NODE *)RARRAY(table)->ptr[i]; + args[0] = final->nd_lit; + args[2] = final->nd_nth; rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); } } diff --git a/intern.h b/intern.h index 74c36d8fe5..88a5b8cb86 100644 --- a/intern.h +++ b/intern.h @@ -215,7 +215,7 @@ VALUE rb_thread_run _((VALUE)); VALUE rb_thread_kill _((VALUE)); VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*)); void rb_thread_interrupt _((void)); -void rb_thread_trap_eval _((VALUE, int)); +void rb_thread_trap_eval _((VALUE, int, int)); void rb_thread_signal_raise _((char*)); int rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *)); void rb_thread_wait_for _((struct timeval)); diff --git a/signal.c b/signal.c index bafaadd8bc..c45d3c95f4 100644 --- a/signal.c +++ b/signal.c @@ -298,7 +298,10 @@ rb_f_kill(argc, argv) return INT2FIX(i-1); } -static VALUE trap_list[NSIG]; +static struct { + VALUE cmd; + int safe; +} trap_list[NSIG]; static rb_atomic_t trap_pending_list[NSIG]; rb_atomic_t rb_trap_pending; rb_atomic_t rb_trap_immediate; @@ -311,8 +314,8 @@ rb_gc_mark_trap_list() int i; for (i=0; i