Skip to content

Commit aa2b32a

Browse files
committed
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
1 parent a7c7cfb commit aa2b32a

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

error.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,16 @@ exc_to_s(VALUE exc)
980980
}
981981

982982
/* FIXME: Include eval_error.c */
983-
void rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
983+
void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
984+
985+
VALUE
986+
rb_get_message(VALUE exc)
987+
{
988+
VALUE e = rb_check_funcall(exc, id_message, 0, 0);
989+
if (e == Qundef) return Qnil;
990+
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
991+
return e;
992+
}
984993

985994
/*
986995
* call-seq:
@@ -1015,7 +1024,7 @@ exc_s_to_tty_p(VALUE self)
10151024
static VALUE
10161025
exc_full_message(int argc, VALUE *argv, VALUE exc)
10171026
{
1018-
VALUE opt, str, errat;
1027+
VALUE opt, str, emesg, errat;
10191028
enum {kw_highlight, kw_order, kw_max_};
10201029
static ID kw[kw_max_];
10211030
VALUE args[kw_max_] = {Qnil, Qnil};
@@ -1051,8 +1060,9 @@ exc_full_message(int argc, VALUE *argv, VALUE exc)
10511060
}
10521061
str = rb_str_new2("");
10531062
errat = rb_get_backtrace(exc);
1063+
emesg = rb_get_message(exc);
10541064

1055-
rb_error_write(exc, errat, str, args[kw_highlight], args[kw_order]);
1065+
rb_error_write(exc, emesg, errat, str, args[kw_highlight], args[kw_order]);
10561066
return str;
10571067
}
10581068

eval_error.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,23 +221,17 @@ print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reve
221221
}
222222

223223
void
224-
rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
224+
rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
225225
{
226-
volatile VALUE eclass = Qundef, emesg = Qundef;
226+
volatile VALUE eclass;
227227

228228
if (NIL_P(errinfo))
229229
return;
230230

231231
if (errat == Qundef) {
232232
errat = Qnil;
233233
}
234-
if ((eclass = CLASS_OF(errinfo)) != Qundef) {
235-
VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0);
236-
if (e != Qundef) {
237-
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
238-
emesg = e;
239-
}
240-
}
234+
eclass = CLASS_OF(errinfo);
241235
if (NIL_P(reverse) || NIL_P(highlight)) {
242236
VALUE tty = (VALUE)rb_stderr_tty_p();
243237
if (NIL_P(reverse)) reverse = tty;
@@ -269,11 +263,14 @@ rb_error_write(VALUE errinfo, VALUE errat, VALUE str, VALUE highlight, VALUE rev
269263
}
270264
}
271265

266+
VALUE rb_get_message(VALUE exc);
267+
272268
void
273269
rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
274270
{
275271
volatile int raised_flag = ec->raised_flag;
276272
volatile VALUE errat = Qundef;
273+
volatile VALUE emesg = Qundef;
277274

278275
if (NIL_P(errinfo))
279276
return;
@@ -283,8 +280,12 @@ rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
283280
if (EC_EXEC_TAG() == TAG_NONE) {
284281
errat = rb_get_backtrace(errinfo);
285282
}
283+
if (emesg == Qundef) {
284+
emesg = Qnil;
285+
emesg = rb_get_message(errinfo);
286+
}
286287

287-
rb_error_write(errinfo, errat, Qnil, Qnil, Qnil);
288+
rb_error_write(errinfo, emesg, errat, Qnil, Qnil, Qnil);
288289

289290
EC_POP_TAG();
290291
ec->errinfo = errinfo;

test/ruby/test_exception.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,4 +1309,15 @@ def test_full_message
13091309
assert_operator(message, :end_with?, top)
13101310
end
13111311
end
1312+
1313+
def test_exception_in_message
1314+
code = "#{<<~"begin;"}\n#{<<~'end;'}"
1315+
begin;
1316+
class Bug14566 < StandardError
1317+
def message; raise self.class; end
1318+
end
1319+
raise Bug14566
1320+
end;
1321+
assert_in_out_err([], code, [], /Bug14566/, success: false, timeout: 1)
1322+
end
13121323
end

0 commit comments

Comments
 (0)