8000 Make String#-@ not freeze receiver if called on unfrozen subclass ins… · github/ruby@7582287 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7582287

Browse files
committed
Make String#-@ not freeze receiver if called on unfrozen subclass instance
rb_fstring behavior in this case is to freeze the receiver. I'm not sure if that should be changed, so this takes the conservative approach of duping the receiver in String#-@ before passing to rb_fstring. Fixes [Bug #15926]
1 parent a4b5aaa commit 7582287

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

string.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,6 +2658,9 @@ str_uplus(VALUE str)
26582658
static VALUE
26592659
str_uminus(VALUE str)
26602660
{
2661+
if (!BARE_STRING_P(str) && !rb_obj_frozen_p(str)) {
2662+
str = rb_str_dup(str);
2663+
}
26612664
return rb_fstring(str);
26622665
}
26632666

test/ruby/test_string.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,22 @@ def test_uplus_minus
31753175
assert_same(str, -bar, "uminus deduplicates [Feature #13077]")
31763176
end
31773177

3178+
def test_uminus_no_freeze_not_bare
3179+
str = @cls.new("foo")
3180+
-str
3181+
assert_equal(false, str.frozen?)
3182+
3183+
str = @cls.new("foo")
3184+
str.instance_variable_set(:@iv, 1)
3185+
-str
3186+
assert_equal(false, str.frozen?)
3187+
3188+
str = @cls.new("foo")
3189+
str.taint
3190+
-str
3191+
assert_equal(false, str.frozen?)
3192+
end
3193+
31783194
def test_ord
31793195
assert_equal(97, "a".ord)
31803196
assert_equal(97, "abc".ord)

0 commit comments

Comments
 (0)
0