* 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>
|
||||
|
||||
* test/ruby/test_fiber.rb: fix to require 'continuation'.
|
||||
|
@ -916,3 +916,44 @@ assert_equal 'ok', %q{
|
||||
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]'
|
||||
|
||||
|
103
insnhelper.ci
103
insnhelper.ci
@ -472,59 +472,15 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
||||
|
||||
start_method_dispatch:
|
||||
|
||||
/* method missing */
|
||||
if (mn == 0) {
|
||||
if (id == idMethodMissing) {
|
||||
rb_bug("method missing");
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mn != 0)) {
|
||||
if ((mn->nd_noex == 0)) {
|
||||
/* 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);
|
||||
@ -569,6 +525,57 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
rb_bug("method missing");
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
RUBY_VM_CHECK_INTS();
|
||||
return val;
|
||||
|
Loading…
x
Reference in New Issue
Block a user