mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
eval.c: hide internal objects
* eval.c (rb_ensure): veil internal exception objects not to leak in ensure functions. [ruby-core:79371] [Bug #13176] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57510 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c2a6adc5fb
commit
2aaca10505
3 changed files with 36 additions and 1 deletions
5
eval.c
5
eval.c
|
@ -924,7 +924,7 @@ rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE
|
|||
{
|
||||
int state;
|
||||
volatile VALUE result = Qnil;
|
||||
volatile VALUE errinfo;
|
||||
VALUE errinfo;
|
||||
rb_thread_t *const th = GET_THREAD();
|
||||
rb_ensure_list_t ensure_list;
|
||||
ensure_list.entry.marker = 0;
|
||||
|
@ -938,6 +938,9 @@ rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE
|
|||
}
|
||||
TH_POP_TAG();
|
||||
errinfo = th->errinfo;
|
||||
if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
|
||||
th->errinfo = Qnil;
|
||||
}
|
||||
th->ensure_list=ensure_list.next;
|
||||
(*ensure_list.entry.e_proc)(ensure_list.entry.data2);
|
||||
th->errinfo = errinfo;
|
||||
|
|
|
@ -18,8 +18,22 @@ ensured(VALUE module, VALUE object)
|
|||
return rb_ensure(begin, object, ensure, object);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
raise(VALUE exc)
|
||||
{
|
||||
rb_exc_raise(exc);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ensure_raise(VALUE module, VALUE object, VALUE exc)
|
||||
{
|
||||
return rb_ensure(rb_yield, object, raise, exc);
|
||||
}
|
||||
|
||||
void
|
||||
Init_ensured(VALUE klass)
|
||||
{
|
||||
rb_define_module_function(klass, "ensured", ensured, 1);
|
||||
rb_define_module_function(klass, "ensure_raise", ensure_raise, 2);
|
||||
}
|
||||
|
|
18
test/-ext-/exception/test_exception_at_throwing.rb
Normal file
18
test/-ext-/exception/test_exception_at_throwing.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
require 'test/unit'
|
||||
|
||||
module Bug
|
||||
class TestException < Test::Unit::TestCase
|
||||
def test_exception_at_throwing
|
||||
assert_separately(%w[-r-test-/exception], "#{<<-"begin;"}\n#{<<-"end;"}")
|
||||
begin;
|
||||
e = RuntimeError.new("[Bug #13176]")
|
||||
assert_raise_with_message(e.class, e.message) do
|
||||
catch do |t|
|
||||
Bug::Exception.ensure_raise(nil, e) {throw t}
|
||||
end
|
||||
end
|
||||
end;
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue