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

ruby-changes:55554

From: Nobuyoshi <ko1@a...>
Date: Sat, 27 Apr 2019 21:30:49 +0900 (JST)
Subject: [ruby-changes:55554] Nobuyoshi Nakada:3f9562015e (trunk): Get rid of indirect sharing

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

From 3f9562015e651735bfc2fdd14e8f6963b673e22a Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Sat, 27 Apr 2019 21:21:55 +0900
Subject: Get rid of indirect sharing

* string.c (str_duplicate): share the root shared string if the
  original string is already sharing, so that all shared strings
  refer the root shared string directly.  indirect sharing can
  cause a dangling pointer.

[Bug #15792]

diff --git a/string.c b/string.c
index 386c460..895fe62 100644
--- a/string.c
+++ b/string.c
@@ -1505,9 +1505,14 @@ str_duplicate(VALUE klass, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1505
 	   char, embed_size);
     if (flags & STR_NOEMBED) {
 	if (UNLIKELY(!(flags & FL_FREEZE))) {
-	    str = str_new_frozen(klass, str);
-	    FL_SET_RAW(str, flags & FL_TAINT);
-	    flags = FL_TEST_RAW(str, flag_mask);
+            if (FL_TEST_RAW(str, STR_SHARED)) {
+                str = RSTRING(str)->as.heap.aux.shared;
+            }
+            else {
+                str = str_new_frozen(klass, str);
+                FL_SET_RAW(str, flags & FL_TAINT);
+                flags = FL_TEST_RAW(str, flag_mask);
+            }
 	}
 	if (flags & STR_NOEMBED) {
 	    RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, str);
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index d94c4da..f591f7e 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -2961,6 +2961,15 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2961
   end
 =end
 
+  def test_nesting_shared
+    a = ('a' * 24).encode(Encoding::ASCII).gsub('x', '')
+    hash = {}
+    hash[a] = true
+    assert_equal(('a' * 24), a)
+    4.times { GC.start }
+    assert_equal(('a' * 24), a, '[Bug #15792]')
+  end
+
   def test_shared_force_encoding
     s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
     h = {}
-- 
cgit v0.10.2


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

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