summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-25 02:05:34 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-25 02:05:34 (GMT)
commit8101cc3de4a846f11b76be637c3260aaa73e0b3c (patch)
treeb35e626dd5bb3e33f97dffd37f6b4f228d27f7a1 /string.c
parent9e4b24d4f363c7b95ef86321c9eb0db67f8c75a5 (diff)
string.c: fill the terminator
* string.c (str_replace_shared_without_enc): fill the terminator of embedded strings in wide char encodings. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r--string.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/string.c b/string.c
index 08fa48b..bf07d97 100644
--- a/string.c
+++ b/string.c
@@ -962,16 +962,24 @@ rb_str_export_to_enc(VALUE str, rb_encoding *enc)
static VALUE
str_replace_shared_without_enc(VALUE str2, VALUE str)
{
- if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
+ const int termlen = TERM_LEN(str);
+ char *ptr;
+ long len;
+
+ RSTRING_GETMEM(str, ptr, len);
+ if (len+termlen <= RSTRING_EMBED_LEN_MAX+1) {
+ char *ptr2 = RSTRING(str2)->as.ary;
STR_SET_EMBED(str2);
- memcpy(RSTRING_PTR(str2), RSTRING_PTR(str), RSTRING_LEN(str)+1);
- STR_SET_EMBED_LEN(str2, RSTRING_LEN(str));
+ memcpy(ptr2, RSTRING_PTR(str), len);
+ STR_SET_EMBED_LEN(str2, len);
+ TERM_FILL(ptr2+len, termlen);
}
else {
str = rb_str_new_frozen(str);
FL_SET(str2, STR_NOEMBED);
- RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
- RSTRING(str2)->as.heap.ptr = RSTRING_PTR(str);
+ RSTRING_GETMEM(str, ptr, len);
+ RSTRING(str2)->as.heap.len = len;
+ RSTRING(str2)->as.heap.ptr = ptr;
STR_SET_SHARED(str2, str);
}
return str2;