[前][次][番号順一覧][スレッド一覧]

ruby-changes:50926

From: nobu <ko1@a...>
Date: Wed, 11 Apr 2018 17:03:48 +0900 (JST)
Subject: [ruby-changes:50926] nobu:r63133 (trunk): eval_error.c: fix loop on exception in message

nobu	2018-04-11 17:03:43 +0900 (Wed, 11 Apr 2018)

  New Revision: 63133

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63133

  Log:
    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]

  Modified files:
    trunk/error.c
    trunk/eval_error.c
    trunk/test/ruby/test_exception.rb
Index: eval_error.c
===================================================================
--- eval_error.c	(revision 63132)
+++ eval_error.c	(revision 63133)
@@ -221,9 +221,9 @@ print_backtrace(const VALUE eclass, cons https://github.com/ruby/ruby/blob/trunk/eval_error.c#L221
 }
 
 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 erra https://github.com/ruby/ruby/blob/trunk/eval_error.c#L231
     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 erra https://github.com/ruby/ruby/blob/trunk/eval_error.c#L263
     }
 }
 
+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 https://github.com/ruby/ruby/blob/trunk/eval_error.c#L280
     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;
Index: error.c
===================================================================
--- error.c	(revision 63132)
+++ error.c	(revision 63133)
@@ -980,7 +980,16 @@ exc_to_s(VALUE exc) https://github.com/ruby/ruby/blob/trunk/error.c#L980
 }
 
 /* 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) https://github.com/ruby/ruby/blob/trunk/error.c#L1024
 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, https://github.com/ruby/ruby/blob/trunk/error.c#L1060
     }
     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;
 }
 
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 63132)
+++ test/ruby/test_exception.rb	(revision 63133)
@@ -1309,4 +1309,15 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L1309
       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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]