* insnhelper.ci (vm_call_method): fix to relaxant safe level check
($SAFE > 2). [ruby-core:11998] * bootstraptest/test_method.rb: add tests for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13275 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cf16f0de0f
commit
343c363d5b
@ -1,3 +1,10 @@
|
|||||||
|
Sun Aug 26 05:54:49 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* insnhelper.ci (vm_call_method): fix to relaxant safe level check
|
||||||
|
($SAFE > 2). [ruby-core:11998]
|
||||||
|
|
||||||
|
* bootstraptest/test_method.rb: add tests for above.
|
||||||
|
|
||||||
Sun Aug 26 05:52:08 2007 Koichi Sasada <ko1@atdot.net>
|
Sun Aug 26 05:52:08 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* test/ruby/test_fiber.rb: fix to require 'continuation'.
|
* test/ruby/test_fiber.rb: fix to require 'continuation'.
|
||||||
|
@ -916,3 +916,44 @@ assert_equal 'ok', %q{
|
|||||||
end
|
end
|
||||||
C.new.m
|
C.new.m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
proc{
|
||||||
|
$SAFE = 1
|
||||||
|
class C
|
||||||
|
def m
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}.call
|
||||||
|
C.new.m
|
||||||
|
}, '[ruby-core:11998]'
|
||||||
|
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
proc{
|
||||||
|
$SAFE = 2
|
||||||
|
class C
|
||||||
|
def m
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}.call
|
||||||
|
C.new.m
|
||||||
|
}, '[ruby-core:11998]'
|
||||||
|
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
proc{
|
||||||
|
$SAFE = 3
|
||||||
|
class C
|
||||||
|
def m
|
||||||
|
:ng
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}.call
|
||||||
|
begin
|
||||||
|
C.new.m
|
||||||
|
rescue SecurityError
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
}, '[ruby-core:11998]'
|
||||||
|
|
||||||
|
173
insnhelper.ci
173
insnhelper.ci
@ -472,8 +472,96 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
|||||||
|
|
||||||
start_method_dispatch:
|
start_method_dispatch:
|
||||||
|
|
||||||
/* method missing */
|
if ((mn != 0)) {
|
||||||
if (mn == 0) {
|
if ((mn->nd_noex == 0)) {
|
||||||
|
/* dispatch method */
|
||||||
|
NODE *node;
|
||||||
|
|
||||||
|
normal_method_dispatch:
|
||||||
|
|
||||||
|
node = mn->nd_body;
|
||||||
|
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case RUBY_VM_METHOD_NODE:{
|
||||||
|
vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
|
||||||
|
return Qundef;
|
||||||
|
}
|
||||||
|
case NODE_CFUNC:{
|
||||||
|
val = vm_call_cfunc(th, cfp, num, id, recv, klass, node, blockptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_ATTRSET:{
|
||||||
|
val = rb_ivar_set(recv, node->nd_vid, *(cfp->sp - 1));
|
||||||
|
cfp->sp -= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_IVAR:{
|
||||||
|
val = rb_ivar_get(recv, node->nd_vid);
|
||||||
|
cfp->sp -= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_BMETHOD:{
|
||||||
|
VALUE *argv = cfp->sp - num;
|
||||||
|
val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv);
|
||||||
|
cfp->sp += - num - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_ZSUPER:{
|
||||||
|
klass = RCLASS(mn->nd_clss)->super;
|
||||||
|
mn = rb_method_node(klass, id);
|
||||||
|
|
||||||
|
if (mn != 0) {
|
||||||
|
goto normal_method_dispatch;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto start_method_dispatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
printf("node: %s\n", ruby_node_name(nd_type(node)));
|
||||||
|
rb_bug("eval_invoke_method: unreachable");
|
||||||
|
/* unreachable */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int noex_safe;
|
||||||
|
|
||||||
|
if (!(flag & VM_CALL_FCALL_BIT) &&
|
||||||
|
(mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
|
||||||
|
int stat = NOEX_PRIVATE;
|
||||||
|
|
||||||
|
if (flag & VM_CALL_VCALL_BIT) {
|
||||||
|
stat |= NOEX_VCALL;
|
||||||
|
}
|
||||||
|
val = vm_method_missing(th, id, recv, num, blockptr, stat);
|
||||||
|
}
|
||||||
|
else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
|
||||||
|
VALUE defined_class = mn->nd_clss;
|
||||||
|
|
||||||
|
if (TYPE(defined_class) == T_ICLASS) {
|
||||||
|
defined_class = RBASIC(defined_class)->klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rb_obj_is_kind_of(cfp->self, rb_class_real(defined_class))) {
|
||||||
|
val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto normal_method_dispatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((noex_safe = NOEX_SAFE(mn->nd_noex)) > th->safe_level &&
|
||||||
|
(noex_safe > 2)) {
|
||||||
|
rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto normal_method_dispatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* method missing */
|
||||||
if (id == idMethodMissing) {
|
if (id == idMethodMissing) {
|
||||||
rb_bug("method missing");
|
rb_bug("method missing");
|
||||||
}
|
}
|
||||||
@ -488,87 +576,6 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
|||||||
val = vm_method_missing(th, id, recv, num, blockptr, stat);
|
val = vm_method_missing(th, id, recv, num, blockptr, stat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (UNLIKELY(mn->nd_noex)) {
|
|
||||||
if (!(flag & VM_CALL_FCALL_BIT) &&
|
|
||||||
(mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
|
|
||||||
int stat = NOEX_PRIVATE;
|
|
||||||
if (flag & VM_CALL_VCALL_BIT) {
|
|
||||||
stat |= NOEX_VCALL;
|
|
||||||
}
|
|
||||||
val = vm_method_missing(th, id, recv, num, blockptr, stat);
|
|
||||||
}
|
|
||||||
else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
|
|
||||||
VALUE defined_class = mn->nd_clss;
|
|
||||||
|
|
||||||
if (TYPE(defined_class) == T_ICLASS) {
|
|
||||||
defined_class = RBASIC(defined_class)->klass;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rb_obj_is_kind_of(cfp->self, rb_class_real(defined_class))) {
|
|
||||||
val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto normal_method_dispatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (NOEX_SAFE(mn->nd_noex) > th->safe_level) {
|
|
||||||
rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto normal_method_dispatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dispatch method */
|
|
||||||
else {
|
|
||||||
NODE *node;
|
|
||||||
normal_method_dispatch:
|
|
||||||
|
|
||||||
node = mn->nd_body;
|
|
||||||
switch (nd_type(node)) {
|
|
||||||
case RUBY_VM_METHOD_NODE:{
|
|
||||||
vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
|
|
||||||
return Qundef;
|
|
||||||
}
|
|
||||||
case NODE_CFUNC:{
|
|
||||||
val = vm_call_cfunc(th, cfp, num, id, recv, klass, node, blockptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_ATTRSET:{
|
|
||||||
val = rb_ivar_set(recv, node->nd_vid, *(cfp->sp - 1));
|
|
||||||
cfp->sp -= 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_IVAR:{
|
|
||||||
val = rb_ivar_get(recv, node->nd_vid);
|
|
||||||
cfp->sp -= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_BMETHOD:{
|
|
||||||
VALUE *argv = cfp->sp - num;
|
|
||||||
val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv);
|
|
||||||
cfp->sp += - num - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_ZSUPER:{
|
|
||||||
klass = RCLASS(mn->nd_clss)->super;
|
|
||||||
mn = rb_method_node(klass, id);
|
|
||||||
|
|
||||||
if (mn != 0) {
|
|
||||||
goto normal_method_dispatch;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto start_method_dispatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
printf("node: %s\n", ruby_node_name(nd_type(node)));
|
|
||||||
rb_bug("eval_invoke_method: unreachable");
|
|
||||||
/* unreachable */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS();
|
RUBY_VM_CHECK_INTS();
|
||||||
return val;
|
return val;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user