Very strange error

N

Noah Roberts

There is some windows specific code in this, but I believe the issue to
be something standard so...

The problem is that after attaching the name of the subdirectory I have
something like "d:\db\db-4.1.25\", which has 16 characters; but when it
arrives in the next call it looks more like "d:\db\db-4.1.25\(clubs)",
which has 17 characters. What is even more interesting is that the test
"if (dir[strlen(dir) - 1] != '\\')" fails when there is a clubs at the
end of the string!

Where am I screwing up?

NR - code follows

void search_directory(char *dir, char *match, void (*deal)(const
char*,const char *))
{
WIN32_FIND_DATA find_data;
HANDLE h_search;
int finished = 0;
char *search_string;

if (dir[strlen(dir) - 1] != '\\') dir[strlen(dir) - 1] = '\0';
else fprintf(stderr, "It is %c", dir[strlen(dir) - 1]);
search_string = malloc(strlen(dir) + 1);
sprintf(search_string, "%s*", dir);
fprintf(stderr, "%d", strlen(dir)); putchar('\n');

fprintf(stderr, search_string);

h_search = FindFirstFile(search_string, &find_data);
if (h_search == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Can't do stuff\n");
exit(1);
}

while (!finished)
{
if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
int begin = strlen(find_data.cFileName) - strlen(match);
if (!strcmp(find_data.cFileName + begin, match))
{
deal(dir, find_data.cFileName);
}

}
else if (strcmp(find_data.cFileName, ".") &&
strcmp(find_data.cFileName, ".."))
{
fprintf(stderr, "Going down...");
char *newdir = malloc(strlen(dir) + strlen(find_data.cFileName));
memset(newdir, 0, strlen(dir) + strlen(find_data.cFileName));
sprintf(newdir, "%s%s\\", dir, find_data.cFileName);
fprintf(stderr, "%d", strlen(newdir)); putchar('\n');
search_directory(newdir, match, deal);
}

if (!FindNextFile(h_search, &find_data))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
finished = 1;
}
else
{
fprintf(stderr, "BROKEN\n");
exit(1);
}
}
}
}

Output:
D:\progs>a.exe d:\ file.txt
It is \3
d:\*Going down...11
It is \11
d:\.xemacs\*Going down...8
It is \8
d:\argo\*Going down...15
It is \15
d:\convert-biz\*Going down...6
It is \6
d:\db\*Going down...16
It is \17
d:\db\db-4.1.25\?*Can't do stuff
 
N

Noah Roberts

Noah said:
There is some windows specific code in this, but I believe the issue to
be something standard so...

The problem is that after attaching the name of the subdirectory I have
something like "d:\db\db-4.1.25\", which has 16 characters; but when it
arrives in the next call it looks more like "d:\db\db-4.1.25\(clubs)",
which has 17 characters. What is even more interesting is that the test
"if (dir[strlen(dir) - 1] != '\\')" fails when there is a clubs at the
end of the string!

More on the problem....

It appears that something is happening in malloc:

fprintf(stderr, "%s is %d characters",dir, strlen(dir)); putchar('\n');
search_string = malloc(strlen(dir) + 1);
fprintf(stderr, "after malloc %s is %d characters",dir, strlen(dir));
putchar('\n');

Result:
d:\db\db-4.1.25\ is 16 characters
after malloc d:\db\db-4.1.25\? is 17 characters

As far as I know there should be no overruns here, right?
 
E

Eric Sosman

Noah said:
There is some windows specific code in this, but I believe the issue to
be something standard so...

I haven't read through the whole thing, but here's
one trouble spot:
search_string = malloc(strlen(dir) + 1);
sprintf(search_string, "%s*", dir);

You allocate enough space for a copy of `dir' (and
forget to check for malloc() failure, by the way), and
then you try to store `dir' plus an extra '*' -- one
more character than you've alloted space for. What
happens next is anyone's guess.
 
N

Noah Roberts

Eric Sosman wrote:

You allocate enough space for a copy of `dir' (and
forget to check for malloc() failure, by the way), and
then you try to store `dir' plus an extra '*' -- one
more character than you've alloted space for. What
happens next is anyone's guess.
That was apparently the problem that resulted in quite a few very
strange behaviors.

Thanks
NR
 
S

Severian

Noah said:
There is some windows specific code in this, but I believe the issue to
be something standard so...

The problem is that after attaching the name of the subdirectory I have
something like "d:\db\db-4.1.25\", which has 16 characters; but when it
arrives in the next call it looks more like "d:\db\db-4.1.25\(clubs)",
which has 17 characters. What is even more interesting is that the test
"if (dir[strlen(dir) - 1] != '\\')" fails when there is a clubs at the
end of the string!

More on the problem....

It appears that something is happening in malloc:

fprintf(stderr, "%s is %d characters",dir, strlen(dir)); putchar('\n');
search_string = malloc(strlen(dir) + 1);
fprintf(stderr, "after malloc %s is %d characters",dir, strlen(dir));
putchar('\n');

Errors are also likely in on the heap because you don't allocate
enough space for your string here, as well as where Eric pointed at.
char *newdir = malloc(strlen(dir) + strlen(find_data.cFileName));
memset(newdir, 0, strlen(dir) + strlen(find_data.cFileName));
sprintf(newdir, "%s%s\\", dir, find_data.cFileName);

The \ and terminating null require space, so you need +2 in the malloc
of newdir.

If your implementation has a maximum allowable path length, you could
avoid all of the mallocs and frees by using local character arrays for
your buffers. Just add a sanity check that you're not exceeding the
maximum length when building a sub-folder's name.

- Sev
 
J

Jim

On Thu, 13 Nov 2003 13:31:11 -0800, Noah Roberts

not so strange!
search_string = malloc(strlen(dir) + 1);
sprintf(search_string, "%s*", dir);

allocation is 1 byte too small
char *newdir = malloc(strlen(dir) + strlen(find_data.cFileName));
memset(newdir, 0, strlen(dir) + strlen(find_data.cFileName));
sprintf(newdir, "%s%s\\", dir, find_data.cFileName);

allocation is 2 bytes too small

strlen("abc") == 3, but it takes 4 bytes to store, since there's a
hidden trailing '\0' character.

Jim
 
N

Noah Roberts

Jim said:
strlen("abc") == 3, but it takes 4 bytes to store, since there's a
hidden trailing '\0' character.

Yes, I was doing things too fast apparently. strlen is 1 past the end
of the string, I just remembered that fact but forgot that it is the
true size and still need 1 more.
 
N

Noah Roberts

Noah Roberts wrote:

[snip stuff]

What is really funny is that I got it to work, and work beutifully. But
now the specs on the program have changed to the point that I highly
doubt any of it to be useful :p First it was, "Search the drive for a
file and rename it to something else." Now it is, "Get a list of
outlook identities, display some summary information (email, servers,
etc), let the user pick one and move the correct file in just that
identity. So now I am searching various places in the CURRENT_USER key
of the registry and will be doing barely any directory work at all :p

NR
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,104
Messages
2,570,643
Members
47,247
Latest member
youngcoin

Latest Threads

Top