ruby-changes:43484
From: ngoto <ko1@a...>
Date: Sat, 2 Jul 2016 02:32:26 +0900 (JST)
Subject: [ruby-changes:43484] ngoto:r55557 (trunk): * string.c (str_fill_term): When termlen increases, re-allocation
ngoto 2016-07-02 02:32:21 +0900 (Sat, 02 Jul 2016) New Revision: 55557 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55557 Log: * 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] Modified files: trunk/ChangeLog trunk/string.c Index: ChangeLog =================================================================== --- ChangeLog (revision 55556) +++ ChangeLog (revision 55557) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Jul 2 02:22:22 2016 Naohisa Goto <ngotogenome@g...> + + * 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@g...> * string.c: Specify termlen as far as possible. Index: string.c =================================================================== --- string.c (revision 55556) +++ string.c (revision 55557) @@ -2029,17 +2029,36 @@ str_null_char(const char *s, long len, c https://github.com/ruby/ruby/blob/trunk/string.c#L2029 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; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/