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

ruby-changes:5964

From: nobu <ko1@a...>
Date: Fri, 20 Jun 2008 15:49:35 +0900 (JST)
Subject: [ruby-changes:5964] Ruby:r17472 (trunk, ruby_1_8): * array.c (rb_ary_store, rb_ary_splice): not depend on unspecified

nobu	2008-06-20 15:42:07 +0900 (Fri, 20 Jun 2008)

  New Revision: 17472

  Modified files:
    branches/ruby_1_8/array.c
    branches/ruby_1_8/string.c
    trunk/array.c
    trunk/string.c

  Log:
    * array.c (rb_ary_store, rb_ary_splice): not depend on unspecified
      behavior at integer overflow.
    
    * string.c (str_buf_cat): ditto.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/string.c?r1=17472&r2=17471&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/array.c?r1=17472&r2=17471&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/array.c?r1=17472&r2=17471&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/string.c?r1=17472&r2=17471&diff_format=u

Index: array.c
===================================================================
--- array.c	(revision 17471)
+++ array.c	(revision 17472)
@@ -383,7 +383,7 @@
 	if (new_capa < ARY_DEFAULT_SIZE) {
 	    new_capa = ARY_DEFAULT_SIZE;
 	}
-	else if (new_capa >= ARY_MAX_SIZE - idx) {
+	if (new_capa >= ARY_MAX_SIZE - idx) {
 	    new_capa = (ARY_MAX_SIZE - idx) / 2;
 	}
 	new_capa += idx;
@@ -986,10 +986,10 @@
     }
     rb_ary_modify(ary);
     if (beg >= RARRAY_LEN(ary)) {
-	len = beg + rlen;
-	if (len < 0 || len > ARY_MAX_SIZE) {
+	if (beg > ARY_MAX_SIZE - rlen) {
 	    rb_raise(rb_eIndexError, "index %ld too big", beg);
 	}
+	len = beg + rlen;
 	if (len >= ARY_CAPA(ary)) {
 	    RESIZE_CAPA(ary, len);
 	}
Index: string.c
===================================================================
--- string.c	(revision 17471)
+++ string.c	(revision 17472)
@@ -1394,16 +1394,16 @@
     return str;
 }
 
-VALUE
-rb_str_buf_cat(VALUE str, const char *ptr, long len)
+static long
+str_buf_cat(VALUE str, const char *ptr, long len)
 {
-    long capa, total;
+    long capa, total, off = -1;
 
-    if (len == 0) return str;
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative string size (or size too big)");
+    if (ptr >= RSTRING_PTR(str) && ptr <= RSTRING_END(str)) {
+        off = ptr - RSTRING_PTR(str);
     }
     rb_str_modify(str);
+    if (len == 0) return 0;
     if (STR_ASSOC_P(str)) {
 	FL_UNSET(str, STR_ASSOC);
 	capa = RSTRING(str)->as.heap.aux.capa = RSTRING_LEN(str);
@@ -1414,13 +1414,23 @@
     else {
 	capa = RSTRING(str)->as.heap.aux.capa;
     }
+    if (RSTRING_LEN(str) >= LONG_MAX - len) {
+	rb_raise(rb_eArgError, "string sizes too big");
+    }
     total = RSTRING_LEN(str)+len;
     if (capa <= total) {
 	while (total > capa) {
+	    if (capa + 1 >= LONG_MAX / 2) {
+		capa = (total + 4095) / 4096;
+		break;
+	    }
 	    capa = (capa + 1) * 2;
 	}
 	RESIZE_CAPA(str, capa);
     }
+    if (off != -1) {
+        ptr = RSTRING_PTR(str) + off;
+    }
     memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
     STR_SET_LEN(str, total);
     RSTRING_PTR(str)[total] = '\0'; /* sentinel */
@@ -1429,6 +1439,16 @@
 }
 
 VALUE
+rb_str_buf_cat(VALUE str, const char *ptr, long len)
+{
+    if (len == 0) return str;
+    if (len < 0) {
+	rb_raise(rb_eArgError, "negative string size (or size too big)");
+    }
+    return str_buf_cat(str, ptr, len);
+}
+
+VALUE
 rb_str_buf_cat2(VALUE str, const char *ptr)
 {
     return rb_str_buf_cat(str, ptr, strlen(ptr));
@@ -1463,8 +1483,6 @@
 rb_enc_cr_str_buf_cat(VALUE str, const char *ptr, long len,
     int ptr_encindex, int ptr_cr, int *ptr_cr_ret)
 {
-    long capa, total, off = -1;
-
     int str_encindex = ENCODING_GET(str);
     int res_encindex;
     int str_cr, res_cr;
@@ -1543,41 +1561,7 @@
     if (len < 0) {
 	rb_raise(rb_eArgError, "negative string size (or size too big)");
     }
-    if (ptr >= RSTRING_PTR(str) && ptr <= RSTRING_END(str)) {
-        off = ptr - RSTRING_PTR(str);
-    }
-    rb_str_modify(str);
-    if (len == 0) {
-        ENCODING_CODERANGE_SET(str, res_encindex, res_cr);
-        return str;
-    }
-    if (STR_ASSOC_P(str)) {
-	FL_UNSET(str, STR_ASSOC);
-	capa = RSTRING(str)->as.heap.aux.capa = RSTRING_LEN(str);
-    }
-    else if (STR_EMBED_P(str)) {
-	capa = RSTRING_EMBED_LEN_MAX;
-    }
-    else {
-	capa = RSTRING(str)->as.heap.aux.capa;
-    }
-    total = RSTRING_LEN(str)+len;
-    if (total < 0 || capa + 1 > LONG_MAX / 2) {
-	rb_raise(rb_eArgError, "string sizes too big");
-    }
-    if (capa <= total) {
-	while (total > capa) {
-	    capa = (capa + 1) * 2;
-	}
-	RESIZE_CAPA(str, capa);
-    }
-    if (off != -1) {
-        ptr = RSTRING_PTR(str) + off;
-    }
-    memcpy(RSTRING_PTR(str) + RSTRING_LEN(str), ptr, len);
-    STR_SET_LEN(str, total);
-    RSTRING_PTR(str)[total] = '\0'; /* sentinel */
-
+    str_buf_cat(str, ptr, len);
     ENCODING_CODERANGE_SET(str, res_encindex, res_cr);
     return str;
 }
Index: ruby_1_8/array.c
===================================================================
--- ruby_1_8/array.c	(revision 17471)
+++ ruby_1_8/array.c	(revision 17472)
@@ -391,7 +391,7 @@
 	if (new_capa < ARY_DEFAULT_SIZE) {
 	    new_capa = ARY_DEFAULT_SIZE;
 	}
-	else if (new_capa >= ARY_MAX_SIZE - idx) {
+	if (new_capa >= ARY_MAX_SIZE - idx) {
 	    new_capa = (ARY_MAX_SIZE - idx) / 2;
 	}
 	new_capa += idx;
@@ -1094,10 +1094,10 @@
     rb_ary_modify(ary);
 
     if (beg >= RARRAY(ary)->len) {
-	len = beg + rlen;
-	if (len < 0 || len > ARY_MAX_SIZE) {
+	if (beg > ARY_MAX_SIZE - rlen) {
 	    rb_raise(rb_eIndexError, "index %ld too big", beg);
 	}
+	len = beg + rlen;
 	if (len >= RARRAY(ary)->aux.capa) {
 	    REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
 	    RARRAY(ary)->aux.capa = len;
Index: ruby_1_8/string.c
===================================================================
--- ruby_1_8/string.c	(revision 17471)
+++ ruby_1_8/string.c	(revision 17472)
@@ -702,18 +702,14 @@
     return str;
 }
 
-VALUE
-rb_str_buf_cat(str, ptr, len)
+static VALUE
+str_buf_cat(str, ptr, len)
     VALUE str;
     const char *ptr;
     long len;
 {
     long capa, total;
 
-    if (len == 0) return str;
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative string size (or size too big)");
-    }
     rb_str_modify(str);
     if (FL_TEST(str, STR_ASSOC)) {
 	FL_UNSET(str, STR_ASSOC);
@@ -722,9 +718,16 @@
     else {
 	capa = RSTRING(str)->aux.capa;
     }
+    if (RSTRING(str)->len >= LONG_MAX - len) {
+	rb_raise(rb_eArgError, "string sizes too big");
+    }
     total = RSTRING(str)->len+len;
     if (capa <= total) {
 	while (total > capa) {
+	    if (capa + 1 >= LONG_MAX / 2) {
+		capa = total;
+		break;
+	    }
 	    capa = (capa + 1) * 2;
 	}
 	RESIZE_CAPA(str, capa);
@@ -737,6 +740,19 @@
 }
 
 VALUE
+rb_str_buf_cat(str, ptr, len)
+    VALUE str;
+    const char *ptr;
+    long len;
+{
+    if (len == 0) return str;
+    if (len < 0) {
+	rb_raise(rb_eArgError, "negative string size (or size too big)");
+    }
+    return str_buf_cat(str, ptr, len);
+}
+
+VALUE
 rb_str_buf_cat2(str, ptr)
     VALUE str;
     const char *ptr;
@@ -777,33 +793,7 @@
 rb_str_buf_append(str, str2)
     VALUE str, str2;
 {
-    long capa, len;
-
-    rb_str_modify(str);
-    if (FL_TEST(str, STR_ASSOC)) {
-	FL_UNSET(str, STR_ASSOC);
-	capa = RSTRING(str)->aux.capa = RSTRING(str)->len;
-    }
-    else {
-	capa = RSTRING(str)->aux.capa;
-    }
-    len = RSTRING(str)->len+RSTRING(str2)->len;
-    if (len < 0 || (capa+1) > LONG_MAX / 2) {
-	rb_raise(rb_eArgError, "string sizes too big");
-    }
-    if (capa <= len) {
-	while (len > capa) {
-	    capa = (capa + 1) * 2;
-	}
-	RESIZE_CAPA(str, capa);
-    }
-    memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
-	   RSTRING(str2)->ptr, RSTRING(str2)->len);
-    RSTRING(str)->len += RSTRING(str2)->len;
-    RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
-    OBJ_INFECT(str, str2);
-
-    return str;
+    return str_buf_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
 }
 
 VALUE

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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