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

ruby-changes:4117

From: ko1@a...
Date: Tue, 26 Feb 2008 15:30:54 +0900 (JST)
Subject: [ruby-changes:4117] nobu - Ruby:r15607 (trunk): * array.c (rb_ary_eql, rb_ary_cmp): get rid of stack overflow with

nobu	2008-02-26 15:30:38 +0900 (Tue, 26 Feb 2008)

  New Revision: 15607

  Modified files:
    trunk/ChangeLog
    trunk/array.c

  Log:
    * array.c (rb_ary_eql, rb_ary_cmp): get rid of stack overflow with
      self-recursive constructs.  [ruby-Bugs-18356]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/array.c?r1=15607&r2=15606&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15607&r2=15606&diff_format=u

Index: array.c
===================================================================
--- array.c	(revision 15606)
+++ array.c	(revision 15607)
@@ -317,7 +317,7 @@
 	rb_raise(rb_eArgError, "array size too big");
     }
     rb_ary_modify(ary);
-	RESIZE_CAPA(ary, len);
+    RESIZE_CAPA(ary, len);
     if (rb_block_given_p()) {
 	long i;
 
@@ -2343,6 +2343,19 @@
     return rb_exec_recursive(recursive_equal, ary1, ary2);
 }
 
+static VALUE
+recursive_eql(VALUE ary1, VALUE ary2, int recur)
+{
+    long i;
+
+    if (recur) return Qfalse;
+    for (i=0; i<RARRAY_LEN(ary1); i++) {
+	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+	    return Qfalse;
+    }
+    return Qtrue;
+}
+
 /*
  *  call-seq:
  *     array.eql?(other)  -> true or false
@@ -2354,16 +2367,10 @@
 static VALUE
 rb_ary_eql(VALUE ary1, VALUE ary2)
 {
-    long i;
-
     if (ary1 == ary2) return Qtrue;
     if (TYPE(ary2) != T_ARRAY) return Qfalse;
     if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
-    for (i=0; i<RARRAY_LEN(ary1); i++) {
-	if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
-	    return Qfalse;
-    }
-    return Qtrue;
+    return rb_exec_recursive(recursive_eql, ary1, ary2);
 }
 
 static VALUE
@@ -2425,6 +2432,25 @@
 }
 
 
+static VALUE
+recursive_cmp(VALUE ary1, VALUE ary2, int recur)
+{
+    long i, len;
+
+    if (recur) return Qnil;
+    len = RARRAY_LEN(ary1);
+    if (len > RARRAY_LEN(ary2)) {
+	len = RARRAY_LEN(ary2);
+    }
+    for (i=0; i<RARRAY_LEN(ary1); i++) {
+	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
+	if (v != INT2FIX(0)) {
+	    return v;
+	}
+    }
+    return Qundef;
+}
+
 /* 
  *  call-seq:
  *     array <=> other_array   ->  -1, 0, +1
@@ -2448,19 +2474,13 @@
 VALUE
 rb_ary_cmp(VALUE ary1, VALUE ary2)
 {
-    long i, len;
+    long len;
+    VALUE v;
 
     ary2 = to_ary(ary2);
-    len = RARRAY_LEN(ary1);
-    if (len > RARRAY_LEN(ary2)) {
-	len = RARRAY_LEN(ary2);
-    }
-    for (i=0; i<len; i++) {
-	VALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));
-	if (v != INT2FIX(0)) {
-	    return v;
-	}
-    }
+    if (ary1 == ary2) return INT2FIX(0);
+    v = rb_exec_recursive(recursive_cmp, ary1, ary2);
+    if (v != Qundef) return v;
     len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
     if (len == 0) return INT2FIX(0);
     if (len > 0) return INT2FIX(1);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15606)
+++ ChangeLog	(revision 15607)
@@ -1,3 +1,8 @@
+Tue Feb 26 15:30:36 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* array.c (rb_ary_eql, rb_ary_cmp): get rid of stack overflow with
+	  self-recursive constructs.  [ruby-Bugs-18356]
+
 Tue Feb 26 01:16:01 2008  Tanaka Akira  <akr@f...>
 
 	* include/ruby/ruby.h (ROBJECT_NUMIV): renamed from ROBJECT_LEN.

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

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