mirror of
https://github.com/opencv/opencv.git
synced 2025-06-10 19:24:07 +08:00
core(persistence): fix resource leaks - force closing files
backporting commit 673eb2b006
This commit is contained in:
parent
a28a520c7f
commit
c920b45fb8
@ -251,10 +251,10 @@ void icvClose( CvFileStorage* fs, cv::String* out )
|
|||||||
else if ( fs->fmt == CV_STORAGE_FORMAT_JSON )
|
else if ( fs->fmt == CV_STORAGE_FORMAT_JSON )
|
||||||
icvPuts( fs, "}\n" );
|
icvPuts( fs, "}\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
icvCloseFile(fs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icvCloseFile(fs);
|
||||||
|
|
||||||
if( fs->outbuf && out )
|
if( fs->outbuf && out )
|
||||||
{
|
{
|
||||||
*out = cv::String(fs->outbuf->begin(), fs->outbuf->end());
|
*out = cv::String(fs->outbuf->begin(), fs->outbuf->end());
|
||||||
|
@ -68,10 +68,9 @@ static bool is_param_exist( const std::vector<std::string> & params, const std::
|
|||||||
|
|
||||||
//===========================================================================================
|
//===========================================================================================
|
||||||
|
|
||||||
CV_IMPL CvFileStorage*
|
static
|
||||||
cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const char* encoding )
|
void cvOpenFileStorage_(CvFileStorage*& fs, const char* query, CvMemStorage* dststorage, int flags, const char* encoding)
|
||||||
{
|
{
|
||||||
CvFileStorage* fs = 0;
|
|
||||||
int default_block_size = 1 << 18;
|
int default_block_size = 1 << 18;
|
||||||
bool append = (flags & 3) == CV_STORAGE_APPEND;
|
bool append = (flags & 3) == CV_STORAGE_APPEND;
|
||||||
bool mem = (flags & CV_STORAGE_MEMORY) != 0;
|
bool mem = (flags & CV_STORAGE_MEMORY) != 0;
|
||||||
@ -104,10 +103,6 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const
|
|||||||
if( mem && append )
|
if( mem && append )
|
||||||
CV_Error( CV_StsBadFlag, "CV_STORAGE_APPEND and CV_STORAGE_MEMORY are not currently compatible" );
|
CV_Error( CV_StsBadFlag, "CV_STORAGE_APPEND and CV_STORAGE_MEMORY are not currently compatible" );
|
||||||
|
|
||||||
fs = (CvFileStorage*)cvAlloc( sizeof(*fs) );
|
|
||||||
CV_Assert(fs);
|
|
||||||
memset( fs, 0, sizeof(*fs));
|
|
||||||
|
|
||||||
fs->memstorage = cvCreateMemStorage( default_block_size );
|
fs->memstorage = cvCreateMemStorage( default_block_size );
|
||||||
fs->dststorage = dststorage ? dststorage : fs->memstorage;
|
fs->dststorage = dststorage ? dststorage : fs->memstorage;
|
||||||
|
|
||||||
@ -373,9 +368,12 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const
|
|||||||
const char* yaml_signature = "%YAML";
|
const char* yaml_signature = "%YAML";
|
||||||
const char* json_signature = "{";
|
const char* json_signature = "{";
|
||||||
const char* xml_signature = "<?xml";
|
const char* xml_signature = "<?xml";
|
||||||
char buf[16];
|
char buf[16] = { 0 };
|
||||||
icvGets( fs, buf, sizeof(buf)-2 );
|
char* bufPtr = icvGets( fs, buf, sizeof(buf)-2);
|
||||||
char* bufPtr = cv_skip_BOM(buf);
|
if (!bufPtr)
|
||||||
|
CV_Error(CV_BADARG_ERR, "Can't read from input stream or input stream is empty");
|
||||||
|
bufPtr = cv_skip_BOM(bufPtr);
|
||||||
|
CV_Assert(bufPtr);
|
||||||
size_t bufOffset = bufPtr - buf;
|
size_t bufOffset = bufPtr - buf;
|
||||||
|
|
||||||
if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
|
if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
|
||||||
@ -417,21 +415,12 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const
|
|||||||
|
|
||||||
//mode = cvGetErrMode();
|
//mode = cvGetErrMode();
|
||||||
//cvSetErrMode( CV_ErrModeSilent );
|
//cvSetErrMode( CV_ErrModeSilent );
|
||||||
try
|
switch (fs->fmt)
|
||||||
{
|
{
|
||||||
switch (fs->fmt)
|
case CV_STORAGE_FORMAT_XML : { icvXMLParse ( fs ); break; }
|
||||||
{
|
case CV_STORAGE_FORMAT_YAML: { icvYMLParse ( fs ); break; }
|
||||||
case CV_STORAGE_FORMAT_XML : { icvXMLParse ( fs ); break; }
|
case CV_STORAGE_FORMAT_JSON: { icvJSONParse( fs ); break; }
|
||||||
case CV_STORAGE_FORMAT_YAML: { icvYMLParse ( fs ); break; }
|
default: break;
|
||||||
case CV_STORAGE_FORMAT_JSON: { icvJSONParse( fs ); break; }
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
fs->is_opened = true;
|
|
||||||
cvReleaseFileStorage( &fs );
|
|
||||||
CV_RETHROW();
|
|
||||||
}
|
}
|
||||||
//cvSetErrMode( mode );
|
//cvSetErrMode( mode );
|
||||||
|
|
||||||
@ -457,9 +446,28 @@ _exit_:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL CvFileStorage*
|
||||||
|
cvOpenFileStorage(const char* query, CvMemStorage* dststorage, int flags, const char* encoding)
|
||||||
|
{
|
||||||
|
CvFileStorage* fs = (CvFileStorage*)cvAlloc( sizeof(*fs) );
|
||||||
|
CV_Assert(fs);
|
||||||
|
memset( fs, 0, sizeof(*fs));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cvOpenFileStorage_(fs, query, dststorage, flags, encoding);
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (fs)
|
||||||
|
cvReleaseFileStorage(&fs);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* closes file storage and deallocates buffers */
|
/* closes file storage and deallocates buffers */
|
||||||
CV_IMPL void
|
CV_IMPL void
|
||||||
|
@ -1703,4 +1703,65 @@ TEST(Core_InputOutput, FileStorage_YAML_parse_multiple_documents)
|
|||||||
ASSERT_EQ(0, std::remove(filename.c_str()));
|
ASSERT_EQ(0, std::remove(filename.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Core_InputOutput, FileStorage_empty_16823)
|
||||||
|
{
|
||||||
|
std::string fname = tempfile("test_fs_empty.yml");
|
||||||
|
{
|
||||||
|
// create empty file
|
||||||
|
std::ofstream f(fname.c_str(), std::ios::out);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileStorage fs(fname, FileStorage::READ);
|
||||||
|
ADD_FAILURE() << "Exception must be thrown for empty file.";
|
||||||
|
}
|
||||||
|
catch (const cv::Exception&)
|
||||||
|
{
|
||||||
|
// expected way
|
||||||
|
// closed files can be checked manually through 'strace'
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << "Unexpected exception: " << e.what();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << "Unexpected unknown C++ exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, remove(fname.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Core_InputOutput, FileStorage_open_empty_16823)
|
||||||
|
{
|
||||||
|
std::string fname = tempfile("test_fs_open_empty.yml");
|
||||||
|
{
|
||||||
|
// create empty file
|
||||||
|
std::ofstream f(fname.c_str(), std::ios::out);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileStorage fs;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fs.open(fname, FileStorage::READ);
|
||||||
|
ADD_FAILURE() << "Exception must be thrown for empty file.";
|
||||||
|
}
|
||||||
|
catch (const cv::Exception&)
|
||||||
|
{
|
||||||
|
// expected way
|
||||||
|
// closed files can be checked manually through 'strace'
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << "Unexpected exception: " << e.what();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << "Unexpected unknown C++ exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, remove(fname.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user