@@ -240,9 +240,9 @@ rb_str_reembeddable_p(VALUE str)
240240}
241241
242242static inline size_t
243- rb_str_embed_size (long capa )
243+ rb_str_embed_size (long capa , long termlen )
244244{
245- size_t size = offsetof(struct RString , as .embed .ary ) + capa ;
245+ size_t size = offsetof(struct RString , as .embed .ary ) + capa + termlen ;
246246 if (size < sizeof (struct RString )) size = sizeof (struct RString );
247247 return size ;
248248}
@@ -252,28 +252,30 @@ rb_str_size_as_embedded(VALUE str)
252252{
253253 size_t real_size ;
254254 if (STR_EMBED_P (str )) {
255- real_size = rb_str_embed_size (RSTRING (str )-> len ) + TERM_LEN (str );
255+ size_t capa = RSTRING (str )-> len ;
256+ if (FL_TEST_RAW (str , STR_PRECOMPUTED_HASH )) capa += sizeof (st_index_t );
257+
258+ real_size = rb_str_embed_size (capa , TERM_LEN (str ));
256259 }
257260 /* if the string is not currently embedded, but it can be embedded, how
258261 * much space would it require */
259262 else if (rb_str_reembeddable_p (str )) {
260- real_size = rb_str_embed_size (RSTRING (str )-> as .heap .aux .capa ) + TERM_LEN (str );
263+ size_t capa = RSTRING (str )-> as .heap .aux .capa ;
264+ if (FL_TEST_RAW (str , STR_PRECOMPUTED_HASH )) capa += sizeof (st_index_t );
265+
266+ real_size = rb_str_embed_size (capa , TERM_LEN (str ));
261267 }
262268 else {
263269 real_size = sizeof (struct RString );
264270 }
265271
266- if (FL_TEST_RAW (str , STR_PRECOMPUTED_HASH )) {
267- real_size += sizeof (st_index_t );
268- }
269-
270272 return real_size ;
271273}
272274
273275static inline bool
274276STR_EMBEDDABLE_P (long len , long termlen )
275277{
276- return rb_gc_size_allocatable_p (rb_str_embed_size (len + termlen ));
278+ return rb_gc_size_allocatable_p (rb_str_embed_size (len , termlen ));
277279}
278280
279281static VALUE str_replace_shared_without_enc (VALUE str2 , VALUE str );
@@ -1006,7 +1008,7 @@ must_not_null(const char *ptr)
10061008static inline VALUE
10071009str_alloc_embed (VALUE klass , size_t capa )
10081010{
1009- size_t size = rb_str_embed_size (capa );
1011+ size_t size = rb_str_embed_size (capa , 0 );
10101012 RUBY_ASSERT (size > 0 );
10111013 RUBY_ASSERT (rb_gc_size_allocatable_p (size ));
10121014
@@ -1883,7 +1885,7 @@ str_replace(VALUE str, VALUE str2)
18831885static inline VALUE
18841886ec_str_alloc_embed (struct rb_execution_context_struct * ec , VALUE klass , size_t capa )
18851887{
1886- size_t size = rb_str_embed_size (capa );
1888+ size_t size = rb_str_embed_size (capa , 0 );
18871889 RUBY_ASSERT (size > 0 );
18881890 RUBY_ASSERT (rb_gc_size_allocatable_p (size ));
18891891
0 commit comments