ruby-changes:1784
From: ko1@a...
Date: 26 Aug 2007 05:57:00 +0900
Subject: [ruby-changes:1784] ko1 - Ruby:r13275 (trunk): * insnhelper.ci (vm_call_method): fix to relaxant safe level check
ko1 2007-08-26 05:56:51 +0900 (Sun, 26 Aug 2007) New Revision: 13275 Modified files: trunk/ChangeLog trunk/bootstraptest/test_method.rb trunk/insnhelper.ci Log: * insnhelper.ci (vm_call_method): fix to relaxant safe level check ($SAFE > 2). [ruby-core:11998] * bootstraptest/test_method.rb: add tests for above. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insnhelper.ci?r1=13275&r2=13274 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13275&r2=13274 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_method.rb?r1=13275&r2=13274 Index: ChangeLog =================================================================== --- ChangeLog (revision 13274) +++ ChangeLog (revision 13275) @@ -1,3 +1,10 @@ +Sun Aug 26 05:54:49 2007 Koichi Sasada <ko1@a...> + + * 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@a...> * test/ruby/test_fiber.rb: fix to require 'continuation'. Index: bootstraptest/test_method.rb =================================================================== --- bootstraptest/test_method.rb (revision 13274) +++ bootstraptest/test_method.rb (revision 13275) @@ -916,3 +916,44 @@ end 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]' + Index: insnhelper.ci =================================================================== --- insnhelper.ci (revision 13274) +++ insnhelper.ci (revision 13275) @@ -472,101 +472,108 @@ start_method_dispatch: - /* method missing */ - if (mn == 0) { - if (id == idMethodMissing) { - rb_bug("method missing"); + 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 stat = 0; - if (flag & VM_CALL_VCALL_BIT) { - stat |= NOEX_VCALL; - } - if (flag & VM_CALL_SUPER_BIT) { - stat |= NOEX_SUPER; - } - 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; + int noex_safe; - if (TYPE(defined_class) == T_ICLASS) { - defined_class = RBASIC(defined_class)->klass; + 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 (!rb_obj_is_kind_of(cfp->self, rb_class_real(defined_class))) { - val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED); + 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 if (NOEX_SAFE(mn->nd_noex) > th->safe_level) { - rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id)); + } + else { + /* method missing */ + if (id == idMethodMissing) { + rb_bug("method missing"); } 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; + int stat = 0; + if (flag & VM_CALL_VCALL_BIT) { + stat |= NOEX_VCALL; } - else { - goto start_method_dispatch; + if (flag & VM_CALL_SUPER_BIT) { + stat |= NOEX_SUPER; } - } - default:{ - printf("node: %s\n", ruby_node_name(nd_type(node))); - rb_bug("eval_invoke_method: unreachable"); - /* unreachable */ - break; - } + val = vm_method_missing(th, id, recv, num, blockptr, stat); } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml