From b204c3981588351aab39ec30c2e1aabc7b30c733 Mon Sep 17 00:00:00 2001 From: Vladimir Ponomarev Date: Tue, 14 Mar 2023 15:00:44 +0300 Subject: [PATCH] Merge pull request #23276 from vovka643:flann_corrections Fixed potential memory leak in flann Issue #22426 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- .../include/opencv2/flann/flann_base.hpp | 23 +++++++++++++++---- modules/flann/src/miniflann.cpp | 10 ++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/modules/flann/include/opencv2/flann/flann_base.hpp b/modules/flann/include/opencv2/flann/flann_base.hpp index 258ec38d20..af0b380bbf 100644 --- a/modules/flann/include/opencv2/flann/flann_base.hpp +++ b/modules/flann/include/opencv2/flann/flann_base.hpp @@ -45,6 +45,21 @@ namespace cvflann { +class FILEScopeGuard { + +public: + explicit FILEScopeGuard(FILE* file) { + file_ = file; + }; + + ~FILEScopeGuard() { + fclose(file_); + }; + +private: + FILE* file_; +}; + /** * Sets the log level used for all flann functions @@ -69,7 +84,6 @@ struct SavedIndexParams : public IndexParams } }; - template NNIndex* load_saved_index(const Matrix& dataset, const cv::String& filename, Distance distance) { @@ -79,13 +93,13 @@ NNIndex* load_saved_index(const Matrix if (fin == NULL) { return NULL; } + FILEScopeGuard fscgd(fin); + IndexHeader header = load_header(fin); if (header.data_type != Datatype::type()) { - fclose(fin); FLANN_THROW(cv::Error::StsError, "Datatype of saved index is different than of the one to be created."); } if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) { - fclose(fin); FLANN_THROW(cv::Error::StsError, "The index saved belongs to a different dataset"); } @@ -93,7 +107,6 @@ NNIndex* load_saved_index(const Matrix params["algorithm"] = header.index_type; NNIndex* nnIndex = create_index_by_type(dataset, params, distance); nnIndex->loadIndex(fin); - fclose(fin); return nnIndex; } @@ -107,7 +120,7 @@ public: typedef typename Distance::ResultType DistanceType; Index(const Matrix& features, const IndexParams& params, Distance distance = Distance() ) - : index_params_(params) + :index_params_(params) { flann_algorithm_t index_type = get_param(params,"algorithm"); loaded_ = false; diff --git a/modules/flann/src/miniflann.cpp b/modules/flann/src/miniflann.cpp index a1146ec2e7..ea0494ddec 100644 --- a/modules/flann/src/miniflann.cpp +++ b/modules/flann/src/miniflann.cpp @@ -767,11 +767,15 @@ bool Index::load(InputArray _data, const String& filename) Mat data = _data.getMat(); bool ok = true; release(); + FILE* fin = fopen(filename.c_str(), "rb"); - if (fin == NULL) + if (fin == NULL) { return false; + } + FILEScopeGuard fscgd(fin); ::cvflann::IndexHeader header = ::cvflann::load_header(fin); + algo = header.index_type; featureType = header.data_type == FLANN_UINT8 ? CV_8U : header.data_type == FLANN_INT8 ? CV_8S : @@ -786,7 +790,6 @@ bool Index::load(InputArray _data, const String& filename) { fprintf(stderr, "Reading FLANN index error: the saved data size (%d, %d) or type (%d) is different from the passed one (%d, %d), %d\n", (int)header.rows, (int)header.cols, featureType, data.rows, data.cols, data.type()); - fclose(fin); return false; } @@ -799,7 +802,6 @@ bool Index::load(InputArray _data, const String& filename) (distType != FLANN_DIST_HAMMING && featureType == CV_32F)) ) { fprintf(stderr, "Reading FLANN index error: unsupported feature type %d for the index type %d\n", featureType, algo); - fclose(fin); return false; } @@ -839,8 +841,6 @@ bool Index::load(InputArray _data, const String& filename) ok = false; } - if( fin ) - fclose(fin); return ok; }