From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 25 Jul 2019 17:15:59 +0300 Subject: [PATCH] objdetect: validate feature rectangle on reading --- modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++---- modules/objdetect/src/cascadedetect.hpp | 6 ++-- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp index 4b2078306f..bd62cd21a1 100644 --- a/modules/objdetect/src/cascadedetect.cpp +++ b/modules/objdetect/src/cascadedetect.cpp @@ -47,6 +47,10 @@ #include "opencv2/objdetect/objdetect_c.h" #include "opencl_kernels_objdetect.hpp" +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member +#endif + namespace cv { @@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector& _s //---------------------------------------------- HaarEvaluator --------------------------------------- -bool HaarEvaluator::Feature :: read( const FileNode& node ) +bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) { FileNode rnode = node[CC_RECTS]; FileNodeIterator it = rnode.begin(), it_end = rnode.end(); @@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node ) rect[ri].weight = 0.f; } + const int W = origWinSize.width; + const int H = origWinSize.height; + for(ri = 0; it != it_end; ++it, ri++) { FileNodeIterator it2 = (*it).begin(); - it2 >> rect[ri].r.x >> rect[ri].r.y >> - rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight; + Feature::RectWeigth& rw = rect[ri]; + it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight; + // input validation + { + CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature"); + CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature"); + CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks + CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks + CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature"); + CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature"); + } } tilted = (int)node[CC_TILTED] != 0; @@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize) for(i = 0; i < n; i++, ++it) { - if(!ff[i].read(*it)) + if(!ff[i].read(*it, _origWinSize)) return false; if( ff[i].tilted ) hasTiltedFeatures = true; @@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const } //---------------------------------------------- LBPEvaluator ------------------------------------- -bool LBPEvaluator::Feature :: read(const FileNode& node ) +bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) { FileNode rnode = node[CC_RECT]; FileNodeIterator it = rnode.begin(); it >> rect.x >> rect.y >> rect.width >> rect.height; + + const int W = origWinSize.width; + const int H = origWinSize.height; + // input validation + { + CV_CheckGE(rect.x, 0, "Invalid LBP feature"); + CV_CheckGE(rect.y, 0, "Invalid LBP feature"); + CV_CheckLT(rect.x, W, "Invalid LBP feature"); + CV_CheckLT(rect.y, H, "Invalid LBP feature"); + CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature"); + CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature"); + } + return true; } @@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize ) std::vector& ff = *features; for(int i = 0; it != it_end; ++it, i++) { - if(!ff[i].read(*it)) + if(!ff[i].read(*it, _origWinSize)) return false; } nchannels = 1; @@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) origWinSize.width = (int)root[CC_WIDTH]; origWinSize.height = (int)root[CC_HEIGHT]; CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 ); + CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)"); + CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)"); // load feature params FileNode fn = root[CC_FEATURE_PARAMS]; diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp index f9910530b9..d9a288fcdd 100644 --- a/modules/objdetect/src/cascadedetect.hpp +++ b/modules/objdetect/src/cascadedetect.hpp @@ -317,12 +317,12 @@ public: struct Feature { Feature(); - bool read( const FileNode& node ); + bool read(const FileNode& node, const Size& origWinSize); bool tilted; enum { RECT_NUM = 3 }; - struct + struct RectWeigth { Rect r; float weight; @@ -412,7 +412,7 @@ public: Feature( int x, int y, int _block_w, int _block_h ) : rect(x, y, _block_w, _block_h) {} - bool read(const FileNode& node ); + bool read(const FileNode& node, const Size& origWinSize); Rect rect; // weight and height for block };