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/