Yocto 2.4

Move OpenBMC to Yocto 2.4(rocko)

Tested: Built and verified Witherspoon and Palmetto images
Change-Id: I12057b18610d6fb0e6903c60213690301e9b0c67
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/import-layers/meta-openembedded/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch b/import-layers/meta-openembedded/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch
new file mode 100644
index 0000000..39f33af
--- /dev/null
+++ b/import-layers/meta-openembedded/meta-oe/recipes-support/opencv/opencv/0002-imgcodecs-refactoring-improve-code-quality.patch
@@ -0,0 +1,656 @@
+Upstream-Status: Backport [https://github.com/opencv/opencv/pull/9376/commits/999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3]
+
+Fix CVEs for opencv 3.3:
+
+* 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
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+---
+From 999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
+Date: Tue, 15 Aug 2017 22:04:55 +0000
+Subject: [PATCH 2/3] 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 | 122 ++++++++++++++++-----------
+ modules/imgcodecs/src/loadsave.cpp  | 164 +++++++++++++++++++++++++++++-------
+ 5 files changed, 231 insertions(+), 89 deletions(-)
+
+diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp
+index a7e187fa0..0a8941aec 100644
+--- a/modules/imgcodecs/src/bitstrm.cpp
++++ b/modules/imgcodecs/src/bitstrm.cpp
+@@ -209,6 +209,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 465c0a847..26947971f 100644
+--- a/modules/imgcodecs/src/bitstrm.hpp
++++ b/modules/imgcodecs/src/bitstrm.hpp
+@@ -48,13 +48,20 @@
+ namespace cv
+ {
+ 
+-enum
+-{
+-    RBS_THROW_EOS=-123,  // <end of stream> exception code
+-    RBS_THROW_FORB=-124,  // <forrbidden huffman code> 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 86cacd316..257f97c2d 100644
+--- a/modules/imgcodecs/src/grfmt_bmp.cpp
++++ b/modules/imgcodecs/src/grfmt_bmp.cpp
+@@ -118,8 +118,9 @@ bool  BmpDecoder::readHeader()
+ 
+                 if( m_bpp <= 8 )
+                 {
+-                    memset( m_palette, 0, sizeof(m_palette));
+-                    m_strm.getBytes( m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
++                    CV_Assert(clrused < 256);
++                    memset(m_palette, 0, sizeof(m_palette));
++                    m_strm.getBytes(m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
+                     iscolor = IsColorPalette( m_palette, m_bpp );
+                 }
+                 else if( m_bpp == 16 && m_rle_code == BMP_BITFIELDS )
+@@ -290,7 +291,9 @@ bool  BmpDecoder::readData( Mat& img )
+                     else if( code > 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
+@@ -379,7 +382,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 1750cb705..68bd8fd93 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 <iostream>
+ 
+ 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;
+ }
+ 
+ 
+@@ -122,13 +130,13 @@ ImageDecoder PxMDecoder::newDecoder() const
+     return makePtr<PxMDecoder>();
+ }
+ 
+-void  PxMDecoder::close()
++void PxMDecoder::close()
+ {
+     m_strm.close();
+ }
+ 
+ 
+-bool  PxMDecoder::readHeader()
++bool PxMDecoder::readHeader()
+ {
+     bool result = false;
+ 
+@@ -158,10 +166,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;
+ 
+@@ -175,8 +183,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 )
+@@ -189,33 +203,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 = divUp(m_width*m_bpp*(bit_depth/8), 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<uchar> _src(src_pitch + 32);
+-    uchar* src = _src;
+-    AutoBuffer<uchar> _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 );
+@@ -229,12 +238,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<uchar> _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 );
+@@ -244,7 +257,10 @@ bool  PxMDecoder::readData( Mat& img )
+             }
+             else
+             {
+-                for( y = 0; y < m_height; y++, data += img.step )
++                AutoBuffer<uchar> _src(src_pitch);
++                uchar* src = _src;
++
++                for (int y = 0; y < m_height; y++, data += img.step)
+                 {
+                     m_strm.getBytes( src, src_pitch );
+ 
+@@ -260,13 +276,17 @@ bool  PxMDecoder::readData( Mat& img )
+         ////////////////////////// 8 BPP /////////////////////////
+         case 8:
+         case 24:
+-            for( y = 0; y < m_height; y++, data += img.step )
++        {
++            AutoBuffer<uchar> _src(std::max<size_t>(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];
+@@ -279,7 +299,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];
+@@ -290,7 +310,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);
+@@ -331,12 +351,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;
+@@ -412,8 +439,9 @@ bool  PxMEncoder::write( const Mat& img, const std::vector<int>& 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 3b2366217..5ee4ca354 100644
+--- a/modules/imgcodecs/src/loadsave.cpp
++++ b/modules/imgcodecs/src/loadsave.cpp
+@@ -55,6 +55,27 @@
+ /****************************************************************************************\
+ *                                      Image Codecs                                      *
+ \****************************************************************************************/
++
++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;
++}
++
++
+ namespace {
+ 
+ class ByteStreamBuffer: public std::streambuf
+@@ -94,9 +115,6 @@ protected:
+ 
+ }
+ 
+-namespace cv
+-{
+-
+ /**
+  * @struct ImageCodecInitializer
+  *
+@@ -408,14 +426,26 @@ 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() )
++    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();
+@@ -451,7 +481,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 );
+@@ -504,8 +548,22 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& 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 (;;)
+     {
+@@ -523,17 +581,32 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& 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);
+@@ -616,6 +689,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 );
+@@ -663,22 +737,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 )
+@@ -712,17 +799,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 );
+@@ -859,7 +959,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<int>(_params, _params+i) : std::vector<int>(),
+@@ -890,7 +990,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 )
+-- 
+2.14.1
+