summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-25 20:56:51 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-25 20:56:51 +0000
commit343c363d5b1374f3aca6f9ba6d755a156d03f3f5 (patch)
tree59306515b95c4da5997a2a1380652d9f6764ae32
parentcf16f0de0f01cbabec98e6efe8bcaaef2edeefe1 (diff)
* 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
-rw-r--r--ChangeLog7
-rw-r--r--bootstraptest/test_method.rb41
-rw-r--r--insnhelper.ci169
3 files changed, 136 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index 90e791c4c5..38dd02d4d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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'.
diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb
index 776d6274a3..bca80087bb 100644
--- a/bootstraptest/test_method.rb
+++ b/bootstraptest/test_method.rb
@@ -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]'
+
diff --git a/insnhelper.ci b/insnhelper.ci
index a5cc0dfcc7..7f1a8ef6f2 100644
--- a/insnhelper.ci
+++ b/insnhelper.ci
@@ -472,101 +472,108 @@ 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 ((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;
+ }
}
- 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;
+ else {
+ int noex_safe;
+
+ if (!(flag & VM_CALL_FCALL_BIT) &&
+ (mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
+ int stat = NOEX_PRIVATE;
- if (TYPE(defined_class) == T_ICLASS) {
- defined_class = RBASIC(defined_class)->klass;
+ 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);
+ 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 {
- 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;
+ /* method missing */
+ if (id == idMethodMissing) {
+ rb_bug("method missing");
+ }
+ else {
+ 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);
}
}