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

ruby-changes:71095

From: John <ko1@a...>
Date: Sun, 6 Feb 2022 11:10:44 +0900 (JST)
Subject: [ruby-changes:71095] c79d2e5474 (master): Fix TAG_THROW through require [Bug #18562]

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

From c79d2e54748f52c5023b0a1ee441561df9826c17 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Sat, 29 Jan 2022 06:11:10 -0800
Subject: Fix TAG_THROW through require [Bug #18562]

Previously this was being incorrectly swapped with TAG_RAISE in the next
line. This would end up checking the T_IMEMO throw_data to the exception
handling (which calls Module#===). This happened to not break existing
tests because Module#=== returned false when klass is NULL.

This commit handles throw from require correctly by jumping to the tag
retaining the TAG_THROW state.
---
 load.c                      |  2 +-
 test/ruby/test_exception.rb | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/load.c b/load.c
index a2b9da48fb..812fe2fe93 100644
--- a/load.c
+++ b/load.c
@@ -1155,7 +1155,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa https://github.com/ruby/ruby/blob/trunk/load.c#L1155
     if (ftptr) load_unlock(th2->vm, RSTRING_PTR(path), !state);
 
     if (state) {
-        if (state == TAG_FATAL) {
+        if (state == TAG_FATAL || state == TAG_THROW) {
             EC_JUMP_TAG(ec, state);
         }
         else if (exception) {
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 9908331689..bd4170e0fd 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -252,6 +252,27 @@ class TestException < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L252
     }
   end
 
+  def test_catch_throw_in_require_cant_be_rescued
+    bug18562 = '[ruby-core:107403]'
+    Tempfile.create(["dep", ".rb"]) {|t|
+      t.puts("throw :extdep, 42")
+      t.close
+
+      rescue_all = Class.new(Exception)
+      def rescue_all.===(_)
+        raise "should not reach here"
+      end
+
+      v = assert_throw(:extdep, bug18562) do
+        require t.path
+      rescue rescue_all => e
+        assert(false, "should not reach here")
+      end
+
+      assert_equal(42, v, bug18562)
+    }
+  end
+
   def test_throw_false
     bug12743 = '[ruby-core:77229] [Bug #12743]'
     Thread.start {
-- 
cgit v1.2.1


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

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