From kevin.hendricks at sympatico.ca  Wed Jun 14 21:04:01 2006
From: kevin.hendricks at sympatico.ca (Kevin B. Hendricks)
Date: Wed, 14 Jun 2006 15:04:01 -0400
Subject: [Rd] More: Hopefully Final Fix for Bug 8141 (C stack overflow in
	substituteList)
Message-ID: <50F91D63-65DD-4452-84DC-7F688F8E6B86@sympatico.ca>

Hi,

Just in case anyone is interested in bug 8141.   With some further  
testing,  I found and fixed a small bug in my code and simplified it  
a bit.

Here is the latest version of the coerce.c routine substituteList  
that fixes the C stack overflow problem as documented in Bug 8141.

Comments welcome.  If people are satisfied with this version I will  
submit a final patch to r-devel sources.

Kevin

/* Work through a list doing substitute on the */
/* elements taking particular care to handle ... */


SEXP attribute_hidden substituteList(SEXP el, SEXP rho)
{
     SEXP h, p, n = R_NilValue;
     p = R_NilValue;
     while (el != R_NilValue) {

         if (CAR(el) == R_DotsSymbol) {
             if (rho == R_NilValue)
                 h = R_UnboundValue;     /* so there is no  
substitution below */
             else
                 h = findVarInFrame3(rho, CAR(el), TRUE);
             if (h == R_UnboundValue)
                 h = lcons(R_DotsSymbol, R_NilValue);
             else if (h == R_NilValue  || h == R_MissingArg)
                 h = R_NilValue;
             else if (TYPEOF(h) == DOTSXP)
                 h = substituteList(h, R_NilValue);
             else {
                 error(_("... used in an incorrect context"));
                 h = R_NilValue;
             }
         }
         else {
             h = substitute(CAR(el), rho);
             if (isLanguage(el))
                 h = LCONS(h, R_NilValue);
             else
                 h = CONS(h, R_NilValue);
             SET_TAG(h, TAG(el));
         }

         if (h != R_NilValue) {
             if (n == R_NilValue)
                 PROTECT(n=h);
             else
                 SETCDR(p,h);
             while ( CDR(h) != R_NilValue ) h = CDR(h);
             p = h;
         }
         el = CDR(el);

     }
     if (n != R_NilValue) {
        UNPROTECT(1);
     }
     return n;
}



[Rd] More: Hopefully Final Fix for Bug 8141 (C stack overflow in substituteList)
Kevin B. Hendricks