mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-20 19:02:23 +00:00
Normalize pathes passed to FS_FOpenFile()
.
There're some maps and maybe models or even mods in the wild which have hardcoded paths with self references (`/./`) and / or empty diretories (`//`). These assets works when read from the filesystem, but not when read from PAK or ZIP files. Work around that by removing self references and empty directories from the path right before opening the file. Closes #767.
This commit is contained in:
parent
42d61449b1
commit
09001d3bfb
1 changed files with 53 additions and 1 deletions
|
@ -369,7 +369,7 @@ FS_FCloseFile(fileHandle_t f)
|
|||
* for streaming data out of either a pak file or a seperate file.
|
||||
*/
|
||||
int
|
||||
FS_FOpenFile(const char *name, fileHandle_t *f, qboolean gamedir_only)
|
||||
FS_FOpenFile(const char *rawname, fileHandle_t *f, qboolean gamedir_only)
|
||||
{
|
||||
char path[MAX_OSPATH], lwrName[MAX_OSPATH];
|
||||
fsHandle_t *handle;
|
||||
|
@ -377,6 +377,58 @@ FS_FOpenFile(const char *name, fileHandle_t *f, qboolean gamedir_only)
|
|||
fsSearchPath_t *search;
|
||||
int i;
|
||||
|
||||
// Remove self references and empty dirs from the requested path.
|
||||
// ZIPs and PAKs don't support them, but they may be hardcoded in
|
||||
// some custom maps or models.
|
||||
char name[MAX_QPATH] = {};
|
||||
size_t namelen = strlen(rawname);
|
||||
for (int input = 0, output = 0; input < namelen; input++)
|
||||
{
|
||||
// Remove self reference.
|
||||
if (rawname[input] == '.')
|
||||
{
|
||||
if (output > 0)
|
||||
{
|
||||
// Inside the path.
|
||||
if (name[output - 1] == '/' && rawname[input + 1] == '/')
|
||||
{
|
||||
input++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// At the beginning. Note: This is save because the Quake II
|
||||
// VFS doesn't have a current working dir. Paths are always
|
||||
// absolute.
|
||||
if (rawname[input + 1] == '/')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Empty dir.
|
||||
if (rawname[input] == '/')
|
||||
{
|
||||
if (rawname[input + 1] == '/')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Pathes starting with a /. I'm not sure if this is
|
||||
// a problem. It shouldn't hurt to remove the leading
|
||||
// slash, though.
|
||||
if (rawname[input] == '/' && output == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
name[output] = rawname[input];
|
||||
output++;
|
||||
}
|
||||
|
||||
file_from_protected_pak = false;
|
||||
handle = FS_HandleForFile(name, f);
|
||||
Q_strlcpy(handle->name, name, sizeof(handle->name));
|
||||
|
|
Loading…
Reference in a new issue