diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-04-27 21:21:55 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-04-27 21:26:42 +0900 |
commit | 3f9562015e651735bfc2fdd14e8f6963b673e22a (patch) | |
tree | e3b5107346fcd0bbff7576bd2f511f90194dc1d3 /string.c | |
parent | afb361dfd0811f96f601d8d6492f9e1a0321ea01 (diff) |
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]
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -1505,9 +1505,14 @@ str_duplicate(VALUE klass, VALUE str) 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); |