diffstat of debian/ for opencv_3.2.0+dfsg-4.1 opencv_3.2.0+dfsg-4.1ubuntu0.1 changelog | 53 ++ control | 3 patches/CVE-2017-1000450.patch | 26 + patches/CVE-2017-14136.patch | 314 +++++++++++++++++ patches/CVE-2017-17760.patch | 25 + patches/CVE-2017-several.patch | 729 +++++++++++++++++++++++++++++++++++++++++ patches/CVE-2018-5268.patch | 128 +++++++ patches/CVE-2018-5269.patch | 227 ++++++++++++ patches/series | 6 9 files changed, 1510 insertions(+), 1 deletion(-) diff -Nru opencv-3.2.0+dfsg/debian/changelog opencv-3.2.0+dfsg/debian/changelog --- opencv-3.2.0+dfsg/debian/changelog 2018-07-11 20:59:18.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/changelog 2018-09-25 15:22:15.000000000 +0000 @@ -1,3 +1,56 @@ +opencv (3.2.0+dfsg-4.1ubuntu0.1) cosmic-security; urgency=medium + + * SECURITY UPDATE: Out-of-bounds read/write errors and buffer + overflows in different functions. + - debian/patches/CVE-2017-several.patch: fix in bitstrm.cpp, + bitstrm.hpp, grfmt_bmp.cpp, grfmt_pxm.cpp, loadsave.cpp, + test_grfmt.cpp and cuda_test.cpp. + - CVE-2016-1516 + - CVE-2016-1517 + - CVE-2017-12597 + - CVE-2017-12598 + - CVE-2017-12599 + - CVE-2017-12600 + - CVE-2017-12601 + - CVE-2017-12602 + - CVE-2017-12603 + - CVE-2017-12604 + - CVE-2017-12605 + - CVE-2017-12606 + - CVE-2017-12862 + - CVE-2017-12863 + - CVE-2017-12864 + * SECURITY UPDATE: Out of bound write cause segmentation fault + - debian/patches/CVE-2017-14136.patch: fix in grfmt_bmp.cpp, + grfmt_exr.cpp, grfmt_jpeg.cpp, grfmt_jpeg2000.cpp, + grfmt_pam.cpp, grfmt_sunras.cpp, utils.cpp and utils.hpp. + - CVE-2017-14136 + * SECURITY UPDATE: Buffer Overflow in the cv::PxMDecoder::readData + function in grfmt_pxm.cpp + - debian/patches/CVE-2017-17760.patch: fix in grfmt_pxm.cpp. + - CVE-2017-17760 + * SECURITY UPDATE: Integer overflow may lead to remote execution or + denial of service + - debian/patches/CVE-2017-1000450.patch: fix in grfmt_bmp.cpp. + - CVE-2017-1000450 + * SECURITY UPDATE: A heap-based buffer overflow happens in + cv::Jpeg2KDecoder::readComponent8u when parsing a crafted image file + - debian/patches/CVE-2018-5268.patch: fix in grfmt_jpeg2000.cpp. + - CVE-2018-5268 + * SECURITY UPDATE: an assertion failure happens in + cv::RBaseStream::setPos in modules/imgcodecs/src/bitstrm.cpp because + of an incorrect integer cast. + - debian/patches/CVE-2018-5269.patch: add overflow checks. + - CVE-2018-5269 + + -- Eduardo Barretto Tue, 25 Sep 2018 12:22:15 -0300 + +opencv (3.2.0+dfsg-4.1build1) cosmic; urgency=medium + + * No-change rebuild for ffmpeg soname changes. + + -- Matthias Klose Thu, 19 Jul 2018 08:43:40 +0000 + opencv (3.2.0+dfsg-4.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru opencv-3.2.0+dfsg/debian/control opencv-3.2.0+dfsg/debian/control --- opencv-3.2.0+dfsg/debian/control 2017-11-11 12:45:08.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/control 2018-09-25 15:22:15.000000000 +0000 @@ -1,7 +1,8 @@ Source: opencv Priority: optional Section: devel -Maintainer: Debian Science Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Science Team Uploaders: Sam Hocevar (Debian packages) , Nobuhiro Iwamatsu , diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2017-1000450.patch opencv-3.2.0+dfsg/debian/patches/CVE-2017-1000450.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2017-1000450.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2017-1000450.patch 2018-09-25 15:21:00.000000000 +0000 @@ -0,0 +1,26 @@ +From c58152d94ba878b2d7d76bcac59146312199b9eb Mon Sep 17 00:00:00 2001 +From: blendin +Date: Tue, 26 Sep 2017 23:04:01 -0700 +Subject: [PATCH] Fix out of bounds write + +--- + modules/imgcodecs/src/grfmt_bmp.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp +index 6afe52d..87d796c 100644 +--- a/modules/imgcodecs/src/grfmt_bmp.cpp ++++ b/modules/imgcodecs/src/grfmt_bmp.cpp +@@ -372,6 +372,9 @@ decode_rle4_bad: ; + gray_palette[code] ); + + line_end_flag = y - prev_y; ++ ++ if( y >= m_height ) ++ break; + } + else if( code > 2 ) // absolute mode + { +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2017-14136.patch opencv-3.2.0+dfsg/debian/patches/CVE-2017-14136.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2017-14136.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2017-14136.patch 2018-09-25 15:19:38.000000000 +0000 @@ -0,0 +1,314 @@ +From aacae2065744adb05e858d327198c7bbe7f452b0 Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Wed, 23 Aug 2017 15:15:27 +0300 +Subject: [PATCH] imgcodesc: fix code problems with integer overflow / address + arithmetic / UB + +--- + modules/imgcodecs/src/grfmt_bmp.cpp | 14 ++++--- + modules/imgcodecs/src/grfmt_exr.cpp | 10 ++--- + modules/imgcodecs/src/grfmt_jpeg.cpp | 2 +- + modules/imgcodecs/src/grfmt_jpeg2000.cpp | 6 +-- + modules/imgcodecs/src/grfmt_pam.cpp | 2 +- + modules/imgcodecs/src/grfmt_sunras.cpp | 6 +-- + modules/imgcodecs/src/utils.cpp | 51 ++++++++++++++---------- + modules/imgcodecs/src/utils.hpp | 2 + + 8 files changed, 54 insertions(+), 39 deletions(-) + +diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp +index d68224f..6afe52d 100644 +--- a/modules/imgcodecs/src/grfmt_bmp.cpp ++++ b/modules/imgcodecs/src/grfmt_bmp.cpp +@@ -115,7 +115,7 @@ bool BmpDecoder::readHeader() + + if( m_bpp <= 8 ) + { +- CV_Assert(clrused < 256); ++ CV_Assert(clrused <= 256); + memset(m_palette, 0, sizeof(m_palette)); + m_strm.getBytes(m_palette, (clrused == 0? 1< 1; + uchar gray_palette[256]; + bool result = false; +@@ -203,7 +204,7 @@ bool BmpDecoder::readData( Mat& img ) + + if( m_origin == IPL_ORIGIN_BL ) + { +- data += (m_height - 1)*step; ++ data += (m_height - 1)*(size_t)step; + step = -step; + } + +@@ -480,11 +481,12 @@ decode_rle8_bad: ; + result = true; + break; + default: +- assert(0); ++ CV_ErrorNoReturn(cv::Error::StsError, "Invalid/unsupported mode"); + } + } + catch(...) + { ++ throw; + } + + return result; +@@ -527,7 +529,7 @@ bool BmpEncoder::write( const Mat& img, const std::vector& ) + int bitmapHeaderSize = 40; + int paletteSize = channels > 1 ? 0 : 1024; + int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize; +- int fileSize = fileStep*height + headerSize; ++ size_t fileSize = (size_t)fileStep*height + headerSize; + PaletteEntry palette[256]; + + if( m_buf ) +@@ -537,7 +539,7 @@ bool BmpEncoder::write( const Mat& img, const std::vector& ) + strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) ); + + // write file header +- strm.putDWord( fileSize ); // file size ++ strm.putDWord( validateToInt(fileSize) ); // file size + strm.putDWord( 0 ); + strm.putDWord( headerSize ); + +diff --git a/modules/imgcodecs/src/grfmt_exr.cpp b/modules/imgcodecs/src/grfmt_exr.cpp +index 71d8912..c76a198 100644 +--- a/modules/imgcodecs/src/grfmt_exr.cpp ++++ b/modules/imgcodecs/src/grfmt_exr.cpp +@@ -188,7 +188,7 @@ bool ExrDecoder::readData( Mat& img ) + bool color = img.channels() > 1; + + uchar* data = img.ptr(); +- int step = img.step; ++ size_t step = img.step; + bool justcopy = m_native_depth; + bool chromatorgb = false; + bool rgbtogray = false; +@@ -196,8 +196,8 @@ bool ExrDecoder::readData( Mat& img ) + FrameBuffer frame; + int xsample[3] = {1, 1, 1}; + char *buffer; +- int xstep; +- int ystep; ++ size_t xstep = 0; ++ size_t ystep = 0; + + xstep = m_native_depth ? 4 : 1; + +@@ -588,7 +588,7 @@ bool ExrEncoder::write( const Mat& img, const std::vector& ) + bool issigned = depth == CV_8S || depth == CV_16S || depth == CV_32S; + bool isfloat = depth == CV_32F || depth == CV_64F; + depth = CV_ELEM_SIZE1(depth)*8; +- const int step = img.step; ++ const size_t step = img.step; + + Header header( width, height ); + Imf::PixelType type; +@@ -618,7 +618,7 @@ bool ExrEncoder::write( const Mat& img, const std::vector& ) + FrameBuffer frame; + + char *buffer; +- int bufferstep; ++ size_t bufferstep; + int size; + if( type == FLOAT && depth == 32 ) + { +diff --git a/modules/imgcodecs/src/grfmt_jpeg.cpp b/modules/imgcodecs/src/grfmt_jpeg.cpp +index 1f5f1e8..cc2804e 100644 +--- a/modules/imgcodecs/src/grfmt_jpeg.cpp ++++ b/modules/imgcodecs/src/grfmt_jpeg.cpp +@@ -396,7 +396,7 @@ int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht, + bool JpegDecoder::readData( Mat& img ) + { + volatile bool result = false; +- int step = (int)img.step; ++ size_t step = img.step; + bool color = img.channels() > 1; + + if( m_state && m_width && m_height ) +diff --git a/modules/imgcodecs/src/grfmt_jpeg2000.cpp b/modules/imgcodecs/src/grfmt_jpeg2000.cpp +index 24aa457..67fd5d7 100644 +--- a/modules/imgcodecs/src/grfmt_jpeg2000.cpp ++++ b/modules/imgcodecs/src/grfmt_jpeg2000.cpp +@@ -156,7 +156,7 @@ bool Jpeg2KDecoder::readData( Mat& img ) + bool result = false; + int color = img.channels() > 1; + uchar* data = img.ptr(); +- int step = (int)img.step; ++ size_t step = img.step; + jas_stream_t* stream = (jas_stream_t*)m_stream; + jas_image_t* image = (jas_image_t*)m_image; + +@@ -252,9 +252,9 @@ bool Jpeg2KDecoder::readData( Mat& img ) + if( !jas_image_readcmpt( image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer )) + { + if( img.depth() == CV_8U ) +- result = readComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts ); ++ result = readComponent8u( data + i, buffer, validateToInt(step), cmptlut[i], maxval, offset, ncmpts ); + else +- result = readComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts ); ++ result = readComponent16u( ((unsigned short *)data) + i, buffer, validateToInt(step / 2), cmptlut[i], maxval, offset, ncmpts ); + if( !result ) + { + i = ncmpts; +diff --git a/modules/imgcodecs/src/grfmt_pam.cpp b/modules/imgcodecs/src/grfmt_pam.cpp +index ac7198a..4908bb8 100644 +--- a/modules/imgcodecs/src/grfmt_pam.cpp ++++ b/modules/imgcodecs/src/grfmt_pam.cpp +@@ -476,7 +476,7 @@ bool PAMDecoder::readData( Mat& img ) + { + uchar* data = img.ptr(); + int target_channels = img.channels(); +- int imp_stride = (int)img.step; ++ size_t imp_stride = img.step; + int sample_depth = CV_ELEM_SIZE1(m_type); + int src_elems_per_row = m_width*m_channels; + int src_stride = src_elems_per_row*sample_depth; +diff --git a/modules/imgcodecs/src/grfmt_sunras.cpp b/modules/imgcodecs/src/grfmt_sunras.cpp +index 34e5c4e..97e1812 100644 +--- a/modules/imgcodecs/src/grfmt_sunras.cpp ++++ b/modules/imgcodecs/src/grfmt_sunras.cpp +@@ -156,7 +156,7 @@ bool SunRasterDecoder::readData( Mat& img ) + { + int color = img.channels() > 1; + uchar* data = img.ptr(); +- int step = (int)img.step; ++ size_t step = img.step; + uchar gray_palette[256]; + bool result = false; + int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2; +@@ -304,11 +304,11 @@ bad_decoding_1bpp: + code = m_strm.getByte(); + + if( color ) +- data = FillUniColor( data, line_end, step, width3, ++ data = FillUniColor( data, line_end, validateToInt(step), width3, + y, m_height, len, + m_palette[code] ); + else +- data = FillUniGray( data, line_end, step, width3, ++ data = FillUniGray( data, line_end, validateToInt(step), width3, + y, m_height, len, + gray_palette[code] ); + if( y >= m_height ) +diff --git a/modules/imgcodecs/src/utils.cpp b/modules/imgcodecs/src/utils.cpp +index 2ee5baf..474dae0 100644 +--- a/modules/imgcodecs/src/utils.cpp ++++ b/modules/imgcodecs/src/utils.cpp +@@ -42,6 +42,13 @@ + #include "precomp.hpp" + #include "utils.hpp" + ++int validateToInt(size_t sz) ++{ ++ int valueInt = (int)sz; ++ CV_Assert((size_t)valueInt == sz); ++ return valueInt; ++} ++ + #define SCALE 14 + #define cR (int)(0.299*(1 << SCALE) + 0.5) + #define cG (int)(0.587*(1 << SCALE) + 0.5) +@@ -537,23 +544,25 @@ uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palett + { + uchar* end = data + len*3; + ++ const PaletteEntry p0 = palette[0], p1 = palette[1]; ++ + while( (data += 24) < end ) + { + int idx = *indices++; +- *((PaletteEntry*)(data - 24)) = palette[(idx & 128) != 0]; +- *((PaletteEntry*)(data - 21)) = palette[(idx & 64) != 0]; +- *((PaletteEntry*)(data - 18)) = palette[(idx & 32) != 0]; +- *((PaletteEntry*)(data - 15)) = palette[(idx & 16) != 0]; +- *((PaletteEntry*)(data - 12)) = palette[(idx & 8) != 0]; +- *((PaletteEntry*)(data - 9)) = palette[(idx & 4) != 0]; +- *((PaletteEntry*)(data - 6)) = palette[(idx & 2) != 0]; +- *((PaletteEntry*)(data - 3)) = palette[(idx & 1) != 0]; ++ *((PaletteEntry*)(data - 24)) = (idx & 128) ? p1 : p0; ++ *((PaletteEntry*)(data - 21)) = (idx & 64) ? p1 : p0; ++ *((PaletteEntry*)(data - 18)) = (idx & 32) ? p1 : p0; ++ *((PaletteEntry*)(data - 15)) = (idx & 16) ? p1 : p0; ++ *((PaletteEntry*)(data - 12)) = (idx & 8) ? p1 : p0; ++ *((PaletteEntry*)(data - 9)) = (idx & 4) ? p1 : p0; ++ *((PaletteEntry*)(data - 6)) = (idx & 2) ? p1 : p0; ++ *((PaletteEntry*)(data - 3)) = (idx & 1) ? p1 : p0; + } + +- int idx = indices[0] << 24; ++ int idx = indices[0]; + for( data -= 24; data < end; data += 3, idx += idx ) + { +- PaletteEntry clr = palette[idx < 0]; ++ const PaletteEntry clr = (idx & 128) ? p1 : p0; + WRITE_PIX( data, clr ); + } + +@@ -565,23 +574,25 @@ uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette ) + { + uchar* end = data + len; + ++ const uchar p0 = palette[0], p1 = palette[1]; ++ + while( (data += 8) < end ) + { + int idx = *indices++; +- *((uchar*)(data - 8)) = palette[(idx & 128) != 0]; +- *((uchar*)(data - 7)) = palette[(idx & 64) != 0]; +- *((uchar*)(data - 6)) = palette[(idx & 32) != 0]; +- *((uchar*)(data - 5)) = palette[(idx & 16) != 0]; +- *((uchar*)(data - 4)) = palette[(idx & 8) != 0]; +- *((uchar*)(data - 3)) = palette[(idx & 4) != 0]; +- *((uchar*)(data - 2)) = palette[(idx & 2) != 0]; +- *((uchar*)(data - 1)) = palette[(idx & 1) != 0]; ++ *((uchar*)(data - 8)) = (idx & 128) ? p1 : p0; ++ *((uchar*)(data - 7)) = (idx & 64) ? p1 : p0; ++ *((uchar*)(data - 6)) = (idx & 32) ? p1 : p0; ++ *((uchar*)(data - 5)) = (idx & 16) ? p1 : p0; ++ *((uchar*)(data - 4)) = (idx & 8) ? p1 : p0; ++ *((uchar*)(data - 3)) = (idx & 4) ? p1 : p0; ++ *((uchar*)(data - 2)) = (idx & 2) ? p1 : p0; ++ *((uchar*)(data - 1)) = (idx & 1) ? p1 : p0; + } + +- int idx = indices[0] << 24; ++ int idx = indices[0]; + for( data -= 8; data < end; data++, idx += idx ) + { +- data[0] = palette[idx < 0]; ++ data[0] = (idx & 128) ? p1 : p0; + } + + return data; +diff --git a/modules/imgcodecs/src/utils.hpp b/modules/imgcodecs/src/utils.hpp +index cab1060..7af4c61 100644 +--- a/modules/imgcodecs/src/utils.hpp ++++ b/modules/imgcodecs/src/utils.hpp +@@ -42,6 +42,8 @@ + #ifndef _UTILS_H_ + #define _UTILS_H_ + ++int validateToInt(size_t step); ++ + struct PaletteEntry + { + unsigned char b, g, r, a; +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2017-17760.patch opencv-3.2.0+dfsg/debian/patches/CVE-2017-17760.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2017-17760.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2017-17760.patch 2018-09-25 15:19:56.000000000 +0000 @@ -0,0 +1,25 @@ +From 7bbe1a53cfc097b82b1589f7915a2120de39274c Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Thu, 21 Dec 2017 01:10:24 +0000 +Subject: [PATCH] imgcodecs(pxm): fix memcpy size + +--- + modules/imgcodecs/src/grfmt_pxm.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/modules/imgcodecs/src/grfmt_pxm.cpp b/modules/imgcodecs/src/grfmt_pxm.cpp +index ac6e08b..9fa1536 100644 +--- a/modules/imgcodecs/src/grfmt_pxm.cpp ++++ b/modules/imgcodecs/src/grfmt_pxm.cpp +@@ -328,7 +328,7 @@ bool PxMDecoder::readData( Mat& img ) + } + } + else +- memcpy( data, src, CV_ELEM_SIZE1(m_type)*m_width); ++ memcpy(data, src, img.elemSize1()*m_width); + } + else + { +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2017-several.patch opencv-3.2.0+dfsg/debian/patches/CVE-2017-several.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2017-several.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2017-several.patch 2018-09-25 15:19:20.000000000 +0000 @@ -0,0 +1,729 @@ +From 999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3 Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Tue, 15 Aug 2017 22:04:55 +0000 +Subject: [PATCH] imgcodecs: refactoring, improve code quality + +--- + modules/imgcodecs/src/bitstrm.cpp | 2 + + modules/imgcodecs/src/bitstrm.hpp | 19 +++- + modules/imgcodecs/src/grfmt_bmp.cpp | 13 ++- + modules/imgcodecs/src/grfmt_pxm.cpp | 121 ++++++++++++-------- + modules/imgcodecs/src/loadsave.cpp | 157 +++++++++++++++++++++----- + modules/imgcodecs/test/test_grfmt.cpp | 2 +- + modules/ts/src/cuda_test.cpp | 56 +++++---- + 7 files changed, 261 insertions(+), 109 deletions(-) + +diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp +index c47744b..bd7551d 100644 +--- a/modules/imgcodecs/src/bitstrm.cpp ++++ b/modules/imgcodecs/src/bitstrm.cpp +@@ -208,6 +208,8 @@ int RLByteStream::getByte() + current = m_current; + } + ++ CV_Assert(current < m_end); ++ + val = *((uchar*)current); + m_current = current + 1; + return val; +diff --git a/modules/imgcodecs/src/bitstrm.hpp b/modules/imgcodecs/src/bitstrm.hpp +index 465c0a8..2694797 100644 +--- a/modules/imgcodecs/src/bitstrm.hpp ++++ b/modules/imgcodecs/src/bitstrm.hpp +@@ -48,13 +48,20 @@ + namespace cv + { + +-enum +-{ +- RBS_THROW_EOS=-123, // exception code +- RBS_THROW_FORB=-124, // exception code +- RBS_HUFF_FORB=2047, // forrbidden huffman code "value" +- RBS_BAD_HEADER=-125 // invalid header ++#define DECLARE_RBS_EXCEPTION(name) \ ++class RBS_ ## name ## _Exception : public cv::Exception \ ++{ \ ++public: \ ++ RBS_ ## name ## _Exception(int code_, const String& err_, const String& func_, const String& file_, int line_) : \ ++ cv::Exception(code_, err_, func_, file_, line_) \ ++ {} \ + }; ++DECLARE_RBS_EXCEPTION(THROW_EOS) ++#define RBS_THROW_EOS RBS_THROW_EOS_Exception(cv::Error::StsError, "Unexpected end of input stream", CV_Func, __FILE__, __LINE__) ++DECLARE_RBS_EXCEPTION(THROW_FORB) ++#define RBS_THROW_FORB RBS_THROW_FORB_Exception(cv::Error::StsError, "Forrbidden huffman code", CV_Func, __FILE__, __LINE__) ++DECLARE_RBS_EXCEPTION(BAD_HEADER) ++#define RBS_BAD_HEADER RBS_BAD_HEADER_Exception(cv::Error::StsError, "Invalid header", CV_Func, __FILE__, __LINE__) + + typedef unsigned long ulong; + +diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp +index 4063d5b..d68224f 100644 +--- a/modules/imgcodecs/src/grfmt_bmp.cpp ++++ b/modules/imgcodecs/src/grfmt_bmp.cpp +@@ -115,8 +115,9 @@ bool BmpDecoder::readHeader() + + if( m_bpp <= 8 ) + { +- memset( m_palette, 0, sizeof(m_palette)); +- m_strm.getBytes( m_palette, (clrused == 0? 1< 2 ) // absolute mode + { + if( data + code*nch > line_end ) goto decode_rle4_bad; +- m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 ); ++ int sz = (((code + 1)>>1) + 1) & (~1); ++ CV_Assert((size_t)sz < _src.size()); ++ m_strm.getBytes(src, sz); + if( color ) + data = FillColorRow4( data, src, code, m_palette ); + else +@@ -376,7 +379,9 @@ decode_rle4_bad: ; + + if( data + code3 > line_end ) + goto decode_rle8_bad; +- m_strm.getBytes( src, (code + 1) & -2 ); ++ int sz = (code + 1) & (~1); ++ CV_Assert((size_t)sz < _src.size()); ++ m_strm.getBytes(src, sz); + if( color ) + data = FillColorRow8( data, src, code, m_palette ); + else +diff --git a/modules/imgcodecs/src/grfmt_pxm.cpp b/modules/imgcodecs/src/grfmt_pxm.cpp +index 8afd7b1..7406d4f 100644 +--- a/modules/imgcodecs/src/grfmt_pxm.cpp ++++ b/modules/imgcodecs/src/grfmt_pxm.cpp +@@ -43,50 +43,58 @@ + #include "precomp.hpp" + #include "utils.hpp" + #include "grfmt_pxm.hpp" ++#include + + namespace cv + { + + ///////////////////////// P?M reader ////////////////////////////// + +-static int ReadNumber( RLByteStream& strm, int maxdigits ) ++static int ReadNumber(RLByteStream& strm, int maxdigits = 0) + { + int code; +- int val = 0; ++ int64 val = 0; + int digits = 0; + + code = strm.getByte(); + +- if( !isdigit(code)) ++ while (!isdigit(code)) + { +- do ++ if (code == '#' ) + { +- if( code == '#' ) ++ do + { +- do +- { +- code = strm.getByte(); +- } +- while( code != '\n' && code != '\r' ); ++ code = strm.getByte(); + } +- ++ while (code != '\n' && code != '\r'); + code = strm.getByte(); +- +- while( isspace(code)) ++ } ++ else if (isspace(code)) ++ { ++ while (isspace(code)) + code = strm.getByte(); + } +- while( !isdigit( code )); ++ else ++ { ++#if 1 ++ CV_ErrorNoReturn_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code)); ++#else ++ code = strm.getByte(); ++#endif ++ } + } + + do + { +- val = val*10 + code - '0'; +- if( ++digits >= maxdigits ) break; ++ val = val*10 + (code - '0'); ++ CV_Assert(val <= INT_MAX && "PXM: ReadNumber(): result is too large"); ++ digits++; ++ if (maxdigits != 0 && digits >= maxdigits) break; + code = strm.getByte(); + } +- while( isdigit(code)); ++ while (isdigit(code)); + +- return val; ++ return (int)val; + } + + +@@ -119,13 +127,13 @@ ImageDecoder PxMDecoder::newDecoder() const + return makePtr(); + } + +-void PxMDecoder::close() ++void PxMDecoder::close() + { + m_strm.close(); + } + + +-bool PxMDecoder::readHeader() ++bool PxMDecoder::readHeader() + { + bool result = false; + +@@ -155,10 +163,10 @@ bool PxMDecoder::readHeader() + m_binary = code >= '4'; + m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1; + +- m_width = ReadNumber( m_strm, INT_MAX ); +- m_height = ReadNumber( m_strm, INT_MAX ); ++ m_width = ReadNumber(m_strm); ++ m_height = ReadNumber(m_strm); + +- m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX ); ++ m_maxval = m_bpp == 1 ? 1 : ReadNumber(m_strm); + if( m_maxval > 65535 ) + throw RBS_BAD_HEADER; + +@@ -172,8 +180,14 @@ bool PxMDecoder::readHeader() + result = true; + } + } +- catch(...) ++ catch (const cv::Exception&) ++ { ++ throw; ++ } ++ catch (...) + { ++ std::cerr << "PXM::readHeader(): unknown C++ exception" << std::endl << std::flush; ++ throw; + } + + if( !result ) +@@ -186,33 +200,28 @@ bool PxMDecoder::readHeader() + } + + +-bool PxMDecoder::readData( Mat& img ) ++bool PxMDecoder::readData( Mat& img ) + { + int color = img.channels() > 1; + uchar* data = img.ptr(); + PaletteEntry palette[256]; + bool result = false; +- int bit_depth = CV_ELEM_SIZE1(m_type)*8; +- int src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8; ++ const int bit_depth = CV_ELEM_SIZE1(m_type)*8; ++ const int src_pitch = (m_width*m_bpp*(bit_depth/8) + 7) / 8; + int nch = CV_MAT_CN(m_type); + int width3 = m_width*nch; +- int i, x, y; + + if( m_offset < 0 || !m_strm.isOpened()) + return false; + +- AutoBuffer _src(src_pitch + 32); +- uchar* src = _src; +- AutoBuffer _gray_palette; +- uchar* gray_palette = _gray_palette; ++ uchar gray_palette[256] = {0}; + + // create LUT for converting colors + if( bit_depth == 8 ) + { +- _gray_palette.allocate(m_maxval + 1); +- gray_palette = _gray_palette; ++ CV_Assert(m_maxval < 256); + +- for( i = 0; i <= m_maxval; i++ ) ++ for (int i = 0; i <= m_maxval; i++) + gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0)); + + FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 ); +@@ -226,12 +235,16 @@ bool PxMDecoder::readData( Mat& img ) + { + ////////////////////////// 1 BPP ///////////////////////// + case 1: ++ CV_Assert(CV_MAT_DEPTH(m_type) == CV_8U); + if( !m_binary ) + { +- for( y = 0; y < m_height; y++, data += img.step ) ++ AutoBuffer _src(m_width); ++ uchar* src = _src; ++ ++ for (int y = 0; y < m_height; y++, data += img.step) + { +- for( x = 0; x < m_width; x++ ) +- src[x] = ReadNumber( m_strm, 1 ) != 0; ++ for (int x = 0; x < m_width; x++) ++ src[x] = ReadNumber(m_strm, 1) != 0; + + if( color ) + FillColorRow8( data, src, m_width, palette ); +@@ -241,7 +254,10 @@ bool PxMDecoder::readData( Mat& img ) + } + else + { +- for( y = 0; y < m_height; y++, data += img.step ) ++ AutoBuffer _src(src_pitch); ++ uchar* src = _src; ++ ++ for (int y = 0; y < m_height; y++, data += img.step) + { + m_strm.getBytes( src, src_pitch ); + +@@ -257,13 +273,16 @@ bool PxMDecoder::readData( Mat& img ) + ////////////////////////// 8 BPP ///////////////////////// + case 8: + case 24: +- for( y = 0; y < m_height; y++, data += img.step ) ++ { ++ AutoBuffer _src(std::max(width3*2, src_pitch)); ++ uchar* src = _src; ++ for (int y = 0; y < m_height; y++, data += img.step) + { + if( !m_binary ) + { +- for( x = 0; x < width3; x++ ) ++ for (int x = 0; x < width3; x++) + { +- int code = ReadNumber( m_strm, INT_MAX ); ++ int code = ReadNumber(m_strm); + if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval; + if( bit_depth == 8 ) + src[x] = gray_palette[code]; +@@ -276,7 +295,7 @@ bool PxMDecoder::readData( Mat& img ) + m_strm.getBytes( src, src_pitch ); + if( bit_depth == 16 && !isBigEndian() ) + { +- for( x = 0; x < width3; x++ ) ++ for (int x = 0; x < width3; x++) + { + uchar v = src[x * 2]; + src[x * 2] = src[x * 2 + 1]; +@@ -287,7 +306,7 @@ bool PxMDecoder::readData( Mat& img ) + + if( img.depth() == CV_8U && bit_depth == 16 ) + { +- for( x = 0; x < width3; x++ ) ++ for (int x = 0; x < width3; x++) + { + int v = ((ushort *)src)[x]; + src[x] = (uchar)(v >> 8); +@@ -328,12 +347,19 @@ bool PxMDecoder::readData( Mat& img ) + } + result = true; + break; ++ } + default: +- assert(0); ++ CV_ErrorNoReturn(Error::StsError, "m_bpp is not supported"); + } + } +- catch(...) ++ catch (const cv::Exception&) ++ { ++ throw; ++ } ++ catch (...) + { ++ std::cerr << "PXM::readData(): unknown exception" << std::endl << std::flush; ++ throw; + } + + return result; +@@ -409,8 +435,9 @@ bool PxMEncoder::write( const Mat& img, const std::vector& params ) + char* buffer = _buffer; + + // write header; +- sprintf( buffer, "P%c\n%d %d\n%d\n", ++ sprintf( buffer, "P%c\n# Generated by OpenCV %s\n%d %d\n%d\n", + '2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0), ++ CV_VERSION, + width, height, (1 << depth) - 1 ); + + strm.putBytes( buffer, (int)strlen(buffer) ); +diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp +index 493ccab..a656834 100644 +--- a/modules/imgcodecs/src/loadsave.cpp ++++ b/modules/imgcodecs/src/loadsave.cpp +@@ -57,6 +57,23 @@ + namespace cv + { + ++// TODO Add runtime configuration ++#define CV_IO_MAX_IMAGE_PARAMS (50) ++#define CV_IO_MAX_IMAGE_WIDTH (1<<20) ++#define CV_IO_MAX_IMAGE_HEIGHT (1<<20) ++#define CV_IO_MAX_IMAGE_PIXELS (1<<30) // 1 Gigapixel ++static Size validateInputImageSize(const Size& size) ++{ ++ CV_Assert(size.width > 0); ++ CV_Assert(size.width <= CV_IO_MAX_IMAGE_WIDTH); ++ CV_Assert(size.height > 0); ++ CV_Assert(size.height <= CV_IO_MAX_IMAGE_HEIGHT); ++ uint64 pixels = (uint64)size.width * (uint64)size.height; ++ CV_Assert(pixels <= CV_IO_MAX_IMAGE_PIXELS); ++ return size; ++} ++ ++ + /** + * @struct ImageCodecInitializer + * +@@ -339,14 +356,27 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) + /// set the filename in the driver + decoder->setSource( filename ); + +- // read the header to make sure it succeeds +- if( !decoder->readHeader() ) ++ // read the header to make sure it succeeds ++ try ++ { ++ // read the header to make sure it succeeds ++ if( !decoder->readHeader() ) ++ return 0; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imread_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush; ++ return 0; ++ } ++ catch (...) ++ { ++ std::cerr << "imread_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush; + return 0; ++ } ++ + + // established the required input image size +- CvSize size; +- size.width = decoder->width(); +- size.height = decoder->height(); ++ Size size = validateInputImageSize(Size(decoder->width(), decoder->height())); + + // grab the decoded type + int type = decoder->type(); +@@ -382,7 +412,21 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) + } + + // read the image data +- if( !decoder->readData( *data )) ++ bool success = false; ++ try ++ { ++ if (decoder->readData(*data)) ++ success = true; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imread_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush; ++ } ++ catch (...) ++ { ++ std::cerr << "imread_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush; ++ } ++ if (!success) + { + cvReleaseImage( &image ); + cvReleaseMat( &matrix ); +@@ -435,8 +479,22 @@ imreadmulti_(const String& filename, int flags, std::vector& mats) + decoder->setSource(filename); + + // read the header to make sure it succeeds +- if (!decoder->readHeader()) ++ try ++ { ++ // read the header to make sure it succeeds ++ if( !decoder->readHeader() ) ++ return 0; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imreadmulti_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush; ++ return 0; ++ } ++ catch (...) ++ { ++ std::cerr << "imreadmulti_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush; + return 0; ++ } + + for (;;) + { +@@ -454,17 +512,33 @@ imreadmulti_(const String& filename, int flags, std::vector& mats) + type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1); + } + ++ // established the required input image size ++ Size size = validateInputImageSize(Size(decoder->width(), decoder->height())); ++ + // read the image data +- Mat mat(decoder->height(), decoder->width(), type); +- if (!decoder->readData(mat)) ++ Mat mat(size.height, size.width, type); ++ bool success = false; ++ try + { +- // optionally rotate the data if EXIF' orientation flag says so +- if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED ) +- { +- ApplyExifOrientation(filename, mat); +- } + ++ if (decoder->readData(mat)) ++ success = true; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imreadmulti_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush; ++ } ++ catch (...) ++ { ++ std::cerr << "imreadmulti_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush; ++ } ++ if (!success) + break; ++ ++ // optionally rotate the data if EXIF' orientation flag says so ++ if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED ) ++ { ++ ApplyExifOrientation(filename, mat); + } + + mats.push_back(mat); +@@ -543,6 +617,7 @@ static bool imwrite_( const String& filename, const Mat& image, + } + + encoder->setDestination( filename ); ++ CV_Assert(params.size() <= CV_IO_MAX_IMAGE_PARAMS*2); + bool code = encoder->write( *pimage, params ); + + // CV_Assert( code ); +@@ -581,22 +656,35 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) + decoder->setSource(filename); + } + +- if( !decoder->readHeader() ) ++ bool success = false; ++ try ++ { ++ if (decoder->readHeader()) ++ success = true; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imdecode_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush; ++ } ++ catch (...) ++ { ++ std::cerr << "imdecode_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush; ++ } ++ if (!success) + { + decoder.release(); +- if ( !filename.empty() ) ++ if (!filename.empty()) + { +- if ( remove(filename.c_str()) != 0 ) ++ if (0 != remove(filename.c_str())) + { +- CV_Error( CV_StsError, "unable to remove temporary file" ); ++ std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush; + } + } + return 0; + } + +- CvSize size; +- size.width = decoder->width(); +- size.height = decoder->height(); ++ // established the required input image size ++ Size size = validateInputImageSize(Size(decoder->width(), decoder->height())); + + int type = decoder->type(); + if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED ) +@@ -630,17 +718,30 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) + temp = cvarrToMat(image); + } + +- bool code = decoder->readData( *data ); ++ success = false; ++ try ++ { ++ if (decoder->readData(*data)) ++ success = true; ++ } ++ catch (const cv::Exception& e) ++ { ++ std::cerr << "imdecode_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush; ++ } ++ catch (...) ++ { ++ std::cerr << "imdecode_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush; ++ } + decoder.release(); +- if ( !filename.empty() ) ++ if (!filename.empty()) + { +- if ( remove(filename.c_str()) != 0 ) ++ if (0 != remove(filename.c_str())) + { +- CV_Error( CV_StsError, "unable to remove temporary file" ); ++ std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush; + } + } + +- if( !code ) ++ if (!success) + { + cvReleaseImage( &image ); + cvReleaseMat( &matrix ); +@@ -757,7 +858,7 @@ cvSaveImage( const char* filename, const CvArr* arr, const int* _params ) + if( _params ) + { + for( ; _params[i] > 0; i += 2 ) +- ; ++ CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons + } + return cv::imwrite_(filename, cv::cvarrToMat(arr), + i > 0 ? std::vector(_params, _params+i) : std::vector(), +@@ -788,7 +889,7 @@ cvEncodeImage( const char* ext, const CvArr* arr, const int* _params ) + if( _params ) + { + for( ; _params[i] > 0; i += 2 ) +- ; ++ CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons + } + cv::Mat img = cv::cvarrToMat(arr); + if( CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL ) +diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp +index faca3d7..5f7f279 100644 +--- a/modules/imgcodecs/test/test_grfmt.cpp ++++ b/modules/imgcodecs/test/test_grfmt.cpp +@@ -784,7 +784,7 @@ TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian) + EXPECT_EQ(0xDEAD, img.at(0,0)); + EXPECT_EQ(0xBEEF, img.at(0,1)); + +- remove(filename.c_str()); ++ EXPECT_EQ(0, remove(filename.c_str())); + } + } + +diff --git a/modules/ts/src/cuda_test.cpp b/modules/ts/src/cuda_test.cpp +index a48e0a0..eb4cee1 100644 +--- a/modules/ts/src/cuda_test.cpp ++++ b/modules/ts/src/cuda_test.cpp +@@ -322,16 +322,20 @@ namespace cvtest + + if (m1.size() != m2.size()) + { +- return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \"" +- << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \"" +- << expr2 << "\" [" << PrintToString(m2.size()) << "]"; ++ std::stringstream msg; ++ msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \"" ++ << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \"" ++ << expr2 << "\" [" << PrintToString(m2.size()) << "]"; ++ return AssertionFailure() << msg.str(); + } + + if (m1.type() != m2.type()) + { +- return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \"" +- << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \"" +- << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]"; ++ std::stringstream msg; ++ msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \"" ++ << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \"" ++ << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]"; ++ return AssertionFailure() << msg.str(); + } + + Mat diff; +@@ -343,12 +347,14 @@ namespace cvtest + + if (maxVal > eps) + { +- return AssertionFailure() << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2 +- << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")" +- << ", which exceeds \"" << eps_expr << "\", where \"" +- << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \"" +- << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \"" +- << eps_expr << "\" evaluates to " << eps; ++ std::stringstream msg; ++ msg << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2 ++ << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")" ++ << ", which exceeds \"" << eps_expr << "\", where \"" ++ << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \"" ++ << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \"" ++ << eps_expr << "\" evaluates to " << eps; ++ return AssertionFailure() << msg.str(); + } + + return AssertionSuccess(); +@@ -469,9 +475,11 @@ namespace cvtest + { + if (gold.size() != actual.size()) + { +- return testing::AssertionFailure() << "KeyPoints size mistmach\n" +- << "\"" << gold_expr << "\" : " << gold.size() << "\n" +- << "\"" << actual_expr << "\" : " << actual.size(); ++ std::stringstream msg; ++ msg << "KeyPoints size mistmach\n" ++ << "\"" << gold_expr << "\" : " << gold.size() << "\n" ++ << "\"" << actual_expr << "\" : " << actual.size(); ++ return AssertionFailure() << msg.str(); + } + + std::sort(actual.begin(), actual.end(), KeyPointLess()); +@@ -484,14 +492,16 @@ namespace cvtest + + if (!keyPointsEquals(p1, p2)) + { +- return testing::AssertionFailure() << "KeyPoints differ at " << i << "\n" +- << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n" +- << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n" +- << "size : " << p1.size << " vs " << p2.size << "\n" +- << "angle : " << p1.angle << " vs " << p2.angle << "\n" +- << "response : " << p1.response << " vs " << p2.response << "\n" +- << "octave : " << p1.octave << " vs " << p2.octave << "\n" +- << "class_id : " << p1.class_id << " vs " << p2.class_id; ++ std::stringstream msg; ++ msg << "KeyPoints differ at " << i << "\n" ++ << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n" ++ << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n" ++ << "size : " << p1.size << " vs " << p2.size << "\n" ++ << "angle : " << p1.angle << " vs " << p2.angle << "\n" ++ << "response : " << p1.response << " vs " << p2.response << "\n" ++ << "octave : " << p1.octave << " vs " << p2.octave << "\n" ++ << "class_id : " << p1.class_id << " vs " << p2.class_id; ++ return AssertionFailure() << msg.str(); + } + } + +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2018-5268.patch opencv-3.2.0+dfsg/debian/patches/CVE-2018-5268.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2018-5268.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2018-5268.patch 2018-09-25 15:21:19.000000000 +0000 @@ -0,0 +1,128 @@ +From 435a3e337bd9d4e11af61cf8b8afca067bf1a8aa Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Tue, 9 Jan 2018 17:36:57 +0300 +Subject: [PATCH] imgcodecs: add more Jasper checks for supported and tested + cases + +--- + modules/imgcodecs/src/grfmt_jpeg2000.cpp | 46 ++++++++++++++++++++---- + 1 file changed, 39 insertions(+), 7 deletions(-) + +diff --git a/modules/imgcodecs/src/grfmt_jpeg2000.cpp b/modules/imgcodecs/src/grfmt_jpeg2000.cpp +index 67fd5d7..4888842 100644 +--- a/modules/imgcodecs/src/grfmt_jpeg2000.cpp ++++ b/modules/imgcodecs/src/grfmt_jpeg2000.cpp +@@ -77,7 +77,8 @@ static JasperInitializer initialize_jasper; + + Jpeg2KDecoder::Jpeg2KDecoder() + { +- m_signature = '\0' + String() + '\0' + String() + '\0' + String("\x0cjP \r\n\x87\n"); ++ static const unsigned char signature_[12] = { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 13, 10, 0x87, 10}; ++ m_signature = String((const char*)signature_, (const char*)signature_ + sizeof(signature_)); + m_stream = 0; + m_image = 0; + } +@@ -121,6 +122,8 @@ bool Jpeg2KDecoder::readHeader() + jas_image_t* image = jas_image_decode( stream, -1, 0 ); + m_image = image; + if( image ) { ++ CV_Assert(0 == (jas_image_tlx(image)) && "not supported"); ++ CV_Assert(0 == (jas_image_tly(image)) && "not supported"); + m_width = jas_image_width( image ); + m_height = jas_image_height( image ); + +@@ -130,14 +133,31 @@ bool Jpeg2KDecoder::readHeader() + for( int i = 0; i < numcmpts; i++ ) + { + int depth_i = jas_image_cmptprec( image, i ); ++ CV_Assert(depth == 0 || depth == depth_i); // component data type mismatch + depth = MAX(depth, depth_i); + if( jas_image_cmpttype( image, i ) > 2 ) + continue; ++ int sgnd = jas_image_cmptsgnd(image, i); ++ int xstart = jas_image_cmpttlx(image, i); ++ int xend = jas_image_cmptbrx(image, i); ++ int xstep = jas_image_cmpthstep(image, i); ++ int ystart = jas_image_cmpttly(image, i); ++ int yend = jas_image_cmptbry(image, i); ++ int ystep = jas_image_cmptvstep(image, i); ++ CV_Assert(sgnd == 0 && "not supported"); ++ CV_Assert(xstart == 0 && "not supported"); ++ CV_Assert(ystart == 0 && "not supported"); ++ CV_Assert(xstep == 1 && "not supported"); ++ CV_Assert(ystep == 1 && "not supported"); ++ CV_Assert(xend == m_width); ++ CV_Assert(yend == m_height); + cntcmpts++; + } + + if( cntcmpts ) + { ++ CV_Assert(depth == 8 || depth == 16); ++ CV_Assert(cntcmpts == 1 || cntcmpts == 3); + m_type = CV_MAKETYPE(depth <= 8 ? CV_8U : CV_16U, cntcmpts > 1 ? 3 : 1); + result = true; + } +@@ -150,9 +170,14 @@ bool Jpeg2KDecoder::readHeader() + return result; + } + ++static void Jpeg2KDecoder_close(Jpeg2KDecoder* ptr) ++{ ++ ptr->close(); ++} + + bool Jpeg2KDecoder::readData( Mat& img ) + { ++ Ptr close_this(this, Jpeg2KDecoder_close); + bool result = false; + int color = img.channels() > 1; + uchar* data = img.ptr(); +@@ -204,11 +229,16 @@ bool Jpeg2KDecoder::readData( Mat& img ) + result = true; + } + else +- fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); ++ { ++ jas_cmprof_destroy(clrprof); ++ CV_Error(Error::StsError, "JPEG 2000 LOADER ERROR: cannot convert colorspace"); ++ } + jas_cmprof_destroy( clrprof ); + } + else +- fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); ++ { ++ CV_Error(Error::StsError, "JPEG 2000 LOADER ERROR: unable to create colorspace"); ++ } + } + else + result = true; +@@ -257,8 +287,8 @@ bool Jpeg2KDecoder::readData( Mat& img ) + result = readComponent16u( ((unsigned short *)data) + i, buffer, validateToInt(step / 2), cmptlut[i], maxval, offset, ncmpts ); + if( !result ) + { +- i = ncmpts; +- result = false; ++ jas_matrix_destroy( buffer ); ++ CV_Error(Error::StsError, "JPEG2000 LOADER ERROR: failed to read component"); + } + } + jas_matrix_destroy( buffer ); +@@ -267,10 +297,12 @@ bool Jpeg2KDecoder::readData( Mat& img ) + } + } + else +- fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" ); ++ { ++ CV_Error(Error::StsError, "JPEG2000 LOADER ERROR: colorspace conversion failed"); ++ } + } + +- close(); ++ CV_Assert(result == true); + + #ifndef WIN32 + if (!clr.empty()) +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/CVE-2018-5269.patch opencv-3.2.0+dfsg/debian/patches/CVE-2018-5269.patch --- opencv-3.2.0+dfsg/debian/patches/CVE-2018-5269.patch 1970-01-01 00:00:00.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/CVE-2018-5269.patch 2018-09-25 15:21:32.000000000 +0000 @@ -0,0 +1,227 @@ +From 8a76fadaa39b87d740ec3346d9eccb64bde5a6af Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Tue, 9 Jan 2018 17:56:52 +0300 +Subject: [PATCH] imgcodecs: add overflow checks + +and + +From be5247921da02e58aa42830c81730ef20a23af80 Mon Sep 17 00:00:00 2001 +From: Alexander Alekhin +Date: Tue, 9 Jan 2018 17:48:55 +0300 +Subject: [PATCH] imgcodecs: remove assert() usage + +--- + modules/imgcodecs/src/bitstrm.cpp | 22 ++++++++++++++-------- + modules/imgcodecs/src/grfmt_bmp.cpp | 1 + + modules/imgcodecs/src/grfmt_pam.cpp | 10 ++++++---- + modules/imgcodecs/src/grfmt_sunras.cpp | 8 ++++---- + modules/imgcodecs/src/precomp.hpp | 1 - + modules/imgcodecs/src/utils.cpp | 2 +- + 6 files changed, 26 insertions(+), 18 deletions(-) + +diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp +index bd7551d..8b9066e 100644 +--- a/modules/imgcodecs/src/bitstrm.cpp ++++ b/modules/imgcodecs/src/bitstrm.cpp +@@ -42,6 +42,7 @@ + + #include "precomp.hpp" + #include "bitstrm.hpp" ++#include "utils.hpp" + + namespace cv + { +@@ -164,7 +165,7 @@ void RBaseStream::release() + + void RBaseStream::setPos( int pos ) + { +- assert( isOpened() && pos >= 0 ); ++ CV_Assert(isOpened() && pos >= 0); + + if( !m_file ) + { +@@ -181,14 +182,19 @@ void RBaseStream::setPos( int pos ) + + int RBaseStream::getPos() + { +- assert( isOpened() ); +- return m_block_pos + (int)(m_current - m_start); ++ CV_Assert(isOpened()); ++ int pos = validateToInt((m_current - m_start) + m_block_pos); ++ CV_Assert(pos >= m_block_pos); // overflow check ++ CV_Assert(pos >= 0); // overflow check ++ return pos; + } + + void RBaseStream::skip( int bytes ) + { +- assert( bytes >= 0 ); ++ CV_Assert(bytes >= 0); ++ uchar* old = m_current; + m_current += bytes; ++ CV_Assert(m_current >= old); // overflow check + } + + ///////////////////////// RLByteStream //////////////////////////// +@@ -220,7 +226,7 @@ int RLByteStream::getBytes( void* buffer, int count ) + { + uchar* data = (uchar*)buffer; + int readed = 0; +- assert( count >= 0 ); ++ CV_Assert(count >= 0); + + while( count > 0 ) + { +@@ -371,7 +377,7 @@ void WBaseStream::writeBlock() + { + int size = (int)(m_current - m_start); + +- assert( isOpened() ); ++ CV_Assert(isOpened()); + if( size == 0 ) + return; + +@@ -442,7 +448,7 @@ void WBaseStream::release() + + int WBaseStream::getPos() + { +- assert( isOpened() ); ++ CV_Assert(isOpened()); + return m_block_pos + (int)(m_current - m_start); + } + +@@ -465,7 +471,7 @@ void WLByteStream::putBytes( const void* buffer, int count ) + { + uchar* data = (uchar*)buffer; + +- assert( data && m_current && count >= 0 ); ++ CV_Assert(data && m_current && count >= 0); + + while( count ) + { +diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp +index 87d796c..554e604 100644 +--- a/modules/imgcodecs/src/grfmt_bmp.cpp ++++ b/modules/imgcodecs/src/grfmt_bmp.cpp +@@ -92,6 +92,7 @@ bool BmpDecoder::readHeader() + m_offset = m_strm.getDWord(); + + int size = m_strm.getDWord(); ++ CV_Assert(size > 0); // overflow, 2Gb limit + + if( size >= 36 ) + { +diff --git a/modules/imgcodecs/src/grfmt_pam.cpp b/modules/imgcodecs/src/grfmt_pam.cpp +index 4908bb8..3e79c3e 100644 +--- a/modules/imgcodecs/src/grfmt_pam.cpp ++++ b/modules/imgcodecs/src/grfmt_pam.cpp +@@ -53,6 +53,8 @@ + #include "utils.hpp" + #include "grfmt_pam.hpp" + ++using namespace cv; ++ + /* the PAM related fields */ + #define MAX_PAM_HEADER_IDENITFIER_LENGTH 8 + #define MAX_PAM_HEADER_VALUE_LENGTH 255 +@@ -184,7 +186,7 @@ basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_ + } + break; + default: +- assert (0); ++ CV_Error(Error::StsInternal, ""); + } + break; + } +@@ -205,12 +207,12 @@ basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_ + } + break; + default: +- assert (0); ++ CV_Error(Error::StsInternal, ""); + } + break; + } + default: +- assert (0); ++ CV_Error(Error::StsInternal, ""); + } + } + +@@ -710,7 +712,7 @@ bool PAMEncoder::write( const Mat& img, const std::vector& params ) + } else + strm.putBytes( data, stride*height ); + } else +- assert (0); ++ CV_Error(Error::StsInternal, ""); + + strm.close(); + return true; +diff --git a/modules/imgcodecs/src/grfmt_sunras.cpp b/modules/imgcodecs/src/grfmt_sunras.cpp +index 97e1812..97e51fd 100644 +--- a/modules/imgcodecs/src/grfmt_sunras.cpp ++++ b/modules/imgcodecs/src/grfmt_sunras.cpp +@@ -120,7 +120,7 @@ bool SunRasterDecoder::readHeader() + m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1; + m_offset = m_strm.getPos(); + +- assert( m_offset == 32 + m_maplength ); ++ CV_Assert(m_offset == 32 + m_maplength); + result = true; + } + } +@@ -133,7 +133,7 @@ bool SunRasterDecoder::readHeader() + + m_offset = m_strm.getPos(); + +- assert( m_offset == 32 + m_maplength ); ++ CV_Assert(m_offset == 32 + m_maplength); + result = true; + } + } +@@ -226,7 +226,7 @@ bool SunRasterDecoder::readData( Mat& img ) + code = m_strm.getByte(); + if( len > line_end - tsrc ) + { +- assert(0); ++ CV_Error(Error::StsInternal, ""); + goto bad_decoding_1bpp; + } + +@@ -367,7 +367,7 @@ bad_decoding_end: + result = true; + break; + default: +- assert(0); ++ CV_Error(Error::StsInternal, ""); + } + } + catch( ... ) +diff --git a/modules/imgcodecs/src/precomp.hpp b/modules/imgcodecs/src/precomp.hpp +index 6a16ca8..90390a0 100644 +--- a/modules/imgcodecs/src/precomp.hpp ++++ b/modules/imgcodecs/src/precomp.hpp +@@ -56,7 +56,6 @@ + #include + #include + #include +-#include + + #if defined WIN32 || defined WINCE + #include +diff --git a/modules/imgcodecs/src/utils.cpp b/modules/imgcodecs/src/utils.cpp +index 474dae0..3273912 100644 +--- a/modules/imgcodecs/src/utils.cpp ++++ b/modules/imgcodecs/src/utils.cpp +@@ -670,7 +670,7 @@ cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags ) + icvCvt_BGR2Gray_8u_C3C1R( s, s_step, d, d_step, size, swap_rb ); + break; + case 33: +- assert( swap_rb ); ++ CV_Assert(swap_rb); + icvCvt_RGB2BGR_8u_C3R( s, s_step, d, d_step, size ); + break; + case 41: +-- +2.17.1 + diff -Nru opencv-3.2.0+dfsg/debian/patches/series opencv-3.2.0+dfsg/debian/patches/series --- opencv-3.2.0+dfsg/debian/patches/series 2018-07-11 20:58:48.000000000 +0000 +++ opencv-3.2.0+dfsg/debian/patches/series 2018-09-25 15:21:32.000000000 +0000 @@ -6,3 +6,9 @@ disable_dnn.patch fix_VFP_asm.patch ffmpeg4.0.patch +CVE-2017-several.patch +CVE-2017-14136.patch +CVE-2017-17760.patch +CVE-2017-1000450.patch +CVE-2018-5268.patch +CVE-2018-5269.patch