1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

eval_error.c: fix loop on exception in message

* error.c (rb_get_message): accessor to the message.

* eval_error.c (rb_ec_error_print): handle exceptions on fetching
  the message.  [Bug #14566]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63133 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-04-11 08:03:43 +00:00
parent a7c7cfb874
commit aa2b32ae4b
3 changed files with 35 additions and 13 deletions

16
error.c
View file

@ -980,7 +980,16 @@ exc_to_s(VALUE exc)
}
/* FIXME: Include eval_error.c */
void rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
VALUE
rb_get_message(VALUE exc)
{
VALUE e = rb_check_funcall(exc, id_message, 0, 0);
if (e == Qundef) return Qnil;
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
return e;
}
/*
* call-seq:
@ -1015,7 +1024,7 @@ exc_s_to_tty_p(VALUE self)
static VALUE
exc_full_message(int argc, VALUE *argv, VALUE exc)
{
VALUE opt, str, errat;
VALUE opt, str, emesg, errat;
enum {kw_highlight, kw_order, kw_max_};
static ID kw[kw_max_];
VALUE args[kw_max_] = {Qnil, Qnil};
@ -1051,8 +1060,9 @@ exc_full_message(int argc, VALUE *argv, VALUE exc)
}
str = rb_str_new2("");
errat = rb_get_backtrace(exc);
emesg = rb_get_message(exc);
rb_error_write(exc, errat, str, args[kw_highlight], args[kw_order]);
rb_error_write(exc, emesg, errat, str, args[kw_highlight], args[kw_order]);
return str;
}

View file

@ -221,9 +221,9 @@ print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reve
}
void
rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
{
volatile VALUE eclass = Qundef, emesg = Qundef;
volatile VALUE eclass;
if (NIL_P(errinfo))
return;
@ -231,13 +231,7 @@ rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE rev
if (errat == Qundef) {
errat = Qnil;
}
if ((eclass = CLASS_OF(errinfo)) != Qundef) {
VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0);
if (e != Qundef) {
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
emesg = e;
}
}
eclass = CLASS_OF(errinfo);
if (NIL_P(reverse) || NIL_P(highlight)) {
VALUE tty = (VALUE)rb_stderr_tty_p();
if (NIL_P(reverse)) reverse = tty;
@ -269,11 +263,14 @@ rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE rev
}
}
VALUE rb_get_message(VALUE exc);
void
rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
{
volatile int raised_flag = ec->raised_flag;
volatile VALUE errat = Qundef;
volatile VALUE emesg = Qundef;
if (NIL_P(errinfo))
return;
@ -283,8 +280,12 @@ rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
if (EC_EXEC_TAG() == TAG_NONE) {
errat = rb_get_backtrace(errinfo);
}
if (emesg == Qundef) {
emesg = Qnil;
emesg = rb_get_message(errinfo);
}
rb_error_write(errinfo, errat, Qnil, Qnil, Qnil);
rb_error_write(errinfo, emesg, errat, Qnil, Qnil, Qnil);
EC_POP_TAG();
ec->errinfo = errinfo;

View file

@ -1309,4 +1309,15 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
assert_operator(message, :end_with?, top)
end
end
def test_exception_in_message
code = "#{<<~"begin;"}\n#{<<~'end;'}"
begin;
class Bug14566 < StandardError
def message; raise self.class; end
end
raise Bug14566
end;
assert_in_out_err([], code, [], /Bug14566/, success: false, timeout: 1)
end
end