diff options
Diffstat (limited to 'src/3rdparty/libtiff/libtiff/tif_fax3.c')
-rw-r--r-- | src/3rdparty/libtiff/libtiff/tif_fax3.c | 114 |
1 files changed, 86 insertions, 28 deletions
diff --git a/src/3rdparty/libtiff/libtiff/tif_fax3.c b/src/3rdparty/libtiff/libtiff/tif_fax3.c index d11c968..9ab5b26 100644 --- a/src/3rdparty/libtiff/libtiff/tif_fax3.c +++ b/src/3rdparty/libtiff/libtiff/tif_fax3.c @@ -73,6 +73,7 @@ typedef struct { int EOLcnt; /* count of EOL codes recognized */ TIFFFaxFillFunc fill; /* fill routine */ uint32* runs; /* b&w runs for current/previous row */ + uint32 nruns; /* size of the refruns / curruns arrays */ uint32* refruns; /* runs for reference line */ uint32* curruns; /* runs for current line */ @@ -160,7 +161,9 @@ Fax3PreDecode(TIFF* tif, uint16 s) */ sp->bitmap = TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); + sp->curruns = sp->runs; if (sp->refruns) { /* init reference line to white */ + sp->refruns = sp->runs + sp->nruns; sp->refruns[0] = (uint32) sp->b.rowpixels; sp->refruns[1] = 0; } @@ -218,8 +221,12 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0) #define Nop -/* +/** * Decode the requested amount of G3 1D-encoded data. + * @param buf destination buffer + * @param occ available bytes in destination buffer + * @param s number of planes (ignored) + * @returns 1 for success, -1 in case of error */ static int Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) @@ -300,7 +307,9 @@ Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) else EXPAND2D(EOF2Da); (*sp->fill)(buf, thisrun, pa, lastx); - SETVALUE(0); /* imaginary change for reference */ + if (pa < thisrun + sp->nruns) { + SETVALUE(0); /* imaginary change for reference */ + } SWAP(uint32*, sp->curruns, sp->refruns); buf += sp->b.rowbytes; occ -= sp->b.rowbytes; @@ -506,7 +515,7 @@ Fax3SetupState(TIFF* tif) int needsRefLine; Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); tmsize_t rowbytes; - uint32 rowpixels, nruns; + uint32 rowpixels; if (td->td_bitspersample != 1) { TIFFErrorExt(tif->tif_clientdata, module, @@ -523,6 +532,13 @@ Fax3SetupState(TIFF* tif) rowbytes = TIFFScanlineSize(tif); rowpixels = td->td_imagewidth; } + if ((uint64)rowbytes < ((uint64)rowpixels + 7) / 8) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Inconsistent number of bytes per row : rowbytes=%lu rowpixels=%lu", + (unsigned long)(rowbytes), (unsigned long)(rowpixels)); + return (0); + } sp->rowbytes = rowbytes; sp->rowpixels = rowpixels; /* @@ -539,26 +555,26 @@ Fax3SetupState(TIFF* tif) TIFFroundup and TIFFSafeMultiply return zero on integer overflow */ dsp->runs=(uint32*) NULL; - nruns = TIFFroundup_32(rowpixels,32); + dsp->nruns = TIFFroundup_32(rowpixels,32); if (needsRefLine) { - nruns = TIFFSafeMultiply(uint32,nruns,2); + dsp->nruns = TIFFSafeMultiply(uint32,dsp->nruns,2); } - if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) { + if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32,dsp->nruns,2) == 0)) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Row pixels integer overflow (rowpixels %u)", rowpixels); return (0); } dsp->runs = (uint32*) _TIFFCheckMalloc(tif, - TIFFSafeMultiply(uint32,nruns,2), + TIFFSafeMultiply(uint32,dsp->nruns,2), sizeof (uint32), "for Group 3/4 run arrays"); if (dsp->runs == NULL) return (0); - memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32)); + memset( dsp->runs, 0, TIFFSafeMultiply(uint32,dsp->nruns,2)*sizeof(uint32)); dsp->curruns = dsp->runs; if (needsRefLine) - dsp->refruns = dsp->runs + nruns; + dsp->refruns = dsp->runs + dsp->nruns; else dsp->refruns = NULL; if (td->td_compression == COMPRESSION_CCITTFAX3 @@ -594,15 +610,19 @@ Fax3SetupState(TIFF* tif) */ #define Fax3FlushBits(tif, sp) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ - (void) TIFFFlushData1(tif); \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ + if( !TIFFFlushData1(tif) ) \ + return 0; \ + } \ *(tif)->tif_rawcp++ = (uint8) (sp)->data; \ (tif)->tif_rawcc++; \ (sp)->data = 0, (sp)->bit = 8; \ } #define _FlushBits(tif) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ - (void) TIFFFlushData1(tif); \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ + if( !TIFFFlushData1(tif) ) \ + return 0; \ + } \ *(tif)->tif_rawcp++ = (uint8) data; \ (tif)->tif_rawcc++; \ data = 0, bit = 8; \ @@ -627,7 +647,7 @@ static const int _msbmask[9] = * the output stream. Values are * assumed to be at most 16 bits. */ -static void +static int Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) { Fax3CodecState* sp = EncoderState(tif); @@ -638,6 +658,7 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) sp->data = data; sp->bit = bit; + return 1; } /* @@ -662,7 +683,7 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) * appropriate table that holds the make-up and * terminating codes is supplied. */ -static void +static int putspan(TIFF* tif, int32 span, const tableentry* tab) { Fax3CodecState* sp = EncoderState(tif); @@ -700,6 +721,8 @@ putspan(TIFF* tif, int32 span, const tableentry* tab) sp->data = data; sp->bit = bit; + + return 1; } /* @@ -708,7 +731,7 @@ putspan(TIFF* tif, int32 span, const tableentry* tab) * here. We also handle writing the tag bit for the next * scanline when doing 2d encoding. */ -static void +static int Fax3PutEOL(TIFF* tif) { Fax3CodecState* sp = EncoderState(tif); @@ -742,6 +765,8 @@ Fax3PutEOL(TIFF* tif) sp->data = data; sp->bit = bit; + + return 1; } /* @@ -991,12 +1016,14 @@ Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits) for (;;) { span = find0span(bp, bs, bits); /* white span */ - putspan(tif, span, TIFFFaxWhiteCodes); + if( !putspan(tif, span, TIFFFaxWhiteCodes) ) + return 0; bs += span; if (bs >= bits) break; span = find1span(bp, bs, bits); /* black span */ - putspan(tif, span, TIFFFaxBlackCodes); + if( !putspan(tif, span, TIFFFaxBlackCodes) ) + return 0; bs += span; if (bs >= bits) break; @@ -1048,21 +1075,28 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits) (b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF; if (!(-3 <= d && d <= 3)) { /* horizontal mode */ a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); - putcode(tif, &horizcode); + if( !putcode(tif, &horizcode) ) + return 0; if (a0+a1 == 0 || PIXEL(bp, a0) == 0) { - putspan(tif, a1-a0, TIFFFaxWhiteCodes); - putspan(tif, a2-a1, TIFFFaxBlackCodes); + if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) ) + return 0; + if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) ) + return 0; } else { - putspan(tif, a1-a0, TIFFFaxBlackCodes); - putspan(tif, a2-a1, TIFFFaxWhiteCodes); + if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) ) + return 0; + if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) ) + return 0; } a0 = a2; } else { /* vertical mode */ - putcode(tif, &vcodes[d+3]); + if( !putcode(tif, &vcodes[d+3]) ) + return 0; a0 = a1; } } else { /* pass mode */ - putcode(tif, &passcode); + if( !putcode(tif, &passcode) ) + return 0; a0 = b2; } if (a0 >= bits) @@ -1091,7 +1125,10 @@ Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) } while (cc > 0) { if ((sp->b.mode & FAXMODE_NOEOL) == 0) - Fax3PutEOL(tif); + { + if( !Fax3PutEOL(tif) ) + return 0; + } if (is2DEncoding(sp)) { if (sp->tag == G3_1D) { if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) @@ -1128,8 +1165,8 @@ Fax3PostEncode(TIFF* tif) return (1); } -static void -Fax3Close(TIFF* tif) +static int +_Fax3Close(TIFF* tif) { if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) { Fax3CodecState* sp = EncoderState(tif); @@ -1145,6 +1182,13 @@ Fax3Close(TIFF* tif) Fax3PutBits(tif, code, length); Fax3FlushBits(tif, sp); } + return 1; +} + +static void +Fax3Close(TIFF* tif) +{ + _Fax3Close(tif); } static void @@ -1453,6 +1497,13 @@ Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) EXPAND2D(EOFG4); if (EOLcnt) goto EOFG4; + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExt(tif->tif_clientdata, module, + "Buffer overrun detected : %d bytes available, %d bits needed", + (int)occ, lastx); + return -1; + } (*sp->fill)(buf, thisrun, pa, lastx); SETVALUE(0); /* imaginary change for reference */ SWAP(uint32*, sp->curruns, sp->refruns); @@ -1468,6 +1519,13 @@ Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) fputs( "Bad EOFB\n", stderr ); #endif ClrBits( 13 ); + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExt(tif->tif_clientdata, module, + "Buffer overrun detected : %d bytes available, %d bits needed", + (int)occ, lastx); + return -1; + } (*sp->fill)(buf, thisrun, pa, lastx); UNCACHE_STATE(tif, sp); return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */ |