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

ruby-changes:56018

From: Nobuyoshi <ko1@a...>
Date: Wed, 5 Jun 2019 13:35:05 +0900 (JST)
Subject: [ruby-changes:56018] Nobuyoshi Nakada: 1624d77f3e (trunk): error.c: avoid infinite recursion at inspecting the frozen object

https://git.ruby-lang.org/ruby.git/commit/?id=1624d77f3e

From 1624d77f3ee0a536a6ab37da014d85d16fcd1de2 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 5 Jun 2019 13:02:38 +0900
Subject: error.c: avoid infinite recursion at inspecting the frozen object


diff --git a/error.c b/error.c
index 1e1af77..19265f6 100644
--- a/error.c
+++ b/error.c
@@ -2887,24 +2887,37 @@ rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...) https://github.com/ruby/ruby/blob/trunk/error.c#L2887
     rb_exc_raise(exc);
 }
 
+static VALUE
+inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
+{
+    if (recur) {
+        rb_str_cat_cstr(mesg, " ...");
+    }
+    else {
+        rb_str_append(mesg, rb_inspect(obj));
+    }
+    return mesg;
+}
+
 void
 rb_error_frozen_object(VALUE frozen_obj)
 {
     VALUE debug_info;
     const ID created_info = id_debug_created_info;
+    VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
+                            CLASS_OF(frozen_obj));
+    VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
+
+    rb_ivar_set(exc, id_recv, frozen_obj);
+    rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
 
     if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
 	VALUE path = rb_ary_entry(debug_info, 0);
 	VALUE line = rb_ary_entry(debug_info, 1);
 
-        rb_frozen_error_raise(frozen_obj,
-            "can't modify frozen %"PRIsVALUE": %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
-            CLASS_OF(frozen_obj), rb_inspect(frozen_obj), path, line);
-    }
-    else {
-        rb_frozen_error_raise(frozen_obj, "can't modify frozen %"PRIsVALUE": %"PRIsVALUE,
-            CLASS_OF(frozen_obj), rb_inspect(frozen_obj));
+        rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
     }
+    rb_exc_raise(exc);
 }
 
 #undef rb_check_frozen
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 54e39a0..c69d18b 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -886,6 +886,21 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L886
       obj.instance_variable_set(:@test, true)
     }
     assert_include(e.message, obj.inspect)
+
+    klass = Class.new do
+      def init
+        @x = true
+      end
+      def inspect
+        init
+        super
+      end
+    end
+    obj = klass.new.freeze
+    e = assert_raise_with_message(FrozenError, /can't modify frozen #{obj.class}/) {
+      obj.init
+    }
+    assert_include(e.message, klass.inspect)
   end
 
   def test_name_error_new_default
-- 
cgit v0.10.2


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

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