From 16ce114e0cad6c85efead4a0ebb07724d691407a Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Tue, 9 Dec 2014 19:13:19 +0300 Subject: [PATCH 1/2] Fix memory leaks appearing when cvOpenFileStorage throws --- modules/core/src/persistence.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 3e4bdd3d88..c88e6d2975 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -2724,7 +2724,10 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co (dot_pos[3] == '\0' || (cv_isdigit(dot_pos[3]) && dot_pos[4] == '\0')) ) { if( append ) + { + cvReleaseFileStorage( &fs ); CV_Error(CV_StsNotImplemented, "Appending data to compressed file is not implemented" ); + } isGZ = true; compression = dot_pos[3]; if( compression ) @@ -2745,6 +2748,7 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co if( !fs->gzfile ) goto _exit_; #else + cvReleaseFileStorage( &fs ); CV_Error(CV_StsNotImplemented, "There is no compressed file storage support in this configuration"); #endif } @@ -2797,7 +2801,10 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co if( strcmp( encoding, "UTF-16" ) == 0 || strcmp( encoding, "utf-16" ) == 0 || strcmp( encoding, "Utf-16" ) == 0 ) + { + cvReleaseFileStorage( &fs ); CV_Error( CV_StsBadArg, "UTF-16 XML encoding is not supported! Use 8-bit encoding\n"); + } CV_Assert( strlen(encoding) < 1000 ); char buf[1100]; @@ -2834,7 +2841,10 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co } } if( last_occurence < 0 ) + { + cvReleaseFileStorage( &fs ); CV_Error( CV_StsError, "Could not find in the end of file.\n" ); + } icvCloseFile( fs ); fs->file = fopen( fs->filename, "r+t" ); fseek( fs->file, last_occurence, SEEK_SET ); @@ -2908,10 +2918,18 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co //mode = cvGetErrMode(); //cvSetErrMode( CV_ErrModeSilent ); - if( fs->fmt == CV_STORAGE_FORMAT_XML ) - icvXMLParse( fs ); - else - icvYMLParse( fs ); + try + { + if( fs->fmt == CV_STORAGE_FORMAT_XML ) + icvXMLParse( fs ); + else + icvYMLParse( fs ); + } + catch (...) + { + cvReleaseFileStorage( &fs ); + throw; + } //cvSetErrMode( mode ); // release resources that we do not need anymore From 08da247a871ed40b868119a999af538da6526c6d Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Mon, 22 Dec 2014 18:54:39 +0300 Subject: [PATCH 2/2] cvOpenFileStorage: reduce the scope of xml_buf and make sure it's freed... ... before any exceptions occur. --- modules/core/src/persistence.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index c88e6d2975..fe39dc0534 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -2683,7 +2683,6 @@ CV_IMPL CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, const char* encoding ) { CvFileStorage* fs = 0; - char* xml_buf = 0; int default_block_size = 1 << 18; bool append = (flags & 3) == CV_STORAGE_APPEND; bool mem = (flags & CV_STORAGE_MEMORY) != 0; @@ -2822,7 +2821,7 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co int last_occurence = -1; xml_buf_size = MIN(xml_buf_size, int(file_size)); fseek( fs->file, -xml_buf_size, SEEK_END ); - xml_buf = (char*)cvAlloc( xml_buf_size+2 ); + char* xml_buf = (char*)cvAlloc( xml_buf_size+2 ); // find the last occurence of for(;;) { @@ -2840,6 +2839,7 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co ptr += strlen(substr); } } + cvFree( &xml_buf ); if( last_occurence < 0 ) { cvReleaseFileStorage( &fs ); @@ -2954,7 +2954,6 @@ _exit_: } } - cvFree( &xml_buf ); return fs; }