[前][次][番号順一覧][スレッド一覧]

ruby-changes:56137

From: Nobuyoshi <ko1@a...>
Date: Wed, 19 Jun 2019 09:57:35 +0900 (JST)
Subject: [ruby-changes:56137] Nobuyoshi Nakada: 28678997e4 (trunk): Preserve the string content at self-copying

https://git.ruby-lang.org/ruby.git/commit/?id=28678997e4

From 28678997e40869f5591eae60edd9757334426ffb Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 19 Jun 2019 09:44:26 +0900
Subject: Preserve the string content at self-copying

* string.c (rb_str_init): preserve the embedded content when
  self-copying with a capacity.  [Bug #15937]

diff --git a/string.c b/string.c
index fdb7e40..e402a5a 100644
--- a/string.c
+++ b/string.c
@@ -1331,6 +1331,7 @@ str_new_empty(VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1331
 }
 
 #define STR_BUF_MIN_SIZE 127
+STATIC_ASSERT(STR_BUF_MIN_SIZE, STR_BUF_MIN_SIZE > RSTRING_EMBED_LEN_MAX);
 
 VALUE
 rb_str_buf_new(long capa)
@@ -1611,7 +1612,9 @@ rb_str_init(int argc, VALUE *argv, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1612
 	    }
 	    str_modifiable(str);
 	    if (STR_EMBED_P(str)) { /* make noembed always */
-		RSTRING(str)->as.heap.ptr = ALLOC_N(char, (size_t)capa + termlen);
+                char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
+                memcpy(new_ptr, RSTRING(str)->as.ary, RSTRING_EMBED_LEN_MAX + 1);
+                RSTRING(str)->as.heap.ptr = new_ptr;
 	    }
 	    else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
 		SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 35f27c8..1d81d24 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -68,6 +68,15 @@ class TestString < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L68
     assert_raise(FrozenError){ str.__send__(:initialize, encoding: 'euc-jp') }
     assert_raise(FrozenError){ str.__send__(:initialize, 'abc', encoding: 'euc-jp') }
     assert_raise(FrozenError){ str.__send__(:initialize, 'abc', capacity: 1000, encoding: 'euc-jp') }
+
+    str = S("")
+    assert_equal("mystring", str.__send__(:initialize, "mystring"))
+    str = S("mystring")
+    assert_equal("mystring", str.__send__(:initialize, str))
+    str = S("")
+    assert_equal("mystring", str.__send__(:initialize, "mystring", capacity: 1000))
+    str = S("mystring")
+    assert_equal("mystring", str.__send__(:initialize, str, capacity: 1000))
   end
 
   def test_initialize_nonstring
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]