Skip to content

Commit df1a026

Browse files
committed
imgcodesc: fix code problems with integer overflow / address arithmetic / UB
1 parent dd9bf1b commit df1a026

File tree

7 files changed

+49
-36
lines changed

7 files changed

+49
-36
lines changed

modules/highgui/src/grfmt_bmp.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ bool BmpDecoder::readHeader()
185185
bool BmpDecoder::readData( Mat& img )
186186
{
187187
uchar* data = img.data;
188-
int step = (int)img.step;
188+
int step = validateToInt(img.step);
189189
bool color = img.channels() > 1;
190190
uchar gray_palette[256];
191191
bool result = false;
@@ -198,7 +198,7 @@ bool BmpDecoder::readData( Mat& img )
198198

199199
if( m_origin == IPL_ORIGIN_BL )
200200
{
201-
data += (m_height - 1)*step;
201+
data += (m_height - 1)*(size_t)step;
202202
step = -step;
203203
}
204204

@@ -522,7 +522,7 @@ bool BmpEncoder::write( const Mat& img, const vector<int>& )
522522
int bitmapHeaderSize = 40;
523523
int paletteSize = channels > 1 ? 0 : 1024;
524524
int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize;
525-
int fileSize = fileStep*height + headerSize;
525+
size_t fileSize = (size_t)fileStep*height + headerSize;
526526
PaletteEntry palette[256];
527527

528528
if( m_buf )
@@ -532,7 +532,7 @@ bool BmpEncoder::write( const Mat& img, const vector<int>& )
532532
strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) );
533533

534534
// write file header
535-
strm.putDWord( fileSize ); // file size
535+
strm.putDWord( validateToInt(fileSize) ); // file size
536536
strm.putDWord( 0 );
537537
strm.putDWord( headerSize );
538538

modules/highgui/src/grfmt_exr.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,16 @@ bool ExrDecoder::readData( Mat& img )
188188
bool color = img.channels() > 1;
189189

190190
uchar* data = img.data;
191-
int step = img.step;
191+
size_t step = img.step;
192192
bool justcopy = m_native_depth;
193193
bool chromatorgb = false;
194194
bool rgbtogray = false;
195195
bool result = true;
196196
FrameBuffer frame;
197197
int xsample[3] = {1, 1, 1};
198198
char *buffer;
199-
int xstep;
200-
int ystep;
199+
size_t xstep = 0;
200+
size_t ystep = 0;
201201

202202
xstep = m_native_depth ? 4 : 1;
203203

@@ -589,7 +589,7 @@ bool ExrEncoder::write( const Mat& img, const vector<int>& )
589589
bool isfloat = depth == CV_32F || depth == CV_64F;
590590
depth = CV_ELEM_SIZE1(depth)*8;
591591
uchar* data = img.data;
592-
int step = img.step;
592+
size_t step = img.step;
593593

594594
Header header( width, height );
595595
Imf::PixelType type;
@@ -619,7 +619,7 @@ bool ExrEncoder::write( const Mat& img, const vector<int>& )
619619
FrameBuffer frame;
620620

621621
char *buffer;
622-
int bufferstep;
622+
size_t bufferstep;
623623
int size;
624624
if( type == FLOAT && depth == 32 )
625625
{

modules/highgui/src/grfmt_jpeg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
392392
bool JpegDecoder::readData( Mat& img )
393393
{
394394
bool result = false;
395-
int step = (int)img.step;
395+
size_t step = img.step;
396396
bool color = img.channels() > 1;
397397

398398
if( m_state && m_width && m_height )

modules/highgui/src/grfmt_jpeg2000.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ bool Jpeg2KDecoder::readData( Mat& img )
156156
bool result = false;
157157
int color = img.channels() > 1;
158158
uchar* data = img.data;
159-
int step = (int)img.step;
159+
size_t step = img.step;
160160
jas_stream_t* stream = (jas_stream_t*)m_stream;
161161
jas_image_t* image = (jas_image_t*)m_image;
162162

@@ -252,9 +252,9 @@ bool Jpeg2KDecoder::readData( Mat& img )
252252
if( !jas_image_readcmpt( image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer ))
253253
{
254254
if( img.depth() == CV_8U )
255-
result = readComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts );
255+
result = readComponent8u( data + i, buffer, validateToInt(step), cmptlut[i], maxval, offset, ncmpts );
256256
else
257-
result = readComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts );
257+
result = readComponent16u( ((unsigned short *)data) + i, buffer, validateToInt(step / 2), cmptlut[i], maxval, offset, ncmpts );
258258
if( !result )
259259
{
260260
i = ncmpts;

modules/highgui/src/grfmt_sunras.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ bool SunRasterDecoder::readData( Mat& img )
156156
{
157157
int color = img.channels() > 1;
158158
uchar* data = img.data;
159-
int step = (int)img.step;
159+
size_t step = img.step;
160160
uchar gray_palette[256];
161161
bool result = false;
162162
int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2;
@@ -304,11 +304,11 @@ bool SunRasterDecoder::readData( Mat& img )
304304
code = m_strm.getByte();
305305

306306
if( color )
307-
data = FillUniColor( data, line_end, step, width3,
307+
data = FillUniColor( data, line_end, validateToInt(step), width3,
308308
y, m_height, len,
309309
m_palette[code] );
310310
else
311-
data = FillUniGray( data, line_end, step, width3,
311+
data = FillUniGray( data, line_end, validateToInt(step), width3,
312312
y, m_height, len,
313313
gray_palette[code] );
314314
if( y >= m_height )

modules/highgui/src/utils.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
#include "precomp.hpp"
4343
#include "utils.hpp"
4444

45+
int validateToInt(size_t sz)
46+
{
47+
int valueInt = (int)sz;
48+
CV_Assert((size_t)valueInt == sz);
49+
return valueInt;
50+
}
51+
4552
#define SCALE 14
4653
#define cR (int)(0.299*(1 << SCALE) + 0.5)
4754
#define cG (int)(0.587*(1 << SCALE) + 0.5)
@@ -537,23 +544,25 @@ uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palett
537544
{
538545
uchar* end = data + len*3;
539546

547+
const PaletteEntry p0 = palette[0], p1 = palette[1];
548+
540549
while( (data += 24) < end )
541550
{
542551
int idx = *indices++;
543-
*((PaletteEntry*)(data - 24)) = palette[(idx & 128) != 0];
544-
*((PaletteEntry*)(data - 21)) = palette[(idx & 64) != 0];
545-
*((PaletteEntry*)(data - 18)) = palette[(idx & 32) != 0];
546-
*((PaletteEntry*)(data - 15)) = palette[(idx & 16) != 0];
547-
*((PaletteEntry*)(data - 12)) = palette[(idx & 8) != 0];
548-
*((PaletteEntry*)(data - 9)) = palette[(idx & 4) != 0];
549-
*((PaletteEntry*)(data - 6)) = palette[(idx & 2) != 0];
550-
*((PaletteEntry*)(data - 3)) = palette[(idx & 1) != 0];
552+
*((PaletteEntry*)(data - 24)) = (idx & 128) ? p1 : p0;
553+
*((PaletteEntry*)(data - 21)) = (idx & 64) ? p1 : p0;
554+
*((PaletteEntry*)(data - 18)) = (idx & 32) ? p1 : p0;
555+
*((PaletteEntry*)(data - 15)) = (idx & 16) ? p1 : p0;
556+
*((PaletteEntry*)(data - 12)) = (idx & 8) ? p1 : p0;
557+
*((PaletteEntry*)(data - 9)) = (idx & 4) ? p1 : p0;
558+
*((PaletteEntry*)(data - 6)) = (idx & 2) ? p1 : p0;
559+
*((PaletteEntry*)(data - 3)) = (idx & 1) ? p1 : p0;
551560
}
552561

553-
int idx = indices[0] << 24;
562+
int idx = indices[0];
554563
for( data -= 24; data < end; data += 3, idx += idx )
555564
{
556-
PaletteEntry clr = palette[idx < 0];
565+
const PaletteEntry clr = (idx & 128) ? p1 : p0;
557566
WRITE_PIX( data, clr );
558567
}
559568

@@ -565,23 +574,25 @@ uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
565574
{
566575
uchar* end = data + len;
567576

577+
const uchar p0 = palette[0], p1 = palette[1];
578+
568579
while( (data += 8) < end )
569580
{
570581
int idx = *indices++;
571-
*((uchar*)(data - 8)) = palette[(idx & 128) != 0];
572-
*((uchar*)(data - 7)) = palette[(idx & 64) != 0];
573-
*((uchar*)(data - 6)) = palette[(idx & 32) != 0];
574-
*((uchar*)(data - 5)) = palette[(idx & 16) != 0];
575-
*((uchar*)(data - 4)) = palette[(idx & 8) != 0];
576-
*((uchar*)(data - 3)) = palette[(idx & 4) != 0];
577-
*((uchar*)(data - 2)) = palette[(idx & 2) != 0];
578-
*((uchar*)(data - 1)) = palette[(idx & 1) != 0];
582+
*((uchar*)(data - 8)) = (idx & 128) ? p1 : p0;
583+
*((uchar*)(data - 7)) = (idx & 64) ? p1 : p0;
584+
*((uchar*)(data - 6)) = (idx & 32) ? p1 : p0;
585+
*((uchar*)(data - 5)) = (idx & 16) ? p1 : p0;
586+
*((uchar*)(data - 4)) = (idx & 8) ? p1 : p0;
587+
*((uchar*)(data - 3)) = (idx & 4) ? p1 : p0;
588+
*((uchar*)(data - 2)) = (idx & 2) ? p1 : p0;
589+
*((uchar*)(data - 1)) = (idx & 1) ? p1 : p0;
579590
}
580591

581-
int idx = indices[0] << 24;
592+
int idx = indices[0];
582593
for( data -= 8; data < end; data++, idx += idx )
583594
{
584-
data[0] = palette[idx < 0];
595+
data[0] = (idx & 128) ? p1 : p0;
585596
}
586597

587598
return data;

modules/highgui/src/utils.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#ifndef _UTILS_H_
4343
#define _UTILS_H_
4444

45+
int validateToInt(size_t step);
46+
4547
struct PaletteEntry
4648
{
4749
unsigned char b, g, r, a;

0 commit comments

Comments
 (0)