From 1910bd42477f928b539f09c7ba2ac444bd368fd4 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 7 Nov 2023 23:26:14 +0900 Subject: [PATCH] String for string literal is not resizable --- ext/-test-/string/depend | 3 +++ ext/-test-/string/fstring.c | 10 ++++++++++ string.c | 2 +- test/-ext-/string/test_fstring.rb | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ext/-test-/string/depend b/ext/-test-/string/depend index 26720282b2dabf..eeb4914346bd91 100644 --- a/ext/-test-/string/depend +++ b/ext/-test-/string/depend @@ -1196,6 +1196,7 @@ fstring.o: $(hdrdir)/ruby/backward.h fstring.o: $(hdrdir)/ruby/backward/2/assume.h fstring.o: $(hdrdir)/ruby/backward/2/attributes.h fstring.o: $(hdrdir)/ruby/backward/2/bool.h +fstring.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h fstring.o: $(hdrdir)/ruby/backward/2/inttypes.h fstring.o: $(hdrdir)/ruby/backward/2/limits.h fstring.o: $(hdrdir)/ruby/backward/2/long_long.h @@ -1358,6 +1359,8 @@ fstring.o: $(hdrdir)/ruby/oniguruma.h fstring.o: $(hdrdir)/ruby/ruby.h fstring.o: $(hdrdir)/ruby/st.h fstring.o: $(hdrdir)/ruby/subst.h +fstring.o: $(top_srcdir)/internal/compilers.h +fstring.o: $(top_srcdir)/internal/string.h fstring.o: fstring.c init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c index 2374319fe340b0..7ee14a8570f7d0 100644 --- a/ext/-test-/string/fstring.c +++ b/ext/-test-/string/fstring.c @@ -1,5 +1,6 @@ #include "ruby.h" #include "ruby/encoding.h" +#include "internal/string.h" VALUE rb_fstring(VALUE str); @@ -9,6 +10,14 @@ bug_s_fstring(VALUE self, VALUE str) return rb_fstring(str); } +VALUE +bug_s_fstring_fake_str(VALUE self) +{ + static const char literal[] = "abcdefghijklmnopqrstuvwxyz"; + struct RString fake_str; + return rb_fstring(rb_setup_fake_str(&fake_str, literal, sizeof(literal) - 1, 0)); +} + VALUE bug_s_rb_enc_interned_str(VALUE self, VALUE encoding) { @@ -25,6 +34,7 @@ void Init_string_fstring(VALUE klass) { rb_define_singleton_method(klass, "fstring", bug_s_fstring, 1); + rb_define_singleton_method(klass, "fstring_fake_str", bug_s_fstring_fake_str, 0); rb_define_singleton_method(klass, "rb_enc_interned_str", bug_s_rb_enc_interned_str, 1); rb_define_singleton_method(klass, "rb_enc_str_new", bug_s_rb_enc_str_new, 1); } diff --git a/string.c b/string.c index 13b63f023a5a39..b3004624ddc16f 100644 --- a/string.c +++ b/string.c @@ -428,7 +428,7 @@ rb_fstring(VALUE str) } } - if (!OBJ_FROZEN(str)) + if (!FL_TEST_RAW(str, FL_FREEZE | STR_NOFREE)) rb_str_resize(str, RSTRING_LEN(str)); fstr = register_fstring(str, FALSE); diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb index 5a3456c5664c33..b7416ccbf37d95 100644 --- a/test/-ext-/string/test_fstring.rb +++ b/test/-ext-/string/test_fstring.rb @@ -49,6 +49,10 @@ def test_singleton_class assert_raise(TypeError) {fstr.singleton_class} end + def test_fake_str + assert_equal([*"a".."z"].join(""), Bug::String.fstring_fake_str) + end + class S < String end