From e8ecb8ccfe8b2356cbd4b4cbf3d078e5a8ad3177 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 17 Nov 2020 18:50:22 +0100 Subject: [PATCH] When .nodeset or .ic was called with a non-existent node, ngspice emitted a warning message, but then moved on, inserting it as a new node with fcn INPtermInsert(). This of course is totally wrong and leads to memory corruption. Now there is a new fcn INPtermSearch(), which just checks if the node is existent. If yes, it will get the value according to the .ic statement, if not, a warning message is emitted, and the non-existent node is simply ignored. --- src/include/ngspice/inpdefs.h | 1 + src/spicelib/parser/inppas3.c | 24 ++++++++++++++++++++---- src/spicelib/parser/inpsymt.c | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index e8d9c864f..a5a6fb8bc 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -135,6 +135,7 @@ void INPpas3( CKTcircuit *, struct card *, INPtables *, TSKtask *, IFparm *, int); int INPpName(char *, IFvalue *, CKTcircuit *, int, GENinstance *); int INPtermInsert(CKTcircuit *, char **, INPtables *, CKTnode **); +int INPtermSearch(CKTcircuit*, char**, INPtables*, CKTnode**); int INPmkTerm(CKTcircuit *, char **, INPtables *, CKTnode **); int INPtypelook(char *); int INP2dot(CKTcircuit *, INPtables *, struct card *, TSKtask *, CKTnode *); diff --git a/src/spicelib/parser/inppas3.c b/src/spicelib/parser/inppas3.c index 87e47b0bd..d1eaf6b13 100644 --- a/src/spicelib/parser/inppas3.c +++ b/src/spicelib/parser/inppas3.c @@ -90,9 +90,17 @@ INPpas3(CKTcircuit *ckt, struct card *data, INPtables *tab, TSKtask *task, /* looks like V - must be V(xx) - get xx now*/ char *nodename; INPgetNetTok(&line,&nodename,1); - if (INPtermInsert(ckt,&nodename,tab,&node1)!=E_EXISTS) + /* If node is not found, issue a warning, ignore the defective token */ + if (INPtermSearch(ckt, &nodename, tab, &node1) != E_EXISTS) { fprintf(stderr, - "Warning : Nodeset on non-existant node - %s\n", nodename); + "Warning : Nodeset on non-existent node - %s, ignored\n", nodename); + fprintf(stderr, + " Please check line %s\n\n", current->line); + FREE(name); + /* Gobble the rest of the token */ + line = nexttok(line); + continue; + } ptemp.rValue = INPevaluate(&line,&error,1); IFC(setNodeParm, (ckt, node1, which, &ptemp, NULL)); FREE(name); @@ -131,9 +139,17 @@ INPpas3(CKTcircuit *ckt, struct card *data, INPtables *tab, TSKtask *task, /* looks like V - must be V(xx) - get xx now*/ char *nodename; INPgetNetTok(&line,&nodename,1); - if (INPtermInsert(ckt,&nodename,tab,&node1)!=E_EXISTS) + /* If node is not found, issue a warning, ignore the defective token */ + if (INPtermSearch(ckt, &nodename, tab, &node1) != E_EXISTS) { fprintf(stderr, - "Warning : IC on non-existant node - %s\n", nodename); + "Warning : IC on non-existent node - %s, ignored\n", nodename); + fprintf(stderr, + " Please check line %s\n\n", current->line); + FREE(name); + /* Gobble the rest of the token */ + line = nexttok(line); + continue; + } ptemp.rValue = INPevaluate(&line,&error,1); IFC(setNodeParm, (ckt, node1, which, &ptemp, NULL)); FREE(name); diff --git a/src/spicelib/parser/inpsymt.c b/src/spicelib/parser/inpsymt.c index d77b23265..4cec02c89 100644 --- a/src/spicelib/parser/inpsymt.c +++ b/src/spicelib/parser/inpsymt.c @@ -281,3 +281,25 @@ static int hash(char *name, int tsize) return (int) (hash % (unsigned) tsize); } + +/* Just tests for the existence of a node. If node is found, its + token and node adresses are fed back. + Return value 0 if no node is found, E_EXISTS if its already there */ +int INPtermSearch(CKTcircuit* ckt, char** token, INPtables* tab, CKTnode** node) +{ + int key; + struct INPnTab* t; + NG_IGNORE(ckt); + + key = hash(*token, tab->INPtermsize); + for (t = tab->INPtermsymtab[key]; t; t = t->t_next) { + if (!strcmp(*token, t->t_ent)) { + FREE(*token); + *token = t->t_ent; + if (node) + *node = t->t_node; + return (E_EXISTS); + } + } + return (0); +}