mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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]
This commit is contained in:
parent
afb361dfd0
commit
3f9562015e
2 changed files with 17 additions and 3 deletions
5
string.c
5
string.c
|
@ -1505,10 +1505,15 @@ str_duplicate(VALUE klass, VALUE str)
|
||||||
char, embed_size);
|
char, embed_size);
|
||||||
if (flags & STR_NOEMBED) {
|
if (flags & STR_NOEMBED) {
|
||||||
if (UNLIKELY(!(flags & FL_FREEZE))) {
|
if (UNLIKELY(!(flags & FL_FREEZE))) {
|
||||||
|
if (FL_TEST_RAW(str, STR_SHARED)) {
|
||||||
|
str = RSTRING(str)->as.heap.aux.shared;
|
||||||
|
}
|
||||||
|
else {
|
||||||
str = str_new_frozen(klass, str);
|
str = str_new_frozen(klass, str);
|
||||||
FL_SET_RAW(str, flags & FL_TAINT);
|
FL_SET_RAW(str, flags & FL_TAINT);
|
||||||
flags = FL_TEST_RAW(str, flag_mask);
|
flags = FL_TEST_RAW(str, flag_mask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (flags & STR_NOEMBED) {
|
if (flags & STR_NOEMBED) {
|
||||||
RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, str);
|
RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, str);
|
||||||
flags |= STR_SHARED;
|
flags |= STR_SHARED;
|
||||||
|
|
|
@ -2961,6 +2961,15 @@ CODE
|
||||||
end
|
end
|
||||||
=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
|
def test_shared_force_encoding
|
||||||
s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
|
s = "\u{3066}\u{3059}\u{3068}".gsub(//, '')
|
||||||
h = {}
|
h = {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue