1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #28386 from akretz:fix_issue_28385

Fix integer overflow in medianBlur #28386

The bug in #28385 is that the pointer arithmetic in
https://github.com/opencv/opencv/blob/d8bc5b94b851d5b392c61e5b954fba992e18bb73/modules/imgproc/src/median_blur.simd.hpp#L666-L668
overflows if `i*sstep` is larger than `INT_MAX`, because both variables are of type `int`. If one operand is of type `size_t` instead, the other operand gets promoted to `size_t` before multiplication and overflow doesn't happen anymore.

The test allocates 2.3GB for the Mat; I hope that's okay.

This PR fixes #28385

### 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
This commit is contained in:
Adrian Kretz
2026-01-28 12:23:43 +01:00
committed by GitHub
parent cf1177e87e
commit 65e6890f33
2 changed files with 24 additions and 11 deletions
+11 -11
View File
@@ -360,7 +360,7 @@ medianBlur_8u_Om( const Mat& _src, Mat& _dst, int m )
uchar* dst = _dst.ptr();
int src_step = (int)_src.step, dst_step = (int)_dst.step;
int cn = _src.channels();
const uchar* src_max = src + size.height*src_step;
const uchar* src_max = src + (size_t)size.height*src_step;
CV_Assert(cn > 0 && cn <= 4);
#define UPDATE_ACC01( pix, cn, op ) \
@@ -381,8 +381,8 @@ medianBlur_8u_Om( const Mat& _src, Mat& _dst, int m )
if( x % 2 != 0 )
{
src_bottom = src_top += src_step*(size.height-1);
dst_cur += dst_step*(size.height-1);
src_bottom = src_top += (size_t)src_step*(size.height-1);
dst_cur += (size_t)dst_step*(size.height-1);
src_step1 = -src_step1;
dst_step1 = -dst_step1;
}
@@ -663,9 +663,9 @@ medianBlur_SortNet( const Mat& _src, Mat& _dst, int m )
size.width *= cn;
for( i = 0; i < size.height; i++, dst += dstep )
{
const T* row0 = src + std::max(i - 1, 0)*sstep;
const T* row1 = src + i*sstep;
const T* row2 = src + std::min(i + 1, size.height-1)*sstep;
const T* row0 = src + (size_t)std::max(i - 1, 0)*sstep;
const T* row1 = src + (size_t)i*sstep;
const T* row2 = src + (size_t)std::min(i + 1, size.height-1)*sstep;
int limit = cn;
for(j = 0;; )
@@ -750,11 +750,11 @@ medianBlur_SortNet( const Mat& _src, Mat& _dst, int m )
for( i = 0; i < size.height; i++, dst += dstep )
{
const T* row[5];
row[0] = src + std::max(i - 2, 0)*sstep;
row[1] = src + std::max(i - 1, 0)*sstep;
row[2] = src + i*sstep;
row[3] = src + std::min(i + 1, size.height-1)*sstep;
row[4] = src + std::min(i + 2, size.height-1)*sstep;
row[0] = src + (size_t)std::max(i - 2, 0)*sstep;
row[1] = src + (size_t)std::max(i - 1, 0)*sstep;
row[2] = src + (size_t)i*sstep;
row[3] = src + (size_t)std::min(i + 1, size.height-1)*sstep;
row[4] = src + (size_t)std::min(i + 2, size.height-1)*sstep;
int limit = cn*2;
for(j = 0;; )
+13
View File
@@ -2264,6 +2264,19 @@ TEST(Imgproc_MedianBlur, hires_regression_13409)
ASSERT_EQ(0.0, cvtest::norm(dst_hires(Rect(516, 516, 1016, 1016)), dst_ref(Rect(4, 4, 1016, 1016)), NORM_INF));
}
TEST(Imgproc_MedianBlur, regression_28385)
{
applyTestTag(CV_TEST_TAG_MEMORY_6GB);
Mat out;
// create a matrix larger than 2^31 to check for signed 32 bit integer overflow
Mat img(50000, 50000, CV_8U);
Mat sub = img(Rect(0, 0, 100, 50000));
// this crashes in case of overflow because of out-of-bounds memory access
medianBlur(sub, out, 3);
ASSERT_EQ(out.size(), Size(100, 50000));
}
TEST(Imgproc_Sobel, s16_regression_13506)
{
Mat src = (Mat_<short>(8, 16) << 127, 138, 130, 102, 118, 97, 76, 84, 124, 90, 146, 63, 130, 87, 212, 85,