[#24536] 「Rubyの落し方」 v.s. ruby_1_8 — akira yamada / やまだあきら <akira@...>

<URL:http://jp.rubyist.net/magazine/?0002-RubyCore>

40 messages 2004/10/20
[#24541] Re: 「Rubyの落し方」 v.s. ruby_1_8 — Yukihiro Matsumoto <matz@...> 2004/10/20

まつもと ゆきひろです

[#24599] 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/26

2004-10-20 (水) の 21:38 +0900 に Yukihiro Matsumoto さんは書きました:

[#24605] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-26 (火) の 16:16 +0900 に akira yamada / やまだあきら さんは書きました:

[#24606] Re: 1.8.2 preview3? — Yukihiro Matsumoto <matz@...> 2004/10/27

まつもと ゆきひろです

[#24608] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 11:48 +0900 に Yukihiro Matsumoto さんは書きました:

[#24620] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 12:42 +0900 に akira yamada / やまだあきら さんは書きました:

[#24629] Re: 1.8.2 preview3? — Tanaka Akira <akr@...17n.org> 2004/10/29

In article <1098888819.9446.14.camel@rice.p.arika.org>,

[ruby-dev:24601] Re: unpack("p") dumps core

From: nobu@...
Date: 2004-10-26 12:50:18 UTC
List: ruby-dev #24601
なかだです。

At Tue, 26 Oct 2004 18:21:30 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:24600]:
> |str_independent()ではSTR_ASSOCを見ていないので(STR_NO_ORIGから
> |変更されたとき以来?)、rb_str_modify()ではSTR_ASSOCがクリアされ
> |ていないようです。また、gsub!やsucc!ではstr_independent()によっ
> |てptrをfreeしているので、["abc"].pack("p").gsub!(/.*/, '')など
> |とするとメモリリークしそうです。
> 
> RESIZE_CAPA()でSTR_ASSOCを見ることで問題は解決するような気が
> します。

aux.capaを変更 == aux.sharedは無効、ということですね。他のcapa
を変更しているところはSTR_ASSOCをクリアしているようです。

> |# というか、str_gsub()のbufって例外のときにも大丈夫?
> 
> 気にはなっているんですが。

Stringをバッファにするということでどうでしょうか。


Index: string.c
===================================================================
RCS file: /cvs/ruby/src/ruby/string.c,v
retrieving revision 1.209
diff -U2 -p -d -r1.209 string.c
--- string.c	21 Oct 2004 15:20:41 -0000	1.209
+++ string.c	26 Oct 2004 12:46:05 -0000
@@ -33,8 +33,22 @@ VALUE rb_cString;
     REALLOC_N(RSTRING(str)->ptr, char, (capacity)+1);\
     RSTRING(str)->aux.capa = (capacity);\
+    FL_UNSET(str, STR_ASSOC|ELTS_SHARED);\
 } while (0)
 
 VALUE rb_fs;
 
+static int str_independent _((VALUE));
+
+static inline void
+str_mod_check(s, p, len)
+    VALUE s;
+    char *p;
+    long len;
+{
+    if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {
+	rb_raise(rb_eRuntimeError, "string modified");
+    }
+}
+
 static VALUE str_alloc _((VALUE));
 static VALUE
@@ -2009,5 +2023,5 @@ str_gsub(argc, argv, str, bang)
     int bang;
 {
-    VALUE pat, val, repl, match;
+    VALUE pat, val, repl, match, dest;
     struct re_registers *regs;
     long beg, n;
@@ -2038,5 +2052,6 @@ str_gsub(argc, argv, str, bang)
 
     blen = RSTRING(str)->len + 30; /* len + margin */
-    buf = ALLOC_N(char, blen);
+    dest = rb_str_new5(str, 0, blen);
+    buf = RSTRING(dest)->ptr;
     bp = buf;
     cp = RSTRING(str)->ptr;
@@ -2049,7 +2064,5 @@ str_gsub(argc, argv, str, bang)
 	    rb_match_busy(match);
 	    val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
-	    if (RSTRING(str)->ptr == buf) {
-		rb_raise(rb_eRuntimeError, "gsub reentered");
-	    }
+	    str_mod_check(dest, buf, blen);
 	    rb_backref_set(match);
 	}
@@ -2062,5 +2075,7 @@ str_gsub(argc, argv, str, bang)
 	    while (blen < len) blen *= 2;
 	    len = bp - buf;
-	    REALLOC_N(buf, char, blen);
+	    RESIZE_CAPA(dest, blen);
+	    RSTRING(dest)->len = blen;
+	    buf = RSTRING(dest)->ptr;
 	    bp = buf + len;
 	}
@@ -2088,6 +2103,8 @@ str_gsub(argc, argv, str, bang)
     if (RSTRING(str)->len > offset) {
 	len = bp - buf;
-	if (blen - len < RSTRING(str)->len - offset + 1) {
-	    REALLOC_N(buf, char, len + RSTRING(str)->len - offset + 1);
+	if (blen - len < RSTRING(str)->len - offset) {
+	    blen = len + RSTRING(str)->len - offset;
+	    RESIZE_CAPA(dest, blen);
+	    buf = RSTRING(dest)->ptr;
 	    bp = buf + len;
 	}
@@ -2096,4 +2113,5 @@ str_gsub(argc, argv, str, bang)
     }
     rb_backref_set(match);
+    *bp = '\0';
     if (bang) {
 	if (str_independent(str)) {
@@ -2101,15 +2119,14 @@ str_gsub(argc, argv, str, bang)
 	}
 	FL_UNSET(str, ELTS_SHARED|STR_ASSOC);
+	RSTRING(str)->ptr = buf;
+	RSTRING(str)->aux.capa = blen;
+	RSTRING(dest)->ptr = 0;
+	RSTRING(dest)->len = 0;
     }
     else {
-	VALUE dup = str_alloc(rb_obj_class(str));
-
-	OBJ_INFECT(dup, str);
-	str = dup;
+	OBJ_INFECT(dest, str);
+	str = dest;
     }
-    RSTRING(str)->ptr = buf;
-    RSTRING(str)->len = len = bp - buf;
-    RSTRING(str)->ptr[len] = '\0';
-    RSTRING(str)->aux.capa = len;
+    RSTRING(str)->len = bp - buf;
 
     if (tainted) OBJ_TAINT(str);
@@ -3591,16 +3608,4 @@ rb_f_split(argc, argv)
 {
     return rb_str_split_m(argc, argv, uscore_get());
-}
-
-
-static inline void
-str_mod_check(s, p, len)
-    VALUE s;
-    char *p;
-    long len;
-{
-    if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {
-	rb_raise(rb_eRuntimeError, "string modified");
-    }
 }
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread