Make Complex#{inspect,to_s} work correctly if real part #inspect returns frozen string

Make static f_format function take a non-frozen string to append
to.

This does not result in an additional allocation for #inspect,
but it does result in an additional allocation for #to_s.

Fixes [Bug #20337]
This commit is contained in:
Jeremy Evans 2024-09-20 14:57:56 -07:00 коммит произвёл Benoit Daloze
Родитель 75ed086348
Коммит 9f574fa12f
2 изменённых файлов: 15 добавлений и 5 удалений

Просмотреть файл

@ -1593,16 +1593,15 @@ f_tpositive_p(VALUE x)
} }
static VALUE static VALUE
f_format(VALUE self, VALUE (*func)(VALUE)) f_format(VALUE self, VALUE s, VALUE (*func)(VALUE))
{ {
VALUE s;
int impos; int impos;
get_dat1(self); get_dat1(self);
impos = f_tpositive_p(dat->imag); impos = f_tpositive_p(dat->imag);
s = (*func)(dat->real); rb_str_concat(s, (*func)(dat->real));
rb_str_cat2(s, !impos ? "-" : "+"); rb_str_cat2(s, !impos ? "-" : "+");
rb_str_concat(s, (*func)(f_abs(dat->imag))); rb_str_concat(s, (*func)(f_abs(dat->imag)));
@ -1629,7 +1628,7 @@ f_format(VALUE self, VALUE (*func)(VALUE))
static VALUE static VALUE
nucomp_to_s(VALUE self) nucomp_to_s(VALUE self)
{ {
return f_format(self, rb_String); return f_format(self, rb_usascii_str_new2(""), rb_String);
} }
/* /*
@ -1651,7 +1650,7 @@ nucomp_inspect(VALUE self)
VALUE s; VALUE s;
s = rb_usascii_str_new2("("); s = rb_usascii_str_new2("(");
rb_str_concat(s, f_format(self, rb_inspect)); f_format(self, s, rb_inspect);
rb_str_cat2(s, ")"); rb_str_cat2(s, ")");
return s; return s;

Просмотреть файл

@ -741,6 +741,17 @@ class Complex_Test < Test::Unit::TestCase
assert_equal('(1+2i)', c.inspect) assert_equal('(1+2i)', c.inspect)
end end
def test_inspect_to_s_frozen_bug_20337
assert_separately([], <<~'RUBY')
class Numeric
def inspect = super.freeze
end
c = Complex(Numeric.new, 1)
assert_match(/\A\(#<Numeric:/, c.inspect)
assert_match(/\A#<Numeric:/, c.to_s)
RUBY
end
def test_marshal def test_marshal
c = Complex(1,2) c = Complex(1,2)