RE: [ng-spice-devel] variable.c


To "'ng-spice-devel@ieee.ing.uniroma1.it'" <ng-spice-devel@ieee.ing.uniroma1.it>
From "Gillespie, Alan" <Alan.Gillespie@analog.com>
Date Thu, 11 Jan 2001 10:36:04 -0000
Delivered-To mailing list ng-spice-devel@ieee.ing.uniroma1.it
Mailing-List contact ng-spice-devel-help@ieee.ing.uniroma1.it; run by ezmlm
Reply-To ng-spice-devel@ieee.ing.uniroma1.it


In the message below, Glao submitted a patch for variable.c which
corrected the problem. I can't remember if I'm using the latest
file from the CVS, or if I applied the fixes myself.

Paolo, do you know if this got into the CVS ? This is a fairly
annoying bug, and I think a lot of people trying rework-13 will
be giving up in disgust. I know you were working on adding some
new models, but is there any way to release a rework-14 with
this fixed ?

By the way Glao, I'm curious about your name. Your email header
says GLAO S. Dezai, and you sign your emails Glao, but all the
comments in are marked "DG". I've been calling you Glao, but am
I getting that right ?

Cheers,

Alan

> -----Original Message-----
> From: GLAO S. Dezai [mailto:dezai@hotbot.com]
> Sent: 30 November 2000 16:31
> To: ng-spice-devel@ieee.ing.uniroma1.it
> Subject: [ng-spice-devel] variable.c
> 
> 
>  
> Hi all,
> I think that i know now why variable.c fails to run in some cases.
> The reason is to be found in the cp_setparse function.
> 
> I used previously to free the pointer ss  before call of the 
> ft_numparse function:
> 
>                 ss = cp_unquote(wl->wl_word);
>                 td = ft_numparse(&ss, FALSE);
>                  ...          
>                  tfree(ss);
> Here is the problem. When ss contains a number, the 
> ft_numparse increment ss so that at the end of the parsing ss 
> points to the end of the allocated area. Freeing ss results 
> to a segfault. If ss doesnot contains a number there is no problem.
> So to fix the bug something like the following must be done.
>                     
>                 copyval=ss = cp_unquote(wl->wl_word);
>                 td = ft_numparse(&ss, FALSE);
>                  ...          
>                  tfree(copyval);
> 
> Apologies.
> glao
> 
> 
> 
> 
> 
> 
> HotBot - Search smarter.
> http://www.hotbot.com
> 


struct variable *
cp_setparse(wordlist *wl)
{
    char *name, *val, *copyval, *s, *ss;
    double *td;
    struct variable *listv = NULL, *vv, *lv = NULL;
    struct variable *vars = NULL;
    int balance;

    while (wl) {
        name = cp_unquote(wl->wl_word);
        wl = wl->wl_next;
        if (((wl == NULL) || (*wl->wl_word != '=')) && 
               strchr(name, '=') == NULL) {
            vv = alloc(struct variable);
            vv->va_name = copy(name);
            vv->va_type = VT_BOOL;
            vv->va_bool = TRUE;
            vv->va_next = vars;
            vars = vv;
            tfree(name);/*DG: cp_unquote Memory leak*/
            continue;
        }
        if (wl && eq(wl->wl_word, "=")) {
            wl = wl->wl_next;
            if (wl == NULL) {
                fprintf(cp_err, "Error: bad set form.\n");
             tfree(name);/*DG: cp_unquote Memory leak*/
              return (NULL);
            }
            val = wl->wl_word;
            wl = wl->wl_next;
        } else if (wl && (*wl->wl_word == '=')) {
            val = wl->wl_word + 1;
            wl = wl->wl_next;
        } else if ((s =strchr(name, '='))) {
            val = s + 1;
            *s = '\0';
            if (*val == '\0') {
                if (!wl) {
                    fprintf(cp_err,
                        "Error:  %s equals what?.\n",
                        name);
                   tfree(name);/*DG: cp_unquote Memory leak: free name before 
exiting*/
                   return (NULL);
                } else {
                    val = wl->wl_word;
                    wl = wl->wl_next;
                }
            }
        } else {
            fprintf(cp_err, "Error: bad set form.\n");
             tfree(name);/*DG: cp_unquote Memory leak: free name befor 
exiting */
             return (NULL);
        }
     /*   val = cp_unquote(val);  DG: bad   old val is lost*/ 
          copyval=cp_unquote(val);/*DG*/
          strcpy(val,copyval);
          tfree(copyval);
        if (eq(val, "(")) { /* ) */
            /* The beginning of a list... We have to walk down the
             * list until we find a close paren... If there are nested
             * ()'s, treat them as tokens...  */
            balance = 1;
            while (wl && wl->wl_word) {
                if (eq(wl->wl_word, "(")) {
                    balance++;
                } else if (eq(wl->wl_word, ")")) {
                    if (!--balance)
                        break;
                }
                vv = alloc(struct variable);
                vv->va_next = NULL;
                copyval=ss = cp_unquote(wl->wl_word);
                td = ft_numparse(&ss, FALSE);
                if (td) {
                    vv->va_type = VT_REAL;
                    vv->va_real = *td;
                } else {
                    vv->va_type = VT_STRING;
                    vv->va_string = copy(ss);
                }
                 tfree(copyval);/*DG: must free copyval any way to avoid 
cp_unquote memory leak*/
                if (listv) {
                    lv->va_next = vv;
                    lv = vv;
                } else
                    listv = lv = vv;
                wl = wl->wl_next;
            }
            if (balance && !wl) {
                fprintf(cp_err, "Error: bad set form.\n");
                return (NULL);
            }
            
            vv = alloc(struct variable);
            vv->va_name = copy(name);
            vv->va_type = VT_LIST;
            vv->va_vlist = listv;
            vv->va_next = vars;
            vars = vv;

            wl = wl->wl_next;
            continue;
        }

       copyval= ss = cp_unquote(val);
        td = ft_numparse(&ss, FALSE);
        vv = alloc(struct variable);
        vv->va_name = copy(name);
        vv->va_next = vars;
        vars = vv;
        if (td) {
            /*** We should try to get VT_NUM's... */
            vv->va_type = VT_REAL;
            vv->va_real = *td;
        } else {
            vv->va_type = VT_STRING;
            vv->va_string = copy(ss);
        }
        tfree(copyval);/*DG: avoid cp_unquote memory leak */
    }
    return (vars);
}

Partial thread listing: