Skip to content

Commit 3b588da

Browse files
committed
Don't modify fstrings in rb_str_tmp_frozen_no_embed_acquire
[Bug #21671]
1 parent 7037d8f commit 3b588da

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

string.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,10 @@ rb_gc_free_fstring(VALUE obj)
612612
{
613613
ASSERT_vm_locking_with_barrier();
614614

615+
RUBY_ASSERT(FL_TEST(obj, RSTRING_FSTR));
616+
RUBY_ASSERT(OBJ_FROZEN(obj));
617+
RUBY_ASSERT(!FL_TEST(obj, STR_SHARED));
618+
615619
rb_concurrent_set_delete_by_identity(fstring_table_obj, obj);
616620

617621
RB_DEBUG_COUNTER_INC(obj_str_fstr);
@@ -1554,7 +1558,7 @@ rb_str_tmp_frozen_no_embed_acquire(VALUE orig)
15541558
* allocated. If the string is shared then the shared root must be
15551559
* embedded, so we want to create a copy. If the string is a shared root
15561560
* then it must be embedded, so we want to create a copy. */
1557-
if (STR_EMBED_P(orig) || FL_TEST_RAW(orig, STR_SHARED | STR_SHARED_ROOT)) {
1561+
if (STR_EMBED_P(orig) || FL_TEST_RAW(orig, STR_SHARED | STR_SHARED_ROOT | RSTRING_FSTR)) {
15581562
RSTRING(str)->as.heap.ptr = rb_xmalloc_mul_add_mul(sizeof(char), capa, sizeof(char), TERM_LEN(orig));
15591563
memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), capa);
15601564
}

test/ruby/test_string.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3441,6 +3441,15 @@ def test_uminus_no_freeze_not_bare
34413441
assert_equal(false, str.frozen?)
34423442
end
34433443

3444+
def test_uminus_no_embed_gc
3445+
pad = "a"*2048
3446+
("aa".."zz").each do |c|
3447+
fstr = -(c + pad).freeze
3448+
File.open(IO::NULL, "w").write(fstr)
3449+
end
3450+
GC.start
3451+
end
3452+
34443453
def test_ord
34453454
assert_equal(97, S("a").ord)
34463455
assert_equal(97, S("abc").ord)

0 commit comments

Comments
 (0)