[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);
|
||||
void strtolower(char *str);
|
||||
void strtoupper(char *str);
|
||||
char * stripWhiteSpacesInsideParens(char *str);
|
||||
char * stripWhiteSpacesInsideParens(const char *str);
|
||||
char * gettok(char **s);
|
||||
char * gettok_instance(char **);
|
||||
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
|
||||
* subckt.c. -- SDB 12.3.2003.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
char *
|
||||
gettok(char **s)
|
||||
{
|
||||
|
|
@ -350,44 +349,63 @@ nexttok(const char *s)
|
|||
char *
|
||||
gettok_iv(char **s)
|
||||
{
|
||||
char c;
|
||||
int paren;
|
||||
char *token; /* return token */
|
||||
SPICE_DSTRING buf; /* allow any length string */
|
||||
char *p_src = *s; /* location in source string */
|
||||
char c; /* current char */
|
||||
|
||||
paren = 0;
|
||||
while (isspace_c(**s) || (**s == '='))
|
||||
(*s)++;
|
||||
/* Step past whitespace and '=' */
|
||||
while (isspace_c(c = *p_src) || (c == '=')) {
|
||||
p_src++;
|
||||
}
|
||||
|
||||
if ((!**s) || ((**s != 'v') && (**s != 'i') && (**s != 'V') && (**s != 'I')))
|
||||
return NULL;
|
||||
/* Test for valid leading character */
|
||||
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
|
||||
spice_dstring_append_char(&buf, *(*s)++);
|
||||
*p_dst++ = *p_src++;
|
||||
|
||||
while ((c = **s) != '\0') {
|
||||
if (c == '(')
|
||||
paren += 1;
|
||||
else if (c == ')')
|
||||
paren -= 1;
|
||||
if (isspace_c(c))
|
||||
(*s)++;
|
||||
else {
|
||||
spice_dstring_append_char(&buf, *(*s)++);
|
||||
if (paren == 0)
|
||||
break;
|
||||
{
|
||||
int n_paren = 0;
|
||||
/* Skip any space between v/V/i/I and '(' */
|
||||
p_src = skip_ws(p_src);
|
||||
|
||||
while ((c = *p_src) != '\0') {
|
||||
/* 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 {
|
||||
*p_dst++ = *p_src++;
|
||||
if (n_paren == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (isspace_c(**s) || **s == ',')
|
||||
(*s)++;
|
||||
/* Step past whitespace and ',' */
|
||||
while (isspace_c(c = *p_src) || (c == ',')) {
|
||||
p_src++;
|
||||
}
|
||||
|
||||
token = copy(spice_dstring_value(&buf));
|
||||
spice_dstring_free(&buf);
|
||||
*s = p_src; /* update position in string */
|
||||
return token;
|
||||
}
|
||||
} /* end of function gettok_iv */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
|
|
@ -650,36 +668,55 @@ get_r_paren(char **s)
|
|||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* this function strips all white space inside parens
|
||||
* is needed in gettoks (dotcards.c) for right processing of expressions
|
||||
* like ".plot v( 5,4) v(6)"
|
||||
* is needed in gettoks (dotcards.c) for correct processing of expressions
|
||||
* like " .plot v( 5 , 4 ) v( 6 )" -> .plot v(5,4) v(6)"
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
char *
|
||||
stripWhiteSpacesInsideParens(char *str)
|
||||
stripWhiteSpacesInsideParens(const char *str)
|
||||
{
|
||||
char *token; /* return token */
|
||||
SPICE_DSTRING buf; /* allow any length string */
|
||||
int i = 0; /* index into string */
|
||||
str = skip_ws(str); /* Skip leading whitespace */
|
||||
const size_t n_char_str = strlen(str);
|
||||
|
||||
while ((str[i] == ' ') || (str[i] == '\t'))
|
||||
i++;
|
||||
/* Allocate buffer for string being built */
|
||||
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);
|
||||
for (; str[i]; i++)
|
||||
if (str[i] != '(') {
|
||||
spice_dstring_append_char(&buf, str[i]);
|
||||
} else {
|
||||
spice_dstring_append_char(&buf, str[i]);
|
||||
while (str[i++] != ')')
|
||||
if (str[i] != ' ')
|
||||
spice_dstring_append_char(&buf, str[i]);
|
||||
i--;
|
||||
/* Process input string until its end */
|
||||
for ( ; ; ) {
|
||||
/* Add char. If at end of input string, return the string
|
||||
* that was built */
|
||||
if ((*p_dst++ = (ch = *str++)) == '\0') {
|
||||
return str_out;
|
||||
}
|
||||
|
||||
token = copy(spice_dstring_value(&buf));
|
||||
spice_dstring_free(&buf);
|
||||
return token;
|
||||
}
|
||||
/* If the char is a ')' add all non-whitespace until ')' or,
|
||||
* if the string is malformed, until '\0' */
|
||||
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
|
||||
|
|
@ -761,3 +798,6 @@ model_name_match(const char *token, const char *model_name)
|
|||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue