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

ruby-changes:66290

From: Alan <ko1@a...>
Date: Sat, 22 May 2021 01:12:46 +0900 (JST)
Subject: [ruby-changes:66290] 636d4f7eb9 (master): Avoid setting the visibility of refinement method entries

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

From 636d4f7eb9f3fcb088e1a44af4181c4aa36789b4 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Thu, 20 May 2021 18:52:32 -0400
Subject: Avoid setting the visibility of refinement method entries

Since refinement search is always performed, these entries should always
be public. The method entry that the refinement search returns decides
the visibility.

Fixes [Bug #17822]
---
 test/ruby/test_refinement.rb | 22 ++++++++++++++++++++++
 vm_method.c                  | 15 ++++++++++-----
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 50f0333..14c112f 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -2537,6 +2537,28 @@ class TestRefinement < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L2537
     assert_equal(:second, klass.new.foo)
   end
 
+  class Bug17822
+    module Ext
+      refine(Bug17822) do
+        def foo = :refined
+      end
+    end
+
+    private(def foo = :not_refined)
+
+    module Client
+      using Ext
+      def self.call_foo
+        Bug17822.new.foo
+      end
+    end
+  end
+
+  # [Bug #17822]
+  def test_privatizing_refined_method
+    assert_equal(:refined, Bug17822::Client.call_foo)
+  end
+
   private
 
   def eval_using(mod, s)
diff --git a/vm_method.c b/vm_method.c
index 34200dc..740279c 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1409,11 +1409,16 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1409
 	rb_vm_check_redefinition_opt_method(me, klass);
 
 	if (klass == defined_class || origin_class == defined_class) {
-	    METHOD_ENTRY_VISI_SET(me, visi);
-
-	    if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
-		METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
-	    }
+            if (me->def->type == VM_METHOD_TYPE_REFINED) {
+                // Refinement method entries should always be public because the refinement
+                // search is always performed.
+                if (me->def->body.refined.orig_me) {
+                    METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
+                }
+            }
+            else {
+                METHOD_ENTRY_VISI_SET(me, visi);
+            }
             rb_clear_method_cache(klass, name);
 	}
 	else {
-- 
cgit v1.1


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

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