[ruby-dev:24319] Re: String#sub! dumps core

From: nobu@...
Date: 2004-09-23 09:45:31 UTC
List: ruby-dev #24319
なかだです。

At Thu, 23 Sep 2004 13:02:00 +0900,
Tanaka Akira wrote in [ruby-dev:24315]:
> 次のようにすると core を吐きます。
> 
> % ./ruby -e '
> s = "a" * 100
> s.sub!(/a*/) { s.clear; "b" * 100 }
> '
> -e:3: [BUG] Segmentation fault
> ruby 1.9.0 (2004-09-22) [i686-linux]
> 
> zsh: abort (core dumped)  ./ruby -e ' s = "a" * 100 s.sub!(/a*/) { s.clear; "b" * 100 } '

まだありそうでしょうか。


Index: string.c
===================================================================
RCS file: /cvs/ruby/src/ruby/string.c,v
retrieving revision 1.198
diff -U2 -p -d -r1.198 string.c
--- string.c	17 Sep 2004 09:24:12 -0000	1.198
+++ string.c	23 Sep 2004 09:43:41 -0000
@@ -1907,5 +1907,5 @@ rb_str_sub_bang(argc, argv, str)
     int iter = 0;
     int tainted = 0;
-    long plen;
+    long plen, beg, end;
 
     if (argc == 1 && rb_block_given_p()) {
@@ -1926,4 +1926,6 @@ rb_str_sub_bang(argc, argv, str)
 	match = rb_backref_get();
 	regs = RMATCH(match)->regs;
+	beg = BEG(0);
+	end = END(0);
 
 	if (iter) {
@@ -1931,4 +1933,8 @@ rb_str_sub_bang(argc, argv, str)
 	    repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
 	    rb_backref_set(match);
+	    if (END(0) > RSTRING(str)->len) {
+		end = RSTRING(str)->len;
+		if (beg > end) beg = end;
+	    }
 	}
 	else {
@@ -1936,14 +1942,14 @@ rb_str_sub_bang(argc, argv, str)
 	}
 	if (OBJ_TAINTED(repl)) tainted = 1;
-	plen = END(0) - BEG(0);
+	plen = end - beg;
 	if (RSTRING(repl)->len > plen) {
 	    RESIZE_CAPA(str, RSTRING(str)->len + RSTRING(repl)->len - plen);
 	}
 	if (RSTRING(repl)->len != plen) {
-	    memmove(RSTRING(str)->ptr + BEG(0) + RSTRING(repl)->len,
-		    RSTRING(str)->ptr + BEG(0) + plen,
-		    RSTRING(str)->len - BEG(0) - plen);
+	    memmove(RSTRING(str)->ptr + beg + RSTRING(repl)->len,
+		    RSTRING(str)->ptr + end,
+		    RSTRING(str)->len - end);
 	}
-	memcpy(RSTRING(str)->ptr + BEG(0),
+	memcpy(RSTRING(str)->ptr + beg,
 	       RSTRING(repl)->ptr, RSTRING(repl)->len);
 	RSTRING(str)->len += RSTRING(repl)->len - plen;


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

In This Thread