No computing embed_capa_max in str_subseq
Fix str_subseq so that it does not attempt to predict the size of the object returned by str_alloc_heap.
This commit is contained in:
parent
b35a222348
commit
132f097149
Notes:
git
2023-08-03 18:53:03 +00:00
23
string.c
23
string.c
@ -2732,15 +2732,30 @@ str_subseq(VALUE str, long beg, long len)
|
|||||||
{
|
{
|
||||||
VALUE str2;
|
VALUE str2;
|
||||||
|
|
||||||
const long rstring_embed_capa_max = ((sizeof(struct RString) - offsetof(struct RString, as.embed.ary)) / sizeof(char)) - 1;
|
assert(beg >= 0);
|
||||||
|
assert(len >= 0);
|
||||||
|
assert(beg+len <= RSTRING_LEN(str));
|
||||||
|
|
||||||
if (!SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str)) ||
|
const int termlen = TERM_LEN(str);
|
||||||
len <= rstring_embed_capa_max) {
|
if (!SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
|
||||||
str2 = rb_str_new(RSTRING_PTR(str) + beg, len);
|
str2 = rb_str_new(RSTRING_PTR(str) + beg, len);
|
||||||
RB_GC_GUARD(str);
|
RB_GC_GUARD(str);
|
||||||
|
return str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
str2 = str_alloc_heap(rb_cString);
|
||||||
|
if (str_embed_capa(str2) >= len + termlen) {
|
||||||
|
char *ptr2 = RSTRING(str2)->as.embed.ary;
|
||||||
|
STR_SET_EMBED(str2);
|
||||||
|
memcpy(ptr2, RSTRING_PTR(str) + beg, len);
|
||||||
|
TERM_FILL(ptr2+len, termlen);
|
||||||
|
|
||||||
|
STR_SET_LEN(str2, len);
|
||||||
|
RB_GC_GUARD(str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
str2 = str_new_shared(rb_cString, str);
|
str_replace_shared(str2, str);
|
||||||
|
assert(!STR_EMBED_P(str2));
|
||||||
ENC_CODERANGE_CLEAR(str2);
|
ENC_CODERANGE_CLEAR(str2);
|
||||||
RSTRING(str2)->as.heap.ptr += beg;
|
RSTRING(str2)->as.heap.ptr += beg;
|
||||||
if (RSTRING_LEN(str2) > len) {
|
if (RSTRING_LEN(str2) > len) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user