Package: publib-dev
Version: 0.38-2 (stable).
Consider the following program:
#include <publib.h>
#include <stdio.h>
int
main(int argc, char** argv)
{
char* words[100];
int wc;
int i;
wc = strsplit(argv[1], words, 100, "=");
printf("Got %d words\n", wc);
for(i =0; i < wc; i++) {
printf("Word %d = '%s'\n", i, words[i]);
}
}
compiled:
gcc -o demo demo.c -lpub
When invoked:
demo split=this and some more stuff
wc is very large and the words array will include the entire argv
and env and more rather than just:
wc[0] = "split"
wc[1] = "this"
This results from an incorrect loop termination condition in strsplit;
The body of that loop looks like:
while ((start = find_nonsep(end, sep)) != NULL) {
end = find_sep(start, sep);
if (count == maxw-1 && find_nonsep(end, sep) != NULL) {
words[count] = start;
}
if (count < maxw) {
*end++ = '\0';
words[count] = start;
}
++count;
}
If count < maxw, after finding a non separator, and then a separator,
end will point to the byte after the end of the string and the while
loop will cycle again, searching for non separators in the data
following the input string. This results in both additional words and
potentially segfaults depending on the data following the input string
and where it lies in memory.
One way to fix this is to terminate the while loop when end >= strlen(s)
+ s:
e.g.:
int strsplit(char *s, char **words, int maxw, const char *sep) {
char *start, *end;
int count;
size_t size;
assert(s != NULL);
assert(words != NULL || maxw == 0);
assert(sep != NULL);
assert(!memoverlap(s, strlen(s)+1, sep, strlen(sep)+1));
count = 0;
end = s;
size = strlen(s);
while (((end - s) <= size) &&
((start = find_nonsep(end, sep)) != NULL)) {
end = find_sep(start, sep);
if (count == maxw-1 && find_nonsep(end, sep) != NULL) {
words[count] = start;
}
if (count < maxw) {
*end++ = '\0';
words[count] = start;
}
++count;
}
return count;
}
or, if you prefer a diff:
20a21
> size_t size;
29c30,31
< while ((start = find_nonsep(end, sep)) != NULL) {
---
> size = strlen(s);
> while (((end - s) <= size) && ((start = find_nonsep(end, sep))
!= NULL)) {
Ron Fox
NSCL
Michigan State University
East Lansing, MI 48824-1321
Most people get a fair amount of fun out of their lives, but on balance
life is suffering, and only the very young or very foolish imagine
otherwise. - George Orwell
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]