[PATCH #50] Ensured no buffer overrun for long namess and improved
efficiency of compare. Also made more modular.
This commit is contained in:
parent
61d50f7177
commit
24e8e7d33b
|
|
@ -19,92 +19,83 @@ Patched: 2010/2012 by Bill Swartz (hash table for vectors)
|
|||
#include <ngspice/dstring.h>
|
||||
#include "variable.h"
|
||||
|
||||
static bool nameeq(const char *n1,const char *n2);
|
||||
static char *canonical_name(const char *name, SPICE_DSTRINGPTR dbuf_p,
|
||||
bool make_i_name_lower);
|
||||
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
cannonical_name(char *name, SPICE_DSTRINGPTR dbuf_p)
|
||||
canonical_name(const char *name, SPICE_DSTRINGPTR dbuf_p,
|
||||
bool make_i_name_lower)
|
||||
{
|
||||
char *tmp; /* position in string */
|
||||
char *ptr; /* current position in string */
|
||||
spice_dstring_reinit(dbuf_p); /* Reset dynamic buffer */
|
||||
|
||||
spice_dstring_reinit(dbuf_p);
|
||||
|
||||
if (ciprefix("i(",name)) {
|
||||
tmp = name;
|
||||
while (*tmp != '(')
|
||||
tmp++;
|
||||
tmp++;
|
||||
for (ptr = tmp; *ptr; ptr++)
|
||||
if (isupper_c(*ptr))
|
||||
tmp = spice_dstring_append_char(dbuf_p, tolower_c(*ptr));
|
||||
else
|
||||
tmp = spice_dstring_append_char(dbuf_p, *ptr);
|
||||
while (*tmp != ')')
|
||||
tmp++;
|
||||
*tmp = '\0';
|
||||
tmp = spice_dstring_append(dbuf_p, "#branch", -1);
|
||||
} else if (isdigit_c(*name)) {
|
||||
spice_dstring_append(dbuf_p, "v(", -1);
|
||||
spice_dstring_append(dbuf_p, name, -1);
|
||||
tmp = spice_dstring_append_char(dbuf_p, ')');
|
||||
} else {
|
||||
tmp = spice_dstring_append(dbuf_p, name, -1);
|
||||
/* "i(some_name)" -> "some_name#branch" */
|
||||
/* "I(some_name)" -> "some_name#branch" */
|
||||
if (ciprefix("i(", name)) {
|
||||
static const char sz_branch[] = "#branch";
|
||||
const char *p_start = name + 2;
|
||||
size_t n = strlen(p_start) - 1; /* copy all but final ')' */
|
||||
if (make_i_name_lower) {
|
||||
(void) spice_dstring_append_lower(dbuf_p, p_start, (int) n);
|
||||
}
|
||||
else {
|
||||
(void) spice_dstring_append(dbuf_p, p_start, (int) n);
|
||||
}
|
||||
return spice_dstring_append(dbuf_p, sz_branch,
|
||||
sizeof sz_branch / sizeof *sz_branch - 1);
|
||||
}
|
||||
|
||||
return(tmp);
|
||||
}
|
||||
/* Convert a name starting with a digit, such as a numbered node to
|
||||
* something like v(33) */
|
||||
if (isdigit_c(*name)) {
|
||||
(void) spice_dstring_append(dbuf_p, "v(", 2);
|
||||
(void) spice_dstring_append(dbuf_p, name, -1);
|
||||
return spice_dstring_append_char(dbuf_p, ')');
|
||||
}
|
||||
|
||||
/* Finally if neither of the special cases above occur, there is
|
||||
* no need to do anything with the name. A slight improvement in
|
||||
* performance could be achieved by simply returning the name
|
||||
* argument. Making a copy ensures that it can be modified without
|
||||
* changing the original, but in the current use cases that is
|
||||
* not an issue. */
|
||||
return spice_dstring_append(dbuf_p, name, -1);
|
||||
} /* end of function canonical_name */
|
||||
|
||||
|
||||
/* Determine if two vectors have the 'same' name. */
|
||||
|
||||
/* Determine if two vectors have the 'same' name. Note that this compare can
|
||||
* be performed by using the "canonical" forms returned by
|
||||
* canonical_name(). */
|
||||
static bool
|
||||
nameeq(char *n1, char *n2)
|
||||
nameeq(const char *n1, const char *n2)
|
||||
{
|
||||
char buf1[BSIZE_SP], buf2[BSIZE_SP];
|
||||
char *tmp;
|
||||
|
||||
if (eq(n1, n2))
|
||||
return (TRUE);
|
||||
|
||||
/* n1 or n2 is in the form i(...) or I(...)
|
||||
* This happens in the saved rawfile
|
||||
*/
|
||||
|
||||
if (ciprefix("i(", n1)) {
|
||||
tmp = n1;
|
||||
while (*tmp != '(')
|
||||
tmp++;
|
||||
tmp++;
|
||||
(void) strcpy(buf1, tmp);
|
||||
tmp = buf1;
|
||||
while (*tmp != ')')
|
||||
tmp++;
|
||||
*tmp = '\0';
|
||||
(void) strcat(buf1, "#branch");
|
||||
} else if (isdigit_c(*n1)) {
|
||||
(void) sprintf(buf1, "v(%s)", n1);
|
||||
} else {
|
||||
(void) strcpy(buf1, n1);
|
||||
/* First compare them the way they came in, case insensitive.
|
||||
* If they match nothing more to do */
|
||||
if (cieq(n1, n2)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ciprefix("i(", n2)) {
|
||||
tmp = n2;
|
||||
while (*tmp != '(')
|
||||
tmp++;
|
||||
tmp++;
|
||||
(void) strcpy(buf2, tmp);
|
||||
tmp = buf2;
|
||||
while (*tmp != ')')
|
||||
tmp++;
|
||||
*tmp = '\0';
|
||||
(void) strcat(buf2, "#branch");
|
||||
} else if (isdigit_c(*n2)) {
|
||||
(void) sprintf(buf2, "v(%s)", n2);
|
||||
} else {
|
||||
(void) strcpy(buf2, n2);
|
||||
}
|
||||
SPICE_DSTRING ds1, ds2; /* Buffers to build canonical names */
|
||||
|
||||
/* Init the dynamic string buffers */
|
||||
spice_dstring_init(&ds1);
|
||||
spice_dstring_init(&ds2);
|
||||
|
||||
/* Compare canonical names */
|
||||
const BOOL rc = (BOOL) cieq(canonical_name(n1, &ds1, FALSE),
|
||||
canonical_name(n2, &ds2, FALSE));
|
||||
|
||||
/* Free the dynamic string buffers */
|
||||
spice_dstring_free(&ds1);
|
||||
spice_dstring_free(&ds2);
|
||||
|
||||
return rc;
|
||||
} /* end of function nameeq */
|
||||
|
||||
return (cieq(buf1, buf2) ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
|
|
@ -116,10 +107,10 @@ com_diff(wordlist *wl)
|
|||
double d1, d2;
|
||||
ngcomplex_t c1, c2, c3;
|
||||
int i, j;
|
||||
char *v1_name; /* cannonical v1 name */
|
||||
char *v2_name; /* cannonical v2 name */
|
||||
char *v1_name; /* canonical v1 name */
|
||||
char *v2_name; /* canonical v2 name */
|
||||
NGHASHPTR crossref_p; /* cross reference hash table */
|
||||
SPICE_DSTRING ibuf; /* used to build cannonical name */
|
||||
SPICE_DSTRING ibuf; /* used to build canonical name */
|
||||
wordlist *tw;
|
||||
char numbuf[BSIZE_SP], numbuf2[BSIZE_SP], numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */
|
||||
|
||||
|
|
@ -195,12 +186,12 @@ com_diff(wordlist *wl)
|
|||
|
||||
for (v2 = p2->pl_dvecs; v2; v2 = v2->v_next) {
|
||||
v2->v_link2 = NULL;
|
||||
v2_name = cannonical_name(v2->v_name, &ibuf);
|
||||
v2_name = canonical_name(v2->v_name, &ibuf, TRUE);
|
||||
nghash_insert(crossref_p, v2_name, v2);
|
||||
}
|
||||
|
||||
for (v1 = p1->pl_dvecs; v1; v1 = v1->v_next) {
|
||||
v1_name = cannonical_name(v1->v_name, &ibuf);
|
||||
v1_name = canonical_name(v1->v_name, &ibuf, TRUE);
|
||||
for (v2 = nghash_find(crossref_p, v1_name);
|
||||
v2;
|
||||
v2 = nghash_find_again(crossref_p, v1_name))
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@
|
|||
----------------------------------------------------------------- */
|
||||
#define SPICE_DSTRING_STATIC_SIZE 200
|
||||
typedef struct spice_dstring {
|
||||
char *string ; /* Points to beginning of string: either
|
||||
* staticSpace below or a malloced array. */
|
||||
int length ; /* Number of non-NULL characters in the
|
||||
* string. */
|
||||
int spaceAvl ; /* Total number of bytes available for the
|
||||
* string and its terminating NULL char. */
|
||||
char *string; /* Points to beginning of string: either
|
||||
* staticSpace below or a malloced array. */
|
||||
int length ; /* Number of characters in the string excluding the
|
||||
* terminating NULL. */
|
||||
int spaceAvl ; /* Total number of bytes available for the
|
||||
* string and its terminating NULL char. */
|
||||
char staticSpace[SPICE_DSTRING_STATIC_SIZE] ;
|
||||
/* Space to use in common case where string
|
||||
* is small. */
|
||||
/* Space to use in common case where string
|
||||
* is small. */
|
||||
} SPICE_DSTRING, *SPICE_DSTRINGPTR ;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue