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

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/

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