summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-01 06:56:07 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-01 06:56:07 +0000
commitc704c569d58678471187031ecf6e492827f75fde (patch)
tree3685be3b19f88fe6d23b8d1f83395bd0fda247ae /eval.c
parent9138b29822aa326e23bb948ec3f25faa001702ef (diff)
* eval.c (method_arity): should return proper arity value.
[ruby-dev:26390] * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@9063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/eval.c b/eval.c
index 3a1acda1b2..159f754c14 100644
--- a/eval.c
+++ b/eval.c
@@ -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)