Skip to content

Commit

Permalink
Fixed *nix style relative/absolute path mixup in FileDirectory
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Jan 3, 2011
1 parent 9abe546 commit c670bf9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 30 deletions.
6 changes: 3 additions & 3 deletions doomsday/engine/portable/include/filedirectory.h
Expand Up @@ -3,8 +3,8 @@
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2003-2010 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2009-2010 Daniel Swanson <danij@dengine.net>
*\author Copyright © 2003-2011 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2009-2011 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -32,7 +32,7 @@ typedef struct filedirectory_node_s {
struct filedirectory_node_s* next;
struct filedirectory_node_s* parent;
filetype_t type;
char* path;
ddstring_t path;
boolean processed;
} filedirectory_node_t;

Expand Down
53 changes: 26 additions & 27 deletions doomsday/engine/portable/src/filedirectory.c
Expand Up @@ -48,42 +48,39 @@ static size_t countNodes(filedirectory_t* fd, filetype_t type)
* @return [ a new | the ] directory node that matches the name
* and has the specified parent node.
*/
static filedirectory_node_t* direcNode(filedirectory_t* fd, const char* name,
static filedirectory_node_t* direcNode(filedirectory_t* fd, const ddstring_t* name,
filedirectory_node_t* parent)
{
assert(fd && name && name[0]);
assert(fd && name && !Str_IsEmpty(name));
{
filedirectory_node_t* node;

// Have we already encountered this directory? Just iterate through all nodes.
for(node = fd->_direcFirst; node; node = node->next)
{
if(node->parent == parent &&
!strnicmp(node->path, name, strlen(node->path) - (node->type == FT_DIRECTORY? 1:0)))
if(node->parent != parent)
continue;
if(Str_Length(&node->path) < Str_Length(name))
continue;
if(!strnicmp(Str_Text(&node->path), Str_Text(name), Str_Length(&node->path) - (node->type == FT_DIRECTORY? 1:0)))
return node;
}

// Add a new node.
if((node = malloc(sizeof(*node))) == 0)
Con_Error("direcNode: failed on allocation of %lu bytes for new node.", (unsigned long) sizeof(*node));

node->next = 0;
node->parent = parent;

if(fd->_direcLast)
fd->_direcLast->next = node;
fd->_direcLast = node;
if(!fd->_direcFirst)
fd->_direcFirst = node;

// Make a copy of the path. Freed in FileDirectory_Clear().
if((node->path = malloc(strlen(name) + 1)) == 0)
Con_Error("direcNode: failed on allocation of %lu bytes for path.", (unsigned long) (strlen(name) + 1));

strcpy(node->path, name);

// No files yet.
node->type = FT_DIRECTORY;
node->processed = false;
Str_Init(&node->path); Str_Copy(&node->path, name);
node->parent = parent;
node->next = 0;
node->processed = false; // No files yet.

return node;
}
Expand Down Expand Up @@ -111,11 +108,11 @@ static filedirectory_node_t* buildDirecNodes(filedirectory_t* fd, const ddstring
p = Str_Text(&relPath);
while((p = Str_CopyDelim2(&part, p, DIR_SEP_CHAR, 0))) // Get the next part.
{
node = direcNode(fd, Str_Text(&part), parent);
node = direcNode(fd, &part, parent);
parent = node;
}
if(Str_Length(&part) != 0)
node = direcNode(fd, Str_Text(&part), parent);
node = direcNode(fd, &part, parent);

Str_Free(&part);
Str_Free(&relPath);
Expand All @@ -130,7 +127,7 @@ static void clearDirectory(filedirectory_t* fd)
while(fd->_direcFirst)
{
filedirectory_node_t* next = fd->_direcFirst->next;
free(fd->_direcFirst->path);
Str_Free(&fd->_direcFirst->path);
free(fd->_direcFirst);
fd->_direcFirst = next;
}
Expand Down Expand Up @@ -461,9 +458,9 @@ void FileDirectory_PrintFileList(filedirectory_t* fd)
}
#endif

boolean FileDirectoryNode_MatchDirectory(const filedirectory_node_t* direc, const char* name)
boolean FileDirectoryNode_MatchDirectory(const filedirectory_node_t* node, const char* name)
{
assert(direc && name && name[0]);
assert(node && name && name[0]);
{
filename_t dir;

Expand All @@ -473,21 +470,23 @@ boolean FileDirectoryNode_MatchDirectory(const filedirectory_node_t* direc, cons
while((pos = strrchr(dir, DIR_SEP_CHAR)) != 0)
{
// Does this match?
if(strnicmp(direc->path, pos + 1, strlen(direc->path) - (direc->type == FT_DIRECTORY? 1:0)))
return false;
if(Str_Length(&node->path) < strlen(name) ||
strnicmp(Str_Text(&node->path), name, Str_Length(&node->path) - (node->type == FT_DIRECTORY? 1:0)))
return false;

// Are there no more parent directories?
if(!direc->parent)
if(!node->parent)
return false;

// So far so good. Move one directory level upwards.
direc = direc->parent;
node = node->parent;
// The string now ends here.
*pos = 0;
}}

// Anything remaining is the root directory or file name - does it match?
if(strnicmp(direc->path, dir, strlen(direc->path) - (direc->type == FT_DIRECTORY? 1:0)))
if(Str_Length(&node->path) < strlen(name) ||
strnicmp(Str_Text(&node->path), name, Str_Length(&node->path) - (node->type == FT_DIRECTORY? 1:0)))
return false;

// We must have now arrived at the search target.
Expand All @@ -498,11 +497,11 @@ boolean FileDirectoryNode_MatchDirectory(const filedirectory_node_t* direc, cons
void FileDirectoryNode_ComposePath(const filedirectory_node_t* direc, ddstring_t* foundPath)
{
assert(direc && foundPath);
Str_Prepend(foundPath, direc->path);
Str_Prepend(foundPath, Str_Text(&direc->path));
direc = direc->parent;
while(direc)
{
Str_Prepend(foundPath, direc->path);
Str_Prepend(foundPath, Str_Text(&direc->path));
direc = direc->parent;
}
}

0 comments on commit c670bf9

Please sign in to comment.