diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | eval.c | 48 |
2 files changed, 36 insertions, 25 deletions
@@ -46,6 +46,11 @@ Mon Aug 29 19:54:21 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp> * lib/rdoc/usage.rb: support the case when non-ruby code exists before shebang. (this is needed when ri.bat is executed on windows) +Mon Aug 29 17:48:17 2005 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (method_arity): should return proper arity value. + [ruby-dev:26390] + Mon Aug 29 01:19:57 2005 Tanaka Akira <akr@m17n.org> * lib/time.rb (Time.parse): extract fractional seconds using @@ -102,6 +107,14 @@ Wed Aug 17 23:58:05 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * eval.c (rb_thread_switch): propagate the exception caused thread termination directly. fixed: [ruby-core:05552] +Wed Aug 17 00:05:46 2005 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_add_method): preserve safe level in the environment + where a method is defined . + + * eval.c (rb_call0): restore preserved safe level in the method + execution. + Mon Aug 15 00:38:51 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * eval.c (rb_rescue2): reduce PUSH_TAG() as well as NODE_RESCUE. @@ -363,6 +363,9 @@ static ID init, eqq, each, aref, aset, match, missing; static ID added, singleton_added; static ID __id__, __send__, respond_to; +#define NOEX_WITH_SAFE(n) ((n) | ruby_safe_level << 4) +#define NOEX_SAFE(n) ((n) >> 4) + void rb_add_method(klass, mid, node, noex) VALUE klass; @@ -389,7 +392,7 @@ rb_add_method(klass, mid, node, noex) } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); rb_clear_cache_by_id(mid); - body = NEW_METHOD(node, noex); + body = NEW_METHOD(node, NOEX_WITH_SAFE(noex)); st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body); if (node && mid != ID_ALLOCATOR && ruby_running) { if (FL_TEST(klass, FL_SINGLETON)) { @@ -5595,20 +5598,21 @@ call_cfunc(func, recv, len, argc, argv) } static VALUE -rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) +rb_call0(klass, recv, id, oid, argc, argv, body, flags) VALUE klass, recv; ID id; ID oid; int argc; /* OK */ VALUE *argv; /* OK */ NODE * volatile body; - int nosuper; + int flags; { NODE *b2; /* OK */ volatile VALUE result = Qnil; int itr; static int tick; TMP_PROTECT; + volatile int safe = -1; switch (ruby_iter->iter) { case ITER_PRE: @@ -5631,7 +5635,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) ruby_frame->last_func = id; ruby_frame->orig_func = oid; - ruby_frame->last_class = nosuper?0:klass; + ruby_frame->last_class = (flags & NOEX_NOSUPER)?0:klass; ruby_frame->self = recv; ruby_frame->argc = argc; ruby_frame->argv = argv; @@ -5695,7 +5699,6 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) NODE *saved_cref = 0; PUSH_SCOPE(); - if (body->nd_rval) { saved_cref = ruby_cref; ruby_cref = (NODE*)body->nd_rval; @@ -5716,7 +5719,10 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) PUSH_VARS(); PUSH_TAG(PROT_FUNC); - + if (NOEX_SAFE(flags) > ruby_safe_level) { + safe = ruby_safe_level; + ruby_safe_level = NOEX_SAFE(flags); + } if ((state = EXEC_TAG()) == 0) { NODE *node = 0; int i; @@ -5800,6 +5806,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) POP_CLASS(); POP_SCOPE(); ruby_cref = saved_cref; + if (safe > 0) ruby_safe_level = safe; if (event_hooks) { EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass); } @@ -5882,7 +5889,7 @@ rb_call(klass, recv, mid, argc, argv, scope) } } - return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER); + return rb_call0(klass, recv, mid, id, argc, argv, body, noex); } VALUE @@ -8622,10 +8629,9 @@ block_pass(self, node) proc = b; } - if (ruby_safe_level >= 1 && OBJ_TAINTED(proc)) { - if (ruby_safe_level > proc_get_safe_level(proc)) { - rb_raise(rb_eSecurityError, "Insecure: tainted block value"); - } + if (ruby_safe_level >= 1 && OBJ_TAINTED(proc) && + ruby_safe_level > proc_get_safe_level(proc)) { + rb_raise(rb_eSecurityError, "Insecure: tainted block value"); } if (ruby_block && ruby_block->block_obj == proc) { @@ -8688,6 +8694,7 @@ struct METHOD { VALUE klass, rklass; VALUE recv; ID id, oid; + int safe_level; NODE *body; }; @@ -8735,6 +8742,7 @@ mnew(klass, obj, id, mklass) data->body = body; data->rklass = rklass; data->oid = oid; + data->safe_level = NOEX_WITH_SAFE(0); OBJ_INFECT(method, klass); return method; @@ -8940,26 +8948,15 @@ method_call(argc, argv, method) { VALUE result = Qnil; /* OK */ struct METHOD *data; - int state; - volatile int safe = -1; Data_Get_Struct(method, struct METHOD, data); if (data->recv == Qundef) { rb_raise(rb_eTypeError, "can't call unbound method; bind first"); } PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT); - PUSH_TAG(PROT_NONE); - if (OBJ_TAINTED(method)) { - safe = ruby_safe_level; - if (ruby_safe_level < 4) ruby_safe_level = 4; - } - if ((state = EXEC_TAG()) == 0) { - result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0); - } - POP_TAG(); + result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body, + data->safe_level); POP_ITER(); - if (safe >= 0) ruby_safe_level = safe; - if (state) JUMP_TAG(state); return result; } @@ -9134,8 +9131,9 @@ method_arity(method) case NODE_IVAR: return INT2FIX(0); case NODE_BMETHOD: - case NODE_DMETHOD: return proc_arity(body->nd_cval); + case NODE_DMETHOD: + return method_arity(body->nd_cval); default: body = body->nd_next; /* skip NODE_SCOPE */ if (nd_type(body) == NODE_BLOCK) |