* string.c (str_fill_term): When termlen increases, re-allocation

of memory for termlen should always be needed.
  In this fix, if possible, decrease capa instead of realloc.
  [Bug #12536] [ruby-dev:49699]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55557 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ngoto 2016-07-01 17:32:21 +00:00
parent 6fee4909c8
commit 61f2ee0d90
2 changed files with 29 additions and 3 deletions

View File

@ -1,3 +1,10 @@
Sat Jul 2 02:22:22 2016 Naohisa Goto <ngotogenome@gmail.com>
* string.c (str_fill_term): When termlen increases, re-allocation
of memory for termlen should always be needed.
In this fix, if possible, decrease capa instead of realloc.
[Bug #12536] [ruby-dev:49699]
Fri Jul 1 20:20:20 2016 Naohisa Goto <ngotogenome@gmail.com>
* string.c: Specify termlen as far as possible.

View File

@ -2029,17 +2029,36 @@ str_null_char(const char *s, long len, const int minlen, rb_encoding *enc)
static char *
str_fill_term(VALUE str, char *s, long len, int termlen)
{
long capa = rb_str_capacity(str) + 1;
long capa = rb_str_capacity(str);
/* This function could be called during the encoding changing procedure.
* If so, the termlen may be different from current TERM_LEN(str).
*/
const int oldtermlen = TERM_LEN(str);
if (capa < len + termlen) {
if (capa < len + termlen - 1) { /* assumes oldtermlen is 1 here */
rb_check_lockedtmp(str);
str_make_independent_expand(str, len, 0L, termlen);
}
else if (str_dependent_p(str)) {
if (!zero_filled(s + len, termlen))
if ((termlen > oldtermlen) || !zero_filled(s + len, termlen))
str_make_independent_expand(str, len, 0L, termlen);
}
else {
if (termlen > oldtermlen) {
if (!STR_EMBED_P(str)) {
const int d = termlen - oldtermlen;
if (capa > len + d) {
/* decrease capa for the new termlen */
capa -= d;
assert(capa >= 1);
assert(!FL_TEST((str), STR_SHARED));
RSTRING(str)->as.heap.aux.capa = capa;
} else {
assert(capa >= len);
RESIZE_CAPA_TERM(str, capa, termlen);
}
}
}
TERM_FILL(s + len, termlen);
return s;
}