From 2457ecf2266b84fc0e26ecec6263cc79c9668f60 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 29 Jan 2025 09:49:19 +0300 Subject: [PATCH] filesystem: fix recursive basedir possible cyclic dependency when default game directory uses a basedir that's base directory is undefined That could happen when default game directory depends on base directory that don't have gameinfo.txt. Because all game directories with liblist.gam automatically have dependency on default game directory, it causes cyclic dependency. --- filesystem/filesystem.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index 5a09e932..a0e9c306 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -1199,11 +1199,11 @@ void FS_AddGameHierarchy( const char *dir, uint flags ) qboolean isGameDir = flags & FS_GAMEDIR_PATH; char buf[MAX_VA_STRING]; - GI->added = true; - if( !COM_CheckString( dir )) return; + Con_Printf( "%s( %s )\n", __func__, dir ); + // add the common game directory // recursive gamedirs @@ -1214,12 +1214,21 @@ void FS_AddGameHierarchy( const char *dir, uint flags ) { dir = FI.games[i]->gamefolder; // fixup directory case + if( FI.games[i]->added ) // already added, refusing + break; + + // don't add our game directory as base dir to prevent cyclic dependency + if( Q_stricmp( FI.games[i]->basedir, GI->gamefolder )) + break; + + // don't add directory which basedir is equal to this gamefolder to prevent + // endless loop + if( Q_stricmp( FI.games[i]->basedir, FI.games[i]->gamefolder )) + break; + Con_Reportf( "%s: adding recursive basedir %s\n", __func__, FI.games[i]->basedir ); - if( !FI.games[i]->added && Q_stricmp( FI.games[i]->gamefolder, FI.games[i]->basedir )) - { - FI.games[i]->added = true; - FS_AddGameHierarchy( FI.games[i]->basedir, flags & (~FS_GAMEDIR_PATH) ); - } + FI.games[i]->added = true; + FS_AddGameHierarchy( FI.games[i]->basedir, flags & (~FS_GAMEDIR_PATH)); break; } } @@ -1276,6 +1285,8 @@ void FS_Rescan( void ) FS_AddGameHierarchy( GI->basedir, 0 ); if( Q_stricmp( GI->basedir, GI->falldir ) && Q_stricmp( GI->gamefolder, GI->falldir )) FS_AddGameHierarchy( GI->falldir, 0 ); + + GI->added = true; FS_AddGameHierarchy( GI->gamefolder, FS_GAMEDIR_PATH ); }