Hi, I noticed a bug in an old variant version of hypermail so I inspected the sources of the latest beta release and it seems to be there, too. I'm a little surprised that it hasn't been caught by now.
Anyway, there's a function called replace() in strings.c that is used to do things like variable substitution and url encoding. (eg: replace occurrences of "$TO" with an email address.) Well, this function is written such that if the new text *contains* the pattern you are replacing, you get incorrect results. In fact, you get infinite recursion. For example, try to replace "%" with "%25" (for url-encoding), and you end up
with an endless sequence of "%%%%%%%%%%%%%%%%%%%%%%%...".
I noticed the new version is slightly better than my crummy old deviant version because it uses strcpymax() instead of strcpy() at one place, but I think the basic problem is still there.
Here is a possible replacement for replace().
Besides the main problem, replace() is tail-recursive which is unnecessary, and also tends to do some unnecessary recopying of a static buffer onto itself due to the recursion. So I cleaned that up a bit, too.
--Byron Darrah
/* Given a string, replaces all instances of "oldpiece" with "newpiece". * * Modified this routine to eliminate recursion and to avoid infinite * expansion of string when newpiece contains oldpiece. --Byron*/
char *replace(char *string, char *oldpiece, char *newpiece) {
int str_index, newstr_index, oldpiece_index, end,
new_len, old_len, cpy_len;
char *c;
char beforestring[MAXLINE], afterstring[MAXLINE];
static char newstring[MAXLINE];
if ((c = (char *) strstr(string, oldpiece)) == NULL)
return string;
new_len = strlen(newpiece); old_len = strlen(oldpiece); end = strlen(string) - old_len; oldpiece_index = c - string;
newstr_index = 0;
str_index = 0;
while(str_index <= end && c != NULL)
{
/* Copy characters from the left of matched pattern occurence */
cpy_len = oldpiece_index-str_index; strncpy(newstring+newstr_index, string+str_index, cpy_len); newstr_index += cpy_len; str_index += cpy_len;
/* Copy replacement characters instead of matched pattern */
strcpy(newstring+newstr_index, newpiece); newstr_index += new_len; str_index += old_len;
/* Check for another pattern match */
if((c = (char *) strstr(string+str_index, oldpiece)) != NULL) oldpiece_index = c - string;
return newstring;
}
Received on Fri 09 Oct 1998 08:01:33 PM GMT
This archive was generated by hypermail 2.3.0 : Sat 13 Mar 2010 03:46:11 AM GMT GMT