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]
This commit is contained in:
Jeremy Evans 2019-06-18 18:59:49 -07:00
parent a4b5aaa9a7
commit 7582287eb2
2 changed files with 19 additions and 0 deletions

View File

@ -2658,6 +2658,9 @@ str_uplus(VALUE str)
static VALUE
str_uminus(VALUE str)
{
if (!BARE_STRING_P(str) && !rb_obj_frozen_p(str)) {
str = rb_str_dup(str);
}
return rb_fstring(str);
}

View File

@ -3175,6 +3175,22 @@ CODE
assert_same(str, -bar, "uminus deduplicates [Feature #13077]")
end
def test_uminus_no_freeze_not_bare
str = @cls.new("foo")
-str
assert_equal(false, str.frozen?)
str = @cls.new("foo")
str.instance_variable_set(:@iv, 1)
-str
assert_equal(false, str.frozen?)
str = @cls.new("foo")
str.taint
-str
assert_equal(false, str.frozen?)
end
def test_ord
assert_equal(97, "a".ord)
assert_equal(97, "abc".ord)