Project

General

Profile

Bug #4438 ยป 0001-check-rescue-clause-arguments.patch

nobu (Nobuyoshi Nakada), 08/06/2012 10:33 PM

View differences:

compile.c
3208 3208
		  case NODE_ARGSPUSH:
3209 3209
		    only_special_literals = 0;
3210 3210
		    COMPILE(cond_seq, "when/cond splat", vals);
3211
		    ADD_INSN1(cond_seq, nd_line(vals), checkincludearray, Qtrue);
3211
		    ADD_INSN1(cond_seq, nd_line(vals), checkincludearray, INT2FIX(0));
3212 3212
		    ADD_INSNL(cond_seq, nd_line(vals), branchif, l1);
3213 3213
		    break;
3214 3214
		  default:
......
3289 3289
	      case NODE_ARGSPUSH:
3290 3290
		ADD_INSN(ret, nd_line(vals), putnil);
3291 3291
		COMPILE(ret, "when2/cond splat", vals);
3292
		ADD_INSN1(ret, nd_line(vals), checkincludearray, Qfalse);
3292
		ADD_INSN1(ret, nd_line(vals), checkincludearray, INT2FIX(1));
3293 3293
		ADD_INSN(ret, nd_line(vals), pop);
3294 3294
		ADD_INSNL(ret, nd_line(vals), branchif, l1);
3295 3295
		break;
......
3687 3687
		switch (nd_type(narg)) {
3688 3688
		  case NODE_ARRAY:
3689 3689
		    while (narg) {
3690
			ADD_INSN1(ret, nd_line(narg), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
3690 3691
			COMPILE(ret, "rescue arg", narg->nd_head);
3692
			ADD_SEND(ret, nd_line(narg), ID2SYM(id_core_check_rescuable), INT2FIX(1));
3691 3693
			ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
3692 3694
			ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
3693 3695
			ADD_INSNL(ret, nd_line(node), branchif, label_hit);
......
3699 3701
		  case NODE_ARGSPUSH:
3700 3702
		    ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
3701 3703
		    COMPILE(ret, "rescue/cond splat", narg);
3702
		    ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue);
3704
		    ADD_INSN1(ret, nd_line(node), checkincludearray, INT2FIX(2));
3703 3705
		    ADD_INSN(ret, nd_line(node), swap);
3704 3706
		    ADD_INSN(ret, nd_line(node), pop);
3705 3707
		    ADD_INSNL(ret, nd_line(node), branchif, label_hit);
id.c
35 35
    REGISTER_SYMID(id_core_hash_merge_ary,          "core#hash_merge_ary");
36 36
    REGISTER_SYMID(id_core_hash_merge_ptr,          "core#hash_merge_ptr");
37 37
    REGISTER_SYMID(id_core_hash_merge_kwd,          "core#hash_merge_kwd");
38
    REGISTER_SYMID(id_core_check_rescuable,         "core#check_rescuable");
38 39

  
39 40
    REGISTER_SYMID(idEach, "each");
40 41
    REGISTER_SYMID(idLength, "length");
insns.def
557 557
	ary = rb_Array(ary);
558 558
    }
559 559

  
560
    if (flag == Qtrue) {
560
    switch (flag) {
561
      case INT2FIX(0):
561 562
	/* NODE_CASE */
562 563
	for (i = 0; i < RARRAY_LEN(ary); i++) {
563 564
	    /* TODO: fix me (use another method dispatch) */
......
566 567
		break;
567 568
	    }
568 569
	}
569
    }
570
    else {
570
	break;
571
      case INT2FIX(1):
571 572
	obj = Qfalse;
572 573
	/* NODE_WHEN */
573 574
	for (i = 0; i < RARRAY_LEN(ary); i++) {
......
576 577
		break;
577 578
	    }
578 579
	}
580
	break;
581
      case INT2FIX(2):
582
	/* NODE_RESBODY */
583
	for (i = 0; i < RARRAY_LEN(ary); i++) {
584
	    void rb_vm_error_invalid_rescue(VALUE);
585
	    VALUE mod = RARRAY_PTR(ary)[i];
586
	    if (!rb_obj_is_kind_of(mod, rb_cModule)) {
587
		rb_vm_error_invalid_rescue(mod);
588
	    }
589
	    if (RTEST(rb_funcall2(mod, idEqq, 1, &obj))) {
590
		result = Qtrue;
591
		break;
592
	    }
593
	}
594
	break;
579 595
    }
580 596
}
581 597

  
parse.y
814 814
%nonassoc id_core_hash_merge_ary
815 815
%nonassoc id_core_hash_merge_ptr
816 816
%nonassoc id_core_hash_merge_kwd
817
%nonassoc id_core_check_rescuable
817 818

  
818 819
%token tLAST_TOKEN
819 820

  
test/ruby/test_exception.rb
209 209
    end
210 210
  end
211 211

  
212
  Bug4438 = '[ruby-core:35364]'
213

  
214
  def test_rescue_single_argument
215
    assert_raise(TypeError, Bug4438) do
216
      begin
217
        raise
218
      rescue 1
219
      end
220
    end
221
  end
222

  
223
  def test_rescue_splat_argument
224
    assert_raise(TypeError, Bug4438) do
225
      begin
226
        raise
227
      rescue *Array(1)
228
      end
229
    end
230
  end
231

  
212 232
  def test_raise_with_wrong_number_of_arguments
213 233
    assert_raise(TypeError) { raise nil }
214 234
    assert_raise(TypeError) { raise 1, 1 }
vm.c
2003 2003
    return hash;
2004 2004
}
2005 2005

  
2006
void
2007
rb_vm_error_invalid_rescue(VALUE mod)
2008
{
2009
    rb_raise(rb_eTypeError, "class or module required for rescue clause");
2010
}
2011

  
2012
static VALUE
2013
m_core_check_rescuable(VALUE recv, VALUE mod)
2014
{
2015
    if (!rb_obj_is_kind_of(mod, rb_cModule)) {
2016
	vm_pop_frame(GET_THREAD());
2017
	rb_vm_error_invalid_rescue(mod);
2018
    }
2019
    return mod;
2020
}
2021

  
2006 2022
extern VALUE *rb_gc_stack_start;
2007 2023
extern size_t rb_gc_stack_maxsize;
2008 2024
#ifdef __ia64
......
2070 2086
    rb_define_method_id(klass, id_core_hash_merge_ary, m_core_hash_merge_ary, 2);
2071 2087
    rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1);
2072 2088
    rb_define_method_id(klass, id_core_hash_merge_kwd, m_core_hash_merge_kwd, 2);
2089
    rb_define_method_id(klass, id_core_check_rescuable, m_core_check_rescuable, 1);
2073 2090
    rb_obj_freeze(fcore);
2074 2091
    rb_gc_register_mark_object(fcore);
2075 2092
    rb_mRubyVMFrozenCore = fcore;
2076
-