summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2024-05-29 10:19:49 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2024-05-29 10:19:49 -0700
commitf12c947192aa47b355015384e5c82cbf674023f1 (patch)
treea45c0fdbc4318c53a15e7a69779bafea9dba0e04 /string.c
parenta8b2317d16fa172edd3cd7e6fcb3bc694287d109 (diff)
merge revision(s) e04146129ec6898dd6a9739dad2983c6e9b68056: [Backport #20292]
[Bug #20292] Truncate embedded string to new capacity
Diffstat (limited to 'string.c')
-rw-r--r--string.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/string.c b/string.c
index 702024671a..cae234687d 100644
--- a/string.c
+++ b/string.c
@@ -1860,17 +1860,13 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
if (orig == str) n = 0;
}
str_modifiable(str);
- if (STR_EMBED_P(str)) { /* make noembed always */
- char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
- assert(RSTRING_LEN(str) + 1 <= str_embed_capa(str));
- memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_LEN(str) + 1);
- RSTRING(str)->as.heap.ptr = new_ptr;
- }
- else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
+ if (STR_EMBED_P(str) || FL_TEST(str, STR_SHARED|STR_NOFREE)) {
+ /* make noembed always */
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_t)capa + termlen);
+ char *new_ptr = ALLOC_N(char, size);
+ if (STR_EMBED_P(str)) RUBY_ASSERT(osize <= str_embed_capa(str));
memcpy(new_ptr, old_ptr, osize < size ? osize : size);
FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
RSTRING(str)->as.heap.ptr = new_ptr;