diff options
Diffstat (limited to 'src/3rdparty/libtiff/libtiff/tif_ojpeg.c')
-rw-r--r-- | src/3rdparty/libtiff/libtiff/tif_ojpeg.c | 91 |
1 files changed, 71 insertions, 20 deletions
diff --git a/src/3rdparty/libtiff/libtiff/tif_ojpeg.c b/src/3rdparty/libtiff/libtiff/tif_ojpeg.c index 27385d8..bf0d1a2 100644 --- a/src/3rdparty/libtiff/libtiff/tif_ojpeg.c +++ b/src/3rdparty/libtiff/libtiff/tif_ojpeg.c @@ -243,6 +243,7 @@ typedef enum { typedef struct { TIFF* tif; int decoder_ok; + int error_in_raw_data_decoding; #ifndef LIBJPEG_ENCAP_EXTERNAL JMP_BUF exit_jmpbuf; #endif @@ -678,7 +679,7 @@ OJPEGPreDecode(TIFF* tif, uint16 s) if (OJPEGReadSecondarySos(tif,s)==0) return(0); } - if isTiled(tif) + if (isTiled(tif)) m=tif->tif_curtile; else m=tif->tif_curstrip; @@ -742,6 +743,7 @@ OJPEGPreDecodeSkipRaw(TIFF* tif) } m-=sp->subsampling_convert_clines-sp->subsampling_convert_state; sp->subsampling_convert_state=0; + sp->error_in_raw_data_decoding=0; } while (m>=sp->subsampling_convert_clines) { @@ -792,6 +794,10 @@ OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized"); return 0; } + if( sp->error_in_raw_data_decoding ) + { + return 0; + } if (sp->libjpeg_jpeg_query_style==0) { if (OJPEGDecodeRaw(tif,buf,cc)==0) @@ -831,8 +837,41 @@ OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc) { if (sp->subsampling_convert_state==0) { + const jpeg_decompress_struct* cinfo = &sp->libjpeg_jpeg_decompress_struct; + int width = 0; + int last_col_width = 0; + int jpeg_bytes; + int expected_bytes; + int i; + if (cinfo->MCUs_per_row == 0) + { + sp->error_in_raw_data_decoding = 1; + return 0; + } + for (i = 0; i < cinfo->comps_in_scan; ++i) + { + const jpeg_component_info* info = cinfo->cur_comp_info[i]; +#if JPEG_LIB_VERSION >= 70 + width += info->MCU_width * info->DCT_h_scaled_size; + last_col_width += info->last_col_width * info->DCT_h_scaled_size; +#else + width += info->MCU_width * info->DCT_scaled_size; + last_col_width += info->last_col_width * info->DCT_scaled_size; +#endif + } + jpeg_bytes = (cinfo->MCUs_per_row - 1) * width + last_col_width; + expected_bytes = sp->subsampling_convert_clinelenout * sp->subsampling_ver * sp->subsampling_hor; + if (jpeg_bytes != expected_bytes) + { + TIFFErrorExt(tif->tif_clientdata,module,"Inconsistent number of MCU in codestream"); + sp->error_in_raw_data_decoding = 1; + return(0); + } if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) + { + sp->error_in_raw_data_decoding = 1; return(0); + } } oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen; ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; @@ -990,7 +1029,6 @@ OJPEGSubsamplingCorrect(TIFF* tif) OJPEGState* sp=(OJPEGState*)tif->tif_data; uint8 mh; uint8 mv; - _TIFFFillStriles( tif ); assert(sp->subsamplingcorrect_done==0); if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && @@ -1046,7 +1084,7 @@ OJPEGReadHeaderInfo(TIFF* tif) assert(sp->readheader_done==0); sp->image_width=tif->tif_dir.td_imagewidth; sp->image_length=tif->tif_dir.td_imagelength; - if isTiled(tif) + if (isTiled(tif)) { sp->strile_width=tif->tif_dir.td_tilewidth; sp->strile_length=tif->tif_dir.td_tilelength; @@ -1082,6 +1120,12 @@ OJPEGReadHeaderInfo(TIFF* tif) } if (sp->strile_length<sp->image_length) { + if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || + ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) + { + TIFFErrorExt(tif->tif_clientdata,module,"Invalid subsampling values"); + return(0); + } if (sp->strile_length%(sp->subsampling_ver*8)!=0) { TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length"); @@ -1197,7 +1241,13 @@ OJPEGWriteHeaderInfo(TIFF* tif) sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines; sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines; sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen; - sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen); + /* The calloc is not normally necessary, except in some edge/broken cases */ + /* for example for a tiled image of height 1 with a tile height of 1 and subsampling_hor=subsampling_ver=2 */ + /* In that case, libjpeg will only fill the 8 first lines of the 16 lines */ + /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */ + /* Even if this case is allowed (?), its handling is broken because OJPEGPreDecode() should also likely */ + /* reset subsampling_convert_state to 0 when changing tile. */ + sp->subsampling_convert_ycbcrbuf=_TIFFcalloc(1, sp->subsampling_convert_ycbcrbuflen); if (sp->subsampling_convert_ycbcrbuf==0) { TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); @@ -1223,10 +1273,11 @@ OJPEGWriteHeaderInfo(TIFF* tif) *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen; for (n=0; n<sp->subsampling_convert_clines; n++) *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen; - sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor); + sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); sp->subsampling_convert_state=0; + sp->error_in_raw_data_decoding=0; sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2); - sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver); + sp->lines_per_strile=sp->strile_length/sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); sp->subsampling_convert_log=1; } } @@ -1272,7 +1323,9 @@ OJPEGReadHeaderInfoSec(TIFF* tif) } else { - if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) + if ((sp->jpeg_interchange_format_length==0) || + (sp->jpeg_interchange_format > TIFF_UINT64_MAX - sp->jpeg_interchange_format_length) || + (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format; } } @@ -1989,32 +2042,30 @@ OJPEGReadBufferFill(OJPEGState* sp) sp->in_buffer_source=osibsStrile; break; case osibsStrile: - if (!_TIFFFillStriles( sp->tif ) - || sp->tif->tif_dir.td_stripoffset == NULL - || sp->tif->tif_dir.td_stripbytecount == NULL) - return 0; - if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) sp->in_buffer_source=osibsEof; else { - sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile]; + int err = 0; + sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif, sp->in_buffer_next_strile, &err); + if( err ) + return 0; if (sp->in_buffer_file_pos!=0) { + uint64 bytecount = TIFFGetStrileByteCountWithErr(sp->tif, sp->in_buffer_next_strile, &err); + if( err ) + return 0; if (sp->in_buffer_file_pos>=sp->file_size) sp->in_buffer_file_pos=0; - else if (sp->tif->tif_dir.td_stripbytecount==NULL) + else if (bytecount==0) sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; else { - if (sp->tif->tif_dir.td_stripbytecount == 0) { - TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing"); - return(0); - } - sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; + sp->in_buffer_file_togo=bytecount; if (sp->in_buffer_file_togo==0) sp->in_buffer_file_pos=0; - else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) + else if (sp->in_buffer_file_pos > TIFF_UINT64_MAX - sp->in_buffer_file_togo || + sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; } } |