diff options
Diffstat (limited to 'string.c')
| -rw-r--r-- | string.c | 18 |
1 files changed, 13 insertions, 5 deletions
@@ -1934,13 +1934,21 @@ rb_str_init(int argc, VALUE *argv, VALUE str) if (orig == str) n = 0; } str_modifiable(str); - if (STR_EMBED_P(str) || FL_TEST(str, STR_SHARED|STR_NOFREE)) { - /* make noembed always */ + if (STR_EMBED_P(str)) { /* make noembed always */ + char *new_ptr = ALLOC_N(char, (size_t)capa + termlen); +#if USE_RVARGC + assert(RSTRING(str)->as.embed.len + 1 <= str_embed_capa(str)); + memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.len + 1); +#else + memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_EMBED_LEN_MAX + 1); +#endif + RSTRING(str)->as.heap.ptr = new_ptr; + } + else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) { const size_t size = (size_t)capa + termlen; const char *const old_ptr = RSTRING_PTR(str); - const size_t osize = RSTRING_LEN(str) + TERM_LEN(str); - char *new_ptr = ALLOC_N(char, size); - if (STR_EMBED_P(str)) RUBY_ASSERT((long)osize <= str_embed_capa(str)); + const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str); + char *new_ptr = ALLOC_N(char, (size_t)capa + termlen); memcpy(new_ptr, old_ptr, osize < size ? osize : size); FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE); RSTRING(str)->as.heap.ptr = new_ptr; |
