From d4926506f9474faf86c9c1e8a89d7d948fc0d083 Mon Sep 17 00:00:00 2001 From: Kyzentun Keeslala Date: Tue, 21 Jun 2016 19:23:37 -0600 Subject: [PATCH] Removed alloca calls from sound reader classes because putting it inside a loop tends to cause a stack overflow. Removed alloca call from png loading because it does not work with setjmp and longjmp. png loading now uses exceptions instead when an error occurs. --- src/RageSoundReader_Resample_Good.cpp | 3 +-- src/RageSoundReader_SpeedChange.cpp | 2 +- src/RageSoundReader_WAV.cpp | 4 ++-- src/RageSurface_Load_PNG.cpp | 27 +++++++++++++++++++-------- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/RageSoundReader_Resample_Good.cpp b/src/RageSoundReader_Resample_Good.cpp index 4b97d328b5..f32530f9ae 100644 --- a/src/RageSoundReader_Resample_Good.cpp +++ b/src/RageSoundReader_Resample_Good.cpp @@ -667,8 +667,7 @@ int RageSoundReader_Resample_Good::Read( float *pBuf, int iFrames ) { int iFramesNeeded = m_apResamplers[0]->NumInputsForOutputSamples(iFrames); - float *pTmpBuf = (float *) alloca( iFramesNeeded * sizeof(float) * iChannels ); - ASSERT( pTmpBuf != NULL ); + float pTmpBuf[iFramesNeeded * iChannels]; int iFramesIn = m_pSource->Read( pTmpBuf, iFramesNeeded ); if( iFramesIn < 0 ) return iFramesIn; diff --git a/src/RageSoundReader_SpeedChange.cpp b/src/RageSoundReader_SpeedChange.cpp index a4825b3b9b..54801c3505 100644 --- a/src/RageSoundReader_SpeedChange.cpp +++ b/src/RageSoundReader_SpeedChange.cpp @@ -89,7 +89,7 @@ int RageSoundReader_SpeedChange::FillData( int iMaxFrames ) if( iBytesToRead <= 0 ) return m_iDataBufferAvailFrames; - float *pTempBuffer = (float *) alloca( iBytesToRead ); + float pTempBuffer[iBytesToRead/sizeof(float)]; int iGotFrames = m_pSource->Read( pTempBuffer, iFramesToRead ); if( iGotFrames < 0 ) { diff --git a/src/RageSoundReader_WAV.cpp b/src/RageSoundReader_WAV.cpp index e0dad1bde8..aafed8f658 100644 --- a/src/RageSoundReader_WAV.cpp +++ b/src/RageSoundReader_WAV.cpp @@ -288,8 +288,8 @@ public: /* We've read the block header; read the rest. Don't read past the end of the data chunk. */ int iMaxSize = min( (int) m_WavData.m_iBlockAlign - 7 * m_WavData.m_iChannels, (m_WavData.m_iDataChunkSize+m_WavData.m_iDataChunkPos) - m_File.Tell() ); - char *pBuf = (char *) alloca( iMaxSize ); - ASSERT( pBuf != NULL ); + char cBuf[iMaxSize]; + char* pBuf= cBuf; int iBlockSize = m_File.Read( pBuf, iMaxSize ); if( iBlockSize == 0 ) diff --git a/src/RageSurface_Load_PNG.cpp b/src/RageSurface_Load_PNG.cpp index 0696a0b40c..71f893b67a 100644 --- a/src/RageSurface_Load_PNG.cpp +++ b/src/RageSurface_Load_PNG.cpp @@ -50,7 +50,10 @@ void PNG_Error( png_struct *png, const char *error ) strncpy( info->err, error, 1024 ); info->err[1023] = 0; LOG->Trace( "loading \"%s\": err: %s", info->fn, info->err ); - longjmp( png_jmpbuf(png), 1 ); + // This exception is just thrown to go to the catch block for cleanup. The + // message has already been printed, so the exception value can be ignored. + // -Kyz + throw int(1); } void PNG_Warning( png_struct *png, const char *warning ) @@ -87,12 +90,10 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro RageSurface *volatile img = NULL; CHECKPOINT_M("Potential issue with png jump about to be analyzed."); - if( setjmp(png_jmpbuf(png) )) + + png_byte** row_pointers= NULL; + try { - png_destroy_read_struct( &png, &info_ptr, NULL ); - delete img; - return NULL; - } png_set_read_fn( png, f, RageFile_png_read ); @@ -227,8 +228,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro } ASSERT( img != NULL ); - /* alloca to prevent memleaks if libpng longjmps us */ - png_byte **row_pointers = (png_byte **) alloca( sizeof(png_byte*) * height ); + row_pointers = new png_byte*[height]; CHECKPOINT_M( ssprintf("%p",row_pointers) ); for( unsigned y = 0; y < height; ++y ) @@ -241,6 +241,17 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_read_end( png, info_ptr ); png_destroy_read_struct( &png, &info_ptr, NULL ); + } + catch(int e) + { + png_destroy_read_struct(&png, &info_ptr, NULL); + delete img; + if(row_pointers != NULL) + { + delete[] row_pointers; + } + return NULL; + } return img; }