Fix replace handling corner case
With flags DOH_REPLACE_ID_BEGIN, DOH_REPLACE_ID_END and
DOH_REPLACE_NUMBER_END the code looked for a match for the token
string using strstr() and then checked the extra condition - if the
extra condition didn't apply it then advanced by the length of the token
before searching again.
However that can miss matches if the strstr() matches can overlap
one another, so only advance one position, which is conservative
but can't miss matches.
For example this would not match before:
Replace("123123", "1231", r, DOH_REPLACE_NUMBER_END);
This issue seems to be entirely latent in the current SWIG codebase
due to the nature of the token strings passed when using these flags.
See #2235
This commit is contained in:
parent
9ab3ef8e96
commit
a0e3825de6
1 changed files with 11 additions and 5 deletions
|
|
@ -610,11 +610,13 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
|
|||
if (!s)
|
||||
return 0;
|
||||
if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
|
||||
s += tokenlen;
|
||||
/* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
|
||||
s += tokenlen;
|
||||
/* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
return s;
|
||||
|
|
@ -624,12 +626,14 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
|
|||
|
||||
|
||||
static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) {
|
||||
(void)tokenlen;
|
||||
while (s) {
|
||||
s = strstr(s, token);
|
||||
if (!s)
|
||||
return 0;
|
||||
if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
|
||||
s += tokenlen;
|
||||
/* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
return s;
|
||||
|
|
@ -644,7 +648,8 @@ static char *match_identifier_end(char *base, char *s, char *token, int tokenlen
|
|||
if (!s)
|
||||
return 0;
|
||||
if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
|
||||
s += tokenlen;
|
||||
/* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
return s;
|
||||
|
|
@ -659,7 +664,8 @@ static char *match_number_end(char *base, char *s, char *token, int tokenlen) {
|
|||
if (!s)
|
||||
return 0;
|
||||
if (isdigit((int) *(s + tokenlen))) {
|
||||
s += tokenlen;
|
||||
/* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
return s;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue