Preserve the string content at self-copying
* string.c (rb_str_init): preserve the embedded content when self-copying with a capacity. [Bug #15937]
This commit is contained in:
parent
d009e321a0
commit
28678997e4
5
string.c
5
string.c
@ -1331,6 +1331,7 @@ str_new_empty(VALUE str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define STR_BUF_MIN_SIZE 127
|
#define STR_BUF_MIN_SIZE 127
|
||||||
|
STATIC_ASSERT(STR_BUF_MIN_SIZE, STR_BUF_MIN_SIZE > RSTRING_EMBED_LEN_MAX);
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_str_buf_new(long capa)
|
rb_str_buf_new(long capa)
|
||||||
@ -1611,7 +1612,9 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
|
|||||||
}
|
}
|
||||||
str_modifiable(str);
|
str_modifiable(str);
|
||||||
if (STR_EMBED_P(str)) { /* make noembed always */
|
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) {
|
else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
|
||||||
SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
|
SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
|
||||||
|
@ -68,6 +68,15 @@ class TestString < Test::Unit::TestCase
|
|||||||
assert_raise(FrozenError){ str.__send__(:initialize, encoding: 'euc-jp') }
|
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', encoding: 'euc-jp') }
|
||||||
assert_raise(FrozenError){ str.__send__(:initialize, 'abc', capacity: 1000, 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
|
end
|
||||||
|
|
||||||
def test_initialize_nonstring
|
def test_initialize_nonstring
|
||||||
|
Loading…
x
Reference in New Issue
Block a user