-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Description
The restriction that "r must have strlen(path) + 2 bytes" is incorrect as it fails to account for the null terminator. This is easiest way to see this is to walk through casepath on "a", which would have been alloca'd 3 bytes:
// r must have strlen(path) + 2 bytes
static int casepath(char const *path, char *r) // In the case that path is "a", the length of r is 3 bytes.
{
size_t l = strlen(path);
char *p = alloca(l + 1);
strcpy(p, path);
size_t rl = 0;
DIR *d;
if (p[0] == '/')
{
d = opendir("/");
p = p + 1;
}
else
{
d = opendir(".");
r[0] = '.'; // we take this path an initialise the first two bytes to 'a' and a null.
r[1] = 0;
rl = 1;
}
int last = 0;
char *c = strsep(&p, "/"); // strsep doesn't find a '/' and sets c to the entire string. In this case "a"
while (c)
{
if (!d) // We successfully opened "."
{
return 0;
}
if (last) // last is still 0
{
closedir(d);
return 0;
}
r[rl] = '/'; // rl is 1, r is now "./" (no null terminator)
rl += 1;
r[rl] = 0; // r is "./" (null terminated)
struct dirent *e = readdir(d); // reading the current directory "."
while (e)
{
if (strcasecmp(c, e->d_name) == 0)
{ // found file 'a'
// copy 'a' to where the null terminator was (the last byte in our buffer)
// AND a null terminator in the next byte of the buffer!?!
strcpy(r + rl, e->d_name);
...
This means that the requirement for casepath's buffer size is actually three bytes more than path's strlen(), since strcpy writes a null to the next byte.
Metadata
Metadata
Assignees
Labels
No labels