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

ruby-changes:71464

From: nagachika <ko1@a...>
Date: Mon, 21 Mar 2022 16:02:06 +0900 (JST)
Subject: [ruby-changes:71464] e0146e6cc8 (ruby_3_0): merge revision(s) 97426e15d721119738a548ecfa7232b1d027cd34: [Backport #18627]

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

From e0146e6cc8f3578b02ad5f228f86bf1aef566d16 Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Mon, 21 Mar 2022 15:35:07 +0900
Subject: merge revision(s) 97426e15d721119738a548ecfa7232b1d027cd34: [Backport
 #18627]

	[Bug #18627] Fix crash when including module

	During lazy sweeping, the iclass could be a dead object that has not yet
	been swept. However, the chain of superclasses of the iclass could
	already have been swept (and become a new object), which would cause a
	crash when trying to read the object.
	---
	 class.c | 48 ++++++++++++++++++++++++++++++------------------
	 1 file changed, 30 insertions(+), 18 deletions(-)
---
 class.c   | 46 ++++++++++++++++++++++++++++------------------
 version.h |  4 ++--
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/class.c b/class.c
index b607135e2f..6a4d3fb264 100644
--- a/class.c
+++ b/class.c
@@ -973,17 +973,22 @@ rb_include_module(VALUE klass, VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L973
         int do_include = 1;
         while (iclass) {
             VALUE check_class = iclass->klass;
-            while (check_class) {
-                if (RB_TYPE_P(check_class, T_ICLASS) &&
-                        (RBASIC(check_class)->klass == module)) {
-                    do_include = 0;
+            /* During lazy sweeping, iclass->klass could be a dead object that
+             * has not yet been swept. */
+            if (!rb_objspace_garbage_object_p(check_class)) {
+                while (check_class) {
+                    if (RB_TYPE_P(check_class, T_ICLASS) &&
+                            (RBASIC(check_class)->klass == module)) {
+                        do_include = 0;
+                    }
+                    check_class = RCLASS_SUPER(check_class);
                 }
-                check_class = RCLASS_SUPER(check_class);
-            }
 
-            if (do_include) {
-                include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
+                if (do_include) {
+                    include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
+                }
             }
+
             iclass = iclass->next;
         }
     }
@@ -1180,17 +1185,22 @@ rb_prepend_module(VALUE klass, VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L1185
         struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass);
         struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin);
         while (iclass) {
-            if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) {
-                // backfill an origin iclass to handle refinements and future prepends
-                rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass);
-                RCLASS_M_TBL(iclass->klass) = klass_m_tbl;
-                VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass));
-                RCLASS_SET_SUPER(iclass->klass, origin);
-                RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass));
-                RCLASS_SET_ORIGIN(iclass->klass, origin);
-                RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
+            /* During lazy sweeping, iclass->klass could be a dead object that
+             * has not yet been swept. */
+            if (!rb_objspace_garbage_object_p(iclass->klass)) {
+                if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) {
+                    // backfill an origin iclass to handle refinements and future prepends
+                    rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass);
+                    RCLASS_M_TBL(iclass->klass) = klass_m_tbl;
+                    VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass));
+                    RCLASS_SET_SUPER(iclass->klass, origin);
+                    RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass));
+                    RCLASS_SET_ORIGIN(iclass->klass, origin);
+                    RICLASS_SET_ORIGIN_SHARED_MTBL(origin);
+                }
+                include_modules_at(iclass->klass, iclass->klass, module, FALSE);
             }
-            include_modules_at(iclass->klass, iclass->klass, module, FALSE);
+
             iclass = iclass->next;
         }
     }
diff --git a/version.h b/version.h
index 5ca9f7c5bd..ba0eb78ef4 100644
--- a/version.h
+++ b/version.h
@@ -12,11 +12,11 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L12
 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
 #define RUBY_VERSION_TEENY 4
 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 197
+#define RUBY_PATCHLEVEL 198
 
 #define RUBY_RELEASE_YEAR 2022
 #define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 13
+#define RUBY_RELEASE_DAY 21
 
 #include "ruby/version.h"
 
-- 
cgit v1.2.1


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

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