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

ruby-changes:69708

From: Peter <ko1@a...>
Date: Fri, 12 Nov 2021 04:08:50 +0900 (JST)
Subject: [ruby-changes:69708] 84202963c5 (master): [Bug #18329] Fix crash when calling non-existent super method

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

From 84202963c52e02cecad3e6b2fad478bfbeee1bc7 Mon Sep 17 00:00:00 2001
From: Peter Zhu <peter@p...>
Date: Thu, 11 Nov 2021 11:55:35 -0500
Subject: [Bug #18329] Fix crash when calling non-existent super method

The cme is NULL when a method does not exist, so check it before
accessing the callcache.
---
 test/ruby/test_super.rb | 31 +++++++++++++++++++++++++++++++
 vm_insnhelper.c         |  3 ++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb
index d94f4679d32..3afde9b0e3a 100644
--- a/test/ruby/test_super.rb
+++ b/test/ruby/test_super.rb
@@ -521,6 +521,37 @@ class TestSuper < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_super.rb#L521
     assert_equal(%w[B A], result, bug9721)
   end
 
+  # [Bug #18329]
+  def test_super_missing_prepended_module
+    a = Module.new do
+      def probe(*methods)
+        prepend(probing_module(methods))
+      end
+
+      def probing_module(methods)
+        Module.new do
+          methods.each do |method|
+            define_method(method) do |*args, **kwargs, &block|
+              super(*args, **kwargs, &block)
+            end
+          end
+        end
+      end
+    end
+
+    b = Class.new do
+      extend a
+
+      probe :danger!, :missing
+
+      def danger!; end
+    end
+
+    o = b.new
+    o.danger!
+    2.times { o.missing rescue NoMethodError }
+  end
+
   def test_from_eval
     bug10263 = '[ruby-core:65122] [Bug #10263a]'
     a = Class.new do
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 86bdfd2fb6f..b9950f4fe28 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1936,7 +1936,8 @@ vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1936
 
 #if OPT_INLINE_METHOD_CACHE
     if (LIKELY(vm_cc_class_check(cc, klass))) {
-        if (LIKELY(!METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc)))) {
+        const struct rb_callable_method_entry_struct *cme = vm_cc_cme(cc);
+        if (LIKELY(cme && !METHOD_ENTRY_INVALIDATED(cme))) {
             VM_ASSERT(callable_method_entry_p(vm_cc_cme(cc)));
             RB_DEBUG_COUNTER_INC(mc_inline_hit);
             VM_ASSERT(vm_cc_cme(cc) == NULL ||                        // not found
-- 
cgit v1.2.1


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

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