Fix scene file loading memory errors

Fixes leaks.
Also safeguards against deallocated pointers by doing
g_TokenProcessor.SetBuffer(NULL) after parsing is done - an access at
NULL should be easier to debug than at some random address, potentially
just reading in garbage data.
This commit is contained in:
Alexander 'z33ky' Hirsch 2021-06-06 16:08:39 +02:00
parent e989cf63c5
commit b41d49c639

View File

@ -3735,7 +3735,7 @@ CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallbac
Q_FixSlashes( loadfile ); Q_FixSlashes( loadfile );
// binary compiled vcd // binary compiled vcd
void *pBuffer; void *pBuffer = NULL;
#ifdef MAPBASE #ifdef MAPBASE
// //
// Raw scene file support // Raw scene file support
@ -3760,12 +3760,13 @@ CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallbac
{ {
g_TokenProcessor.SetBuffer((char*)pBuffer); g_TokenProcessor.SetBuffer((char*)pBuffer);
pScene = ChoreoLoadScene( loadfile, NULL, &g_TokenProcessor, LocalScene_Printf ); pScene = ChoreoLoadScene( loadfile, NULL, &g_TokenProcessor, LocalScene_Printf );
g_TokenProcessor.SetBuffer(NULL);
} }
// Okay, it's definitely missing. // Okay, it's definitely missing.
else else
{ {
MissingSceneWarning( loadfile ); MissingSceneWarning( loadfile );
return NULL; pScene = NULL;
} }
if (pScene) if (pScene)
@ -4283,6 +4284,7 @@ CBaseEntity *CSceneEntity::FindNamedEntity( const char *name, CBaseEntity *pActo
#ifdef MAPBASE #ifdef MAPBASE
const char *GetFirstSoundInScene(const char *pszScene) const char *GetFirstSoundInScene(const char *pszScene)
{ {
const char *soundName;
SceneCachedData_t sceneData; SceneCachedData_t sceneData;
if ( scenefilecache->GetSceneCachedData( pszScene, &sceneData ) ) if ( scenefilecache->GetSceneCachedData( pszScene, &sceneData ) )
{ {
@ -4292,7 +4294,7 @@ const char *GetFirstSoundInScene(const char *pszScene)
short stringId = scenefilecache->GetSceneCachedSound( sceneData.sceneId, 0 ); short stringId = scenefilecache->GetSceneCachedSound( sceneData.sceneId, 0 );
// Trust that it's been precached // Trust that it's been precached
return scenefilecache->GetSceneString( stringId ); soundName = scenefilecache->GetSceneString( stringId );
} }
} }
else else
@ -4302,6 +4304,7 @@ const char *GetFirstSoundInScene(const char *pszScene)
{ {
g_TokenProcessor.SetBuffer((char*)pBuffer); g_TokenProcessor.SetBuffer((char*)pBuffer);
CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf ); CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf );
g_TokenProcessor.SetBuffer(NULL);
if (pScene) if (pScene)
{ {
for (int i = 0; i < pScene->GetNumEvents(); i++) for (int i = 0; i < pScene->GetNumEvents(); i++)
@ -4309,13 +4312,17 @@ const char *GetFirstSoundInScene(const char *pszScene)
CChoreoEvent *pEvent = pScene->GetEvent(i); CChoreoEvent *pEvent = pScene->GetEvent(i);
if (pEvent->GetType() == CChoreoEvent::SPEAK) if (pEvent->GetType() == CChoreoEvent::SPEAK)
return pEvent->GetParameters(); {
soundName = pEvent->GetParameters();
break;
}
} }
} }
} }
FreeSceneFileMemory( pBuffer );
} }
return NULL; return soundName;
} }
const char *GetFirstSoundInScene(CChoreoScene *scene) const char *GetFirstSoundInScene(CChoreoScene *scene)
@ -4483,6 +4490,8 @@ bool CSceneEntity::ScriptLoadSceneFromString(const char* pszFilename, const char
PrecacheScene(pScene); PrecacheScene(pScene);
} }
g_TokenProcessor.SetBuffer(NULL);
if (pScene != NULL) if (pScene != NULL)
{ {
// release prior scene if present // release prior scene if present
@ -5284,12 +5293,12 @@ int GetSceneSpeechCount( char const *pszScene )
else else
{ {
void *pBuffer = NULL; void *pBuffer = NULL;
int iNumSounds = 0;
if (filesystem->ReadFileEx( pszScene, "MOD", &pBuffer, true )) if (filesystem->ReadFileEx( pszScene, "MOD", &pBuffer, true ))
{ {
int iNumSounds = 0;
g_TokenProcessor.SetBuffer((char*)pBuffer); g_TokenProcessor.SetBuffer((char*)pBuffer);
CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf ); CChoreoScene *pScene = ChoreoLoadScene( pszScene, NULL, &g_TokenProcessor, LocalScene_Printf );
g_TokenProcessor.SetBuffer(NULL);
if (pScene) if (pScene)
{ {
for (int i = 0; i < pScene->GetNumEvents(); i++) for (int i = 0; i < pScene->GetNumEvents(); i++)
@ -5300,9 +5309,11 @@ int GetSceneSpeechCount( char const *pszScene )
iNumSounds++; iNumSounds++;
} }
} }
return iNumSounds;
} }
FreeSceneFileMemory( pBuffer );
return iNumSounds;
} }
#endif #endif
return 0; return 0;
@ -5367,7 +5378,9 @@ void PrecacheInstancedScene( char const *pszScene )
{ {
PrecacheChoreoScene(pScene); PrecacheChoreoScene(pScene);
} }
g_TokenProcessor.SetBuffer(NULL);
} }
FreeSceneFileMemory( pBuffer );
#else #else
// Scenes are sloppy and don't always exist. // Scenes are sloppy and don't always exist.
// A scene that is not in the pre-built cache image, but on disk, is a true error. // A scene that is not in the pre-built cache image, but on disk, is a true error.