From fe411ba3b57c8969c78099948fa68a82eac87e98 Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Wed, 15 Nov 2023 13:22:04 -0500 Subject: [PATCH] Fix a bunch of memory leaks throughout codebase --- neo/cm/CollisionModel_load.cpp | 4 ++++ neo/framework/Common.cpp | 1 + neo/framework/FileSystem.cpp | 1 + neo/idlib/math/Polynomial.cpp | 7 +++++++ neo/idlib/math/Polynomial.h | 2 ++ neo/libs/libbinkdec/src/BinkDecoder.cpp | 2 ++ neo/renderer/NVRHI/RenderProgs_NVRHI.cpp | 3 +++ neo/sys/common/savegame.cpp | 1 + neo/sys/common/socket_net.cpp | 1 + neo/sys/posix/posix_main.cpp | 2 +- 10 files changed, 23 insertions(+), 1 deletion(-) diff --git a/neo/cm/CollisionModel_load.cpp b/neo/cm/CollisionModel_load.cpp index dcdbfe69..d59078d0 100644 --- a/neo/cm/CollisionModel_load.cpp +++ b/neo/cm/CollisionModel_load.cpp @@ -3558,11 +3558,15 @@ cm_model_t* idCollisionModelManagerLocal::LoadBinaryModelFromFile( idFile* file, } file->ReadBig( model->polygonMemory ); + // SRS - Boost polygonMemory to handle in-memory (ptr) vs. on-disk (int) size for cm_polygon_t.material, otherwise AllocPolygon() leaks + model->polygonMemory += ( sizeof( idMaterial* ) - sizeof( int ) ) * model->numPolygons; model->polygonBlock = ( cm_polygonBlock_t* ) Mem_ClearedAlloc( sizeof( cm_polygonBlock_t ) + model->polygonMemory, TAG_COLLISION ); model->polygonBlock->bytesRemaining = model->polygonMemory; model->polygonBlock->next = ( ( byte* ) model->polygonBlock ) + sizeof( cm_polygonBlock_t ); file->ReadBig( model->brushMemory ); + // SRS - Boost brushMemory to handle in-memory (ptr) vs. on-disk (int) size for cm_brush_t.material, otherwise AllocBrush() leaks + model->brushMemory += ( sizeof( idMaterial* ) - sizeof( int ) ) * model->numBrushes; model->brushBlock = ( cm_brushBlock_t* ) Mem_ClearedAlloc( sizeof( cm_brushBlock_t ) + model->brushMemory, TAG_COLLISION ); model->brushBlock->bytesRemaining = model->brushMemory; model->brushBlock->next = ( ( byte* ) model->brushBlock ) + sizeof( cm_brushBlock_t ); diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 0db2ad7f..0c3f950f 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -920,6 +920,7 @@ void idCommonLocal::RenderBink( const char* path ) materialText.Format( "{ translucent { videoMap %s } }", path ); idMaterial* material = const_cast( declManager->FindMaterial( "splashbink" ) ); + material->FreeData(); // SRS - always free data before parsing, otherwise leaks occur material->Parse( materialText.c_str(), materialText.Length(), false ); material->ResetCinematicTime( Sys_Milliseconds() ); diff --git a/neo/framework/FileSystem.cpp b/neo/framework/FileSystem.cpp index 349a2589..51d074b6 100644 --- a/neo/framework/FileSystem.cpp +++ b/neo/framework/FileSystem.cpp @@ -2881,6 +2881,7 @@ int idFileSystemLocal::AddResourceFile( const char* resourceFileName ) common->Printf( "Loaded resource file %s\n", resourceFile.c_str() ); return resourceFiles.Num() - 1; } + delete rc; return -1; } diff --git a/neo/idlib/math/Polynomial.cpp b/neo/idlib/math/Polynomial.cpp index fadba6fd..62c93672 100644 --- a/neo/idlib/math/Polynomial.cpp +++ b/neo/idlib/math/Polynomial.cpp @@ -231,6 +231,7 @@ void idPolynomial::Test() value = p.GetValue( roots[i] ); assert( idMath::Fabs( value ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( -5.0f, 4.0f, 3.0f ); num = p.GetRoots( roots ); @@ -239,6 +240,7 @@ void idPolynomial::Test() value = p.GetValue( roots[i] ); assert( idMath::Fabs( value ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); num = p.GetRoots( roots ); @@ -247,6 +249,7 @@ void idPolynomial::Test() value = p.GetValue( roots[i] ); assert( idMath::Fabs( value ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); num = p.GetRoots( roots ); @@ -255,6 +258,7 @@ void idPolynomial::Test() value = p.GetValue( roots[i] ); assert( idMath::Fabs( value ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( -5.0f, 4.0f, 3.0f, 2.0f, 1.0f ); num = p.GetRoots( roots ); @@ -263,6 +267,7 @@ void idPolynomial::Test() value = p.GetValue( roots[i] ); assert( idMath::Fabs( value ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( 1.0f, 4.0f, 3.0f, -2.0f ); num = p.GetRoots( complexRoots ); @@ -271,6 +276,7 @@ void idPolynomial::Test() complexValue = p.GetValue( complexRoots[i] ); assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); } + Mem_Free16( p.coefficient ); p = idPolynomial( 5.0f, 4.0f, 3.0f, -2.0f ); num = p.GetRoots( complexRoots ); @@ -279,4 +285,5 @@ void idPolynomial::Test() complexValue = p.GetValue( complexRoots[i] ); assert( idMath::Fabs( complexValue.r ) < 1e-4f && idMath::Fabs( complexValue.i ) < 1e-4f ); } + Mem_Free16( p.coefficient ); } diff --git a/neo/idlib/math/Polynomial.h b/neo/idlib/math/Polynomial.h index 33318589..3c2ab17d 100644 --- a/neo/idlib/math/Polynomial.h +++ b/neo/idlib/math/Polynomial.h @@ -190,6 +190,8 @@ ID_INLINE idPolynomial idPolynomial::operator-() const ID_INLINE idPolynomial& idPolynomial::operator=( const idPolynomial& p ) { + allocated = p.allocated; + coefficient = p.coefficient; Resize( p.degree, false ); for( int i = 0; i <= degree; i++ ) { diff --git a/neo/libs/libbinkdec/src/BinkDecoder.cpp b/neo/libs/libbinkdec/src/BinkDecoder.cpp index 3016d4e4..49855ad4 100644 --- a/neo/libs/libbinkdec/src/BinkDecoder.cpp +++ b/neo/libs/libbinkdec/src/BinkDecoder.cpp @@ -175,6 +175,8 @@ BinkDecoder::~BinkDecoder() delete[] planes[i].last; } + FreeBundles(); + for (uint32_t i = 0; i < audioTracks.size(); i++) { delete[] audioTracks[i]->buffer; diff --git a/neo/renderer/NVRHI/RenderProgs_NVRHI.cpp b/neo/renderer/NVRHI/RenderProgs_NVRHI.cpp index 831e5677..069dac1f 100644 --- a/neo/renderer/NVRHI/RenderProgs_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderProgs_NVRHI.cpp @@ -160,6 +160,9 @@ void idRenderProgManager::LoadShader( shader_t& shader ) ( constants.Num() > 0 ) ? &constants[0] : shaderConstant, uint32_t( constants.Num() ) ); shader.handle = shaderHandle; + + // SRS - Free the shader blob data, otherwise a leak will occur + Mem_Free( shaderBlob.data ); } /* diff --git a/neo/sys/common/savegame.cpp b/neo/sys/common/savegame.cpp index 65de9bb8..e5c63e49 100644 --- a/neo/sys/common/savegame.cpp +++ b/neo/sys/common/savegame.cpp @@ -525,6 +525,7 @@ int idSaveGameThread::Enumerate() // DG: just use the idFile object's timestamp - the windows code gets file attributes and // other complicated stuff like that.. I'm wonderin what that was good for.. this seems to work. details->date = file->Timestamp(); + delete file; #endif // DG end } else diff --git a/neo/sys/common/socket_net.cpp b/neo/sys/common/socket_net.cpp index c09f55b6..07a6d4aa 100644 --- a/neo/sys/common/socket_net.cpp +++ b/neo/sys/common/socket_net.cpp @@ -1021,6 +1021,7 @@ void Sys_InitNetworking() // DG end num_interfaces++; } + free( ifap ); #else // not _WIN32, OSX or FreeBSD int s; char buf[ MAX_INTERFACES * sizeof( ifreq ) ]; diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index e7926618..28b27b20 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -100,7 +100,7 @@ const char* Sys_DefaultSavePath() char* base_path = SDL_GetPrefPath( "", "RBDOOM-3-BFG" ); if( base_path ) { - savepath = SDL_strdup( base_path ); + savepath = base_path; savepath.StripTrailing( '/' ); SDL_free( base_path ); }