[PATCH #62] Fixed buffer overrun. Reworked to not use dstring for more
efficient parsing.
This commit is contained in:
parent
24a13736bd
commit
e92e2c7362
|
|
@ -22,7 +22,7 @@ int cieq(const char *p, const char *s);
|
||||||
int ciprefix(const char *p, const char *s);
|
int ciprefix(const char *p, const char *s);
|
||||||
void strtolower(char *str);
|
void strtolower(char *str);
|
||||||
void strtoupper(char *str);
|
void strtoupper(char *str);
|
||||||
char * stripWhiteSpacesInsideParens(char *str);
|
char * stripWhiteSpacesInsideParens(const char *str);
|
||||||
char * gettok(char **s);
|
char * gettok(char **s);
|
||||||
char * gettok_instance(char **);
|
char * gettok_instance(char **);
|
||||||
char * gettok_char(char **s, char p, bool inc_p, bool nested);
|
char * gettok_char(char **s, char p, bool inc_p, bool nested);
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,6 @@ cimatch(char *p, char *s)
|
||||||
* since I didn't want to break any fcns which called it from elsewhere than
|
* since I didn't want to break any fcns which called it from elsewhere than
|
||||||
* subckt.c. -- SDB 12.3.2003.
|
* subckt.c. -- SDB 12.3.2003.
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
gettok(char **s)
|
gettok(char **s)
|
||||||
{
|
{
|
||||||
|
|
@ -350,44 +349,63 @@ nexttok(const char *s)
|
||||||
char *
|
char *
|
||||||
gettok_iv(char **s)
|
gettok_iv(char **s)
|
||||||
{
|
{
|
||||||
char c;
|
char *p_src = *s; /* location in source string */
|
||||||
int paren;
|
char c; /* current char */
|
||||||
char *token; /* return token */
|
|
||||||
SPICE_DSTRING buf; /* allow any length string */
|
|
||||||
|
|
||||||
paren = 0;
|
/* Step past whitespace and '=' */
|
||||||
while (isspace_c(**s) || (**s == '='))
|
while (isspace_c(c = *p_src) || (c == '=')) {
|
||||||
(*s)++;
|
p_src++;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!**s) || ((**s != 'v') && (**s != 'i') && (**s != 'V') && (**s != 'I')))
|
/* Test for valid leading character */
|
||||||
return NULL;
|
if (((c =*p_src) == '\0') ||
|
||||||
|
((c != 'v') && (c != 'i') && (c != 'V') && (c != 'I'))) {
|
||||||
|
*s = p_src; /* update position in string */
|
||||||
|
return (char *) NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate buffer for token being returned */
|
||||||
|
char * const token = TMALLOC(char, strlen(p_src) + 1);
|
||||||
|
char *p_dst = token; /* location in token */
|
||||||
|
|
||||||
// initialize string
|
|
||||||
spice_dstring_init(&buf);
|
|
||||||
// add v or i to buf
|
// add v or i to buf
|
||||||
spice_dstring_append_char(&buf, *(*s)++);
|
*p_dst++ = *p_src++;
|
||||||
|
|
||||||
while ((c = **s) != '\0') {
|
{
|
||||||
if (c == '(')
|
int n_paren = 0;
|
||||||
paren += 1;
|
/* Skip any space between v/V/i/I and '(' */
|
||||||
else if (c == ')')
|
p_src = skip_ws(p_src);
|
||||||
paren -= 1;
|
|
||||||
if (isspace_c(c))
|
while ((c = *p_src) != '\0') {
|
||||||
(*s)++;
|
/* Keep track of nesting level */
|
||||||
|
if (c == '(') {
|
||||||
|
n_paren++;
|
||||||
|
}
|
||||||
|
else if (c == ')') {
|
||||||
|
n_paren--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isspace_c(c)) { /* Do not copy whitespace to output */
|
||||||
|
p_src++;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
spice_dstring_append_char(&buf, *(*s)++);
|
*p_dst++ = *p_src++;
|
||||||
if (paren == 0)
|
if (n_paren == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (isspace_c(**s) || **s == ',')
|
/* Step past whitespace and ',' */
|
||||||
(*s)++;
|
while (isspace_c(c = *p_src) || (c == ',')) {
|
||||||
|
p_src++;
|
||||||
|
}
|
||||||
|
|
||||||
token = copy(spice_dstring_value(&buf));
|
*s = p_src; /* update position in string */
|
||||||
spice_dstring_free(&buf);
|
|
||||||
return token;
|
return token;
|
||||||
}
|
} /* end of function gettok_iv */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*
|
/*-------------------------------------------------------------------------*
|
||||||
|
|
@ -650,36 +668,55 @@ get_r_paren(char **s)
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*
|
/*-------------------------------------------------------------------------*
|
||||||
* this function strips all white space inside parens
|
* this function strips all white space inside parens
|
||||||
* is needed in gettoks (dotcards.c) for right processing of expressions
|
* is needed in gettoks (dotcards.c) for correct processing of expressions
|
||||||
* like ".plot v( 5,4) v(6)"
|
* like " .plot v( 5 , 4 ) v( 6 )" -> .plot v(5,4) v(6)"
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
stripWhiteSpacesInsideParens(char *str)
|
stripWhiteSpacesInsideParens(const char *str)
|
||||||
{
|
{
|
||||||
char *token; /* return token */
|
str = skip_ws(str); /* Skip leading whitespace */
|
||||||
SPICE_DSTRING buf; /* allow any length string */
|
const size_t n_char_str = strlen(str);
|
||||||
int i = 0; /* index into string */
|
|
||||||
|
|
||||||
while ((str[i] == ' ') || (str[i] == '\t'))
|
/* Allocate buffer for string being built */
|
||||||
i++;
|
char * const str_out = TMALLOC(char, n_char_str + 1);
|
||||||
|
char *p_dst = str_out; /* location in str_out */
|
||||||
|
char ch; /* current char */
|
||||||
|
|
||||||
spice_dstring_init(&buf);
|
/* Process input string until its end */
|
||||||
for (; str[i]; i++)
|
for ( ; ; ) {
|
||||||
if (str[i] != '(') {
|
/* Add char. If at end of input string, return the string
|
||||||
spice_dstring_append_char(&buf, str[i]);
|
* that was built */
|
||||||
} else {
|
if ((*p_dst++ = (ch = *str++)) == '\0') {
|
||||||
spice_dstring_append_char(&buf, str[i]);
|
return str_out;
|
||||||
while (str[i++] != ')')
|
|
||||||
if (str[i] != ' ')
|
|
||||||
spice_dstring_append_char(&buf, str[i]);
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token = copy(spice_dstring_value(&buf));
|
/* If the char is a ')' add all non-whitespace until ')' or,
|
||||||
spice_dstring_free(&buf);
|
* if the string is malformed, until '\0' */
|
||||||
return token;
|
if (ch == '(') {
|
||||||
}
|
for ( ; ; ) {
|
||||||
|
/* If at end of input string, the closing ') was missing.
|
||||||
|
* The caller will need to resolve this issue. */
|
||||||
|
if ((ch = *str++) == '\0') {
|
||||||
|
*p_dst = '\0';
|
||||||
|
return str_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isspace((int) ch)) { /* skip whitespace */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not whitespace, so add next character */
|
||||||
|
*p_dst++ = ch;
|
||||||
|
|
||||||
|
/* If the char that was added was ')', done */
|
||||||
|
if (ch == ')') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* end of loop processing () */
|
||||||
|
} /* end of case of '(' found */
|
||||||
|
} /* end of loop over chars in input string */
|
||||||
|
} /* end of function stripWhiteSpacesInsideParens */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -761,3 +798,6 @@ model_name_match(const char *token, const char *model_name)
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue