xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_read.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 /*
2  * Copyright (c) 1988-1997 Sam Leffler
3  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that (i) the above copyright notices and this permission notice appear in
8  * all copies of the software and related documentation, and (ii) the names of
9  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10  * publicity relating to the software without the specific, prior written
11  * permission of Sam Leffler and Silicon Graphics.
12  *
13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22  * OF THIS SOFTWARE.
23  */
24 
25 /*
26  * TIFF Library.
27  * Scanline-oriented Read Support
28  */
29 #include "tiffiop.h"
30 #include <stdio.h>
31 
32 int TIFFFillStrip(TIFF *tif, uint32_t strip);
33 int TIFFFillTile(TIFF *tif, uint32_t tile);
34 static int TIFFStartStrip(TIFF *tif, uint32_t strip);
35 static int TIFFStartTile(TIFF *tif, uint32_t tile);
36 static int TIFFCheckRead(TIFF *, int);
37 static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
38                                   tmsize_t size, const char *module);
39 static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
40                                  tmsize_t size, const char *module);
41 
42 #define NOSTRIP ((uint32_t)(-1)) /* undefined state */
43 #define NOTILE ((uint32_t)(-1))  /* undefined state */
44 
45 #define INITIAL_THRESHOLD (1024 * 1024)
46 #define THRESHOLD_MULTIPLIER 10
47 #define MAX_THRESHOLD                                                          \
48     (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER *      \
49      INITIAL_THRESHOLD)
50 
51 #define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
52 
53 /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
54  * Returns 1 in case of success, 0 otherwise. */
TIFFReadAndRealloc(TIFF * tif,tmsize_t size,tmsize_t rawdata_offset,int is_strip,uint32_t strip_or_tile,const char * module)55 static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
56                               int is_strip, uint32_t strip_or_tile,
57                               const char *module)
58 {
59 #if SIZEOF_SIZE_T == 8
60     tmsize_t threshold = INITIAL_THRESHOLD;
61 #endif
62     tmsize_t already_read = 0;
63 
64 #if SIZEOF_SIZE_T != 8
65     /* On 32 bit processes, if the request is large enough, check against */
66     /* file size */
67     if (size > 1000 * 1000 * 1000)
68     {
69         uint64_t filesize = TIFFGetFileSize(tif);
70         if ((uint64_t)size >= filesize)
71         {
72             TIFFErrorExtR(tif, module,
73                           "Chunk size requested is larger than file size.");
74             return 0;
75         }
76     }
77 #endif
78 
79     /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
80     /* so as to avoid allocating too much memory in case the file is too */
81     /* short. We could ask for the file size, but this might be */
82     /* expensive with some I/O layers (think of reading a gzipped file) */
83     /* Restrict to 64 bit processes, so as to avoid reallocs() */
84     /* on 32 bit processes where virtual memory is scarce.  */
85     while (already_read < size)
86     {
87         tmsize_t bytes_read;
88         tmsize_t to_read = size - already_read;
89 #if SIZEOF_SIZE_T == 8
90         if (to_read >= threshold && threshold < MAX_THRESHOLD &&
91             already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
92         {
93             to_read = threshold;
94             threshold *= THRESHOLD_MULTIPLIER;
95         }
96 #endif
97         if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
98         {
99             uint8_t *new_rawdata;
100             assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
101             tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
102                 (uint64_t)already_read + to_read + rawdata_offset, 1024);
103             if (tif->tif_rawdatasize == 0)
104             {
105                 TIFFErrorExtR(tif, module, "Invalid buffer size");
106                 return 0;
107             }
108             new_rawdata =
109                 (uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize);
110             if (new_rawdata == 0)
111             {
112                 TIFFErrorExtR(tif, module,
113                               "No space for data buffer at scanline %" PRIu32,
114                               tif->tif_row);
115                 _TIFFfreeExt(tif, tif->tif_rawdata);
116                 tif->tif_rawdata = 0;
117                 tif->tif_rawdatasize = 0;
118                 return 0;
119             }
120             tif->tif_rawdata = new_rawdata;
121         }
122         if (tif->tif_rawdata == NULL)
123         {
124             /* should not happen in practice but helps CoverityScan */
125             return 0;
126         }
127 
128         bytes_read = TIFFReadFile(
129             tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
130         already_read += bytes_read;
131         if (bytes_read != to_read)
132         {
133             memset(tif->tif_rawdata + rawdata_offset + already_read, 0,
134                    tif->tif_rawdatasize - rawdata_offset - already_read);
135             if (is_strip)
136             {
137                 TIFFErrorExtR(tif, module,
138                               "Read error at scanline %" PRIu32
139                               "; got %" TIFF_SSIZE_FORMAT " bytes, "
140                               "expected %" TIFF_SSIZE_FORMAT,
141                               tif->tif_row, already_read, size);
142             }
143             else
144             {
145                 TIFFErrorExtR(tif, module,
146                               "Read error at row %" PRIu32 ", col %" PRIu32
147                               ", tile %" PRIu32 "; "
148                               "got %" TIFF_SSIZE_FORMAT
149                               " bytes, expected %" TIFF_SSIZE_FORMAT "",
150                               tif->tif_row, tif->tif_col, strip_or_tile,
151                               already_read, size);
152             }
153             return 0;
154         }
155     }
156     return 1;
157 }
158 
TIFFFillStripPartial(TIFF * tif,int strip,tmsize_t read_ahead,int restart)159 static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
160                                 int restart)
161 {
162     static const char module[] = "TIFFFillStripPartial";
163     register TIFFDirectory *td = &tif->tif_dir;
164     tmsize_t unused_data;
165     uint64_t read_offset;
166     tmsize_t to_read;
167     tmsize_t read_ahead_mod;
168     /* tmsize_t bytecountm; */
169 
170     /*
171      * Expand raw data buffer, if needed, to hold data
172      * strip coming from file (perhaps should set upper
173      * bound on the size of a buffer we'll use?).
174      */
175 
176     /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
177 
178     /* Not completely sure where the * 2 comes from, but probably for */
179     /* an exponentional growth strategy of tif_rawdatasize */
180     if (read_ahead < TIFF_TMSIZE_T_MAX / 2)
181         read_ahead_mod = read_ahead * 2;
182     else
183         read_ahead_mod = read_ahead;
184     if (read_ahead_mod > tif->tif_rawdatasize)
185     {
186         assert(restart);
187 
188         tif->tif_curstrip = NOSTRIP;
189         if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
190         {
191             TIFFErrorExtR(tif, module,
192                           "Data buffer too small to hold part of strip %d",
193                           strip);
194             return (0);
195         }
196     }
197 
198     if (restart)
199     {
200         tif->tif_rawdataloaded = 0;
201         tif->tif_rawdataoff = 0;
202     }
203 
204     /*
205     ** If we are reading more data, move any unused data to the
206     ** start of the buffer.
207     */
208     if (tif->tif_rawdataloaded > 0)
209         unused_data =
210             tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
211     else
212         unused_data = 0;
213 
214     if (unused_data > 0)
215     {
216         assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
217         memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data);
218     }
219 
220     /*
221     ** Seek to the point in the file where more data should be read.
222     */
223     read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff +
224                   tif->tif_rawdataloaded;
225 
226     if (!SeekOK(tif, read_offset))
227     {
228         TIFFErrorExtR(tif, module,
229                       "Seek error at scanline %" PRIu32 ", strip %d",
230                       tif->tif_row, strip);
231         return 0;
232     }
233 
234     /*
235     ** How much do we want to read?
236     */
237     if (read_ahead_mod > tif->tif_rawdatasize)
238         to_read = read_ahead_mod - unused_data;
239     else
240         to_read = tif->tif_rawdatasize - unused_data;
241     if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) -
242                                 tif->tif_rawdataoff - tif->tif_rawdataloaded)
243     {
244         to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) -
245                   tif->tif_rawdataoff - tif->tif_rawdataloaded;
246     }
247 
248     assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
249     if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */
250                             0,                            /* strip_or_tile */
251                             module))
252     {
253         return 0;
254     }
255 
256     tif->tif_rawdataoff =
257         tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data;
258     tif->tif_rawdataloaded = unused_data + to_read;
259 
260     tif->tif_rawcc = tif->tif_rawdataloaded;
261     tif->tif_rawcp = tif->tif_rawdata;
262 
263     if (!isFillOrder(tif, td->td_fillorder) &&
264         (tif->tif_flags & TIFF_NOBITREV) == 0)
265     {
266         assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
267         TIFFReverseBits(tif->tif_rawdata + unused_data, to_read);
268     }
269 
270     /*
271     ** When starting a strip from the beginning we need to
272     ** restart the decoder.
273     */
274     if (restart)
275     {
276 
277 #ifdef JPEG_SUPPORT
278         /* A bit messy since breaks the codec abstraction. Ultimately */
279         /* there should be a function pointer for that, but it seems */
280         /* only JPEG is affected. */
281         /* For JPEG, if there are multiple scans (can generally be known */
282         /* with the  read_ahead used), we need to read the whole strip */
283         if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
284             (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip))
285         {
286             if (TIFFJPEGIsFullStripRequired(tif))
287             {
288                 return TIFFFillStrip(tif, strip);
289             }
290         }
291 #endif
292 
293         return TIFFStartStrip(tif, strip);
294     }
295     else
296     {
297         return 1;
298     }
299 }
300 
301 /*
302  * Seek to a random row+sample in a file.
303  *
304  * Only used by TIFFReadScanline, and is only used on
305  * strip organized files.  We do some tricky stuff to try
306  * and avoid reading the whole compressed raw data for big
307  * strips.
308  */
TIFFSeek(TIFF * tif,uint32_t row,uint16_t sample)309 static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
310 {
311     register TIFFDirectory *td = &tif->tif_dir;
312     uint32_t strip;
313     int whole_strip;
314     tmsize_t read_ahead = 0;
315 
316     /*
317     ** Establish what strip we are working from.
318     */
319     if (row >= td->td_imagelength)
320     { /* out of range */
321         TIFFErrorExtR(tif, tif->tif_name,
322                       "%" PRIu32 ": Row out of range, max %" PRIu32 "", row,
323                       td->td_imagelength);
324         return (0);
325     }
326     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
327     {
328         if (sample >= td->td_samplesperpixel)
329         {
330             TIFFErrorExtR(tif, tif->tif_name,
331                           "%" PRIu16 ": Sample out of range, max %" PRIu16 "",
332                           sample, td->td_samplesperpixel);
333             return (0);
334         }
335         strip = (uint32_t)sample * td->td_stripsperimage +
336                 row / td->td_rowsperstrip;
337     }
338     else
339         strip = row / td->td_rowsperstrip;
340 
341         /*
342          * Do we want to treat this strip as one whole chunk or
343          * read it a few lines at a time?
344          */
345 #if defined(CHUNKY_STRIP_READ_SUPPORT)
346     whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
347     if (td->td_compression == COMPRESSION_LERC ||
348         td->td_compression == COMPRESSION_JBIG)
349     {
350         /* Ideally plugins should have a way to declare they don't support
351          * chunk strip */
352         whole_strip = 1;
353     }
354 #else
355     whole_strip = 1;
356 #endif
357 
358     if (!whole_strip)
359     {
360         /* 16 is for YCbCr mode where we may need to read 16 */
361         /* lines at a time to get a decompressed line, and 5000 */
362         /* is some constant value, for example for JPEG tables */
363         if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
364             tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
365         {
366             read_ahead = tif->tif_scanlinesize * 16 + 5000;
367         }
368         else
369         {
370             read_ahead = tif->tif_scanlinesize;
371         }
372     }
373 
374     /*
375      * If we haven't loaded this strip, do so now, possibly
376      * only reading the first part.
377      */
378     if (strip != tif->tif_curstrip)
379     { /* different strip, refill */
380 
381         if (whole_strip)
382         {
383             if (!TIFFFillStrip(tif, strip))
384                 return (0);
385         }
386         else
387         {
388             if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
389                 return 0;
390         }
391     }
392 
393     /*
394     ** If we already have some data loaded, do we need to read some more?
395     */
396     else if (!whole_strip)
397     {
398         if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) <
399                 read_ahead &&
400             (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded <
401                 TIFFGetStrileByteCount(tif, strip))
402         {
403             if (!TIFFFillStripPartial(tif, strip, read_ahead, 0))
404                 return 0;
405         }
406     }
407 
408     if (row < tif->tif_row)
409     {
410         /*
411          * Moving backwards within the same strip: backup
412          * to the start and then decode forward (below).
413          *
414          * NB: If you're planning on lots of random access within a
415          * strip, it's better to just read and decode the entire
416          * strip, and then access the decoded data in a random fashion.
417          */
418 
419         if (tif->tif_rawdataoff != 0)
420         {
421             if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
422                 return 0;
423         }
424         else
425         {
426             if (!TIFFStartStrip(tif, strip))
427                 return (0);
428         }
429     }
430 
431     if (row != tif->tif_row)
432     {
433         /*
434          * Seek forward to the desired row.
435          */
436 
437         /* TODO: Will this really work with partial buffers? */
438 
439         if (!(*tif->tif_seek)(tif, row - tif->tif_row))
440             return (0);
441         tif->tif_row = row;
442     }
443 
444     return (1);
445 }
446 
TIFFReadScanline(TIFF * tif,void * buf,uint32_t row,uint16_t sample)447 int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
448 {
449     int e;
450 
451     if (!TIFFCheckRead(tif, 0))
452         return (-1);
453     if ((e = TIFFSeek(tif, row, sample)) != 0)
454     {
455         /*
456          * Decompress desired row into user buffer.
457          */
458         e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
459                                   sample);
460 
461         /* we are now poised at the beginning of the next row */
462         tif->tif_row = row + 1;
463 
464         if (e)
465             (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
466     }
467     return (e > 0 ? 1 : -1);
468 }
469 
470 /*
471  * Calculate the strip size according to the number of
472  * rows in the strip (check for truncated last strip on any
473  * of the separations).
474  */
TIFFReadEncodedStripGetStripSize(TIFF * tif,uint32_t strip,uint16_t * pplane)475 static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
476                                                  uint16_t *pplane)
477 {
478     static const char module[] = "TIFFReadEncodedStrip";
479     TIFFDirectory *td = &tif->tif_dir;
480     uint32_t rowsperstrip;
481     uint32_t stripsperplane;
482     uint32_t stripinplane;
483     uint32_t rows;
484     tmsize_t stripsize;
485     if (!TIFFCheckRead(tif, 0))
486         return ((tmsize_t)(-1));
487     if (strip >= td->td_nstrips)
488     {
489         TIFFErrorExtR(tif, module,
490                       "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
491                       td->td_nstrips);
492         return ((tmsize_t)(-1));
493     }
494 
495     rowsperstrip = td->td_rowsperstrip;
496     if (rowsperstrip > td->td_imagelength)
497         rowsperstrip = td->td_imagelength;
498     stripsperplane =
499         TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
500     stripinplane = (strip % stripsperplane);
501     if (pplane)
502         *pplane = (uint16_t)(strip / stripsperplane);
503     rows = td->td_imagelength - stripinplane * rowsperstrip;
504     if (rows > rowsperstrip)
505         rows = rowsperstrip;
506     stripsize = TIFFVStripSize(tif, rows);
507     if (stripsize == 0)
508         return ((tmsize_t)(-1));
509     return stripsize;
510 }
511 
512 /*
513  * Read a strip of data and decompress the specified
514  * amount into the user-supplied buffer.
515  */
TIFFReadEncodedStrip(TIFF * tif,uint32_t strip,void * buf,tmsize_t size)516 tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
517                               tmsize_t size)
518 {
519     static const char module[] = "TIFFReadEncodedStrip";
520     TIFFDirectory *td = &tif->tif_dir;
521     tmsize_t stripsize;
522     uint16_t plane;
523 
524     stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
525     if (stripsize == ((tmsize_t)(-1)))
526         return ((tmsize_t)(-1));
527 
528     /* shortcut to avoid an extra memcpy() */
529     if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
530         size >= stripsize && !isMapped(tif) &&
531         ((tif->tif_flags & TIFF_NOREADRAW) == 0))
532     {
533         if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
534             return ((tmsize_t)(-1));
535 
536         if (!isFillOrder(tif, td->td_fillorder) &&
537             (tif->tif_flags & TIFF_NOBITREV) == 0)
538             TIFFReverseBits(buf, stripsize);
539 
540         (*tif->tif_postdecode)(tif, buf, stripsize);
541         return (stripsize);
542     }
543 
544     if ((size != (tmsize_t)(-1)) && (size < stripsize))
545         stripsize = size;
546     if (!TIFFFillStrip(tif, strip))
547         return ((tmsize_t)(-1));
548     if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
549         return ((tmsize_t)(-1));
550     (*tif->tif_postdecode)(tif, buf, stripsize);
551     return (stripsize);
552 }
553 
554 /* Variant of TIFFReadEncodedStrip() that does
555  * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
556  * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case
557  * of truncated file.
558  * * calls regular TIFFReadEncodedStrip() if *buf != NULL
559  */
_TIFFReadEncodedStripAndAllocBuffer(TIFF * tif,uint32_t strip,void ** buf,tmsize_t bufsizetoalloc,tmsize_t size_to_read)560 tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
561                                              void **buf,
562                                              tmsize_t bufsizetoalloc,
563                                              tmsize_t size_to_read)
564 {
565     tmsize_t this_stripsize;
566     uint16_t plane;
567 
568     if (*buf != NULL)
569     {
570         return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
571     }
572 
573     this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
574     if (this_stripsize == ((tmsize_t)(-1)))
575         return ((tmsize_t)(-1));
576 
577     if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize))
578         this_stripsize = size_to_read;
579     if (!TIFFFillStrip(tif, strip))
580         return ((tmsize_t)(-1));
581 
582     *buf = _TIFFmallocExt(tif, bufsizetoalloc);
583     if (*buf == NULL)
584     {
585         TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
586         return ((tmsize_t)(-1));
587     }
588     _TIFFmemset(*buf, 0, bufsizetoalloc);
589 
590     if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
591         return ((tmsize_t)(-1));
592     (*tif->tif_postdecode)(tif, *buf, this_stripsize);
593     return (this_stripsize);
594 }
595 
TIFFReadRawStrip1(TIFF * tif,uint32_t strip,void * buf,tmsize_t size,const char * module)596 static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
597                                   tmsize_t size, const char *module)
598 {
599     assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
600     if (!isMapped(tif))
601     {
602         tmsize_t cc;
603 
604         if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip)))
605         {
606             TIFFErrorExtR(tif, module,
607                           "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
608                           tif->tif_row, strip);
609             return ((tmsize_t)(-1));
610         }
611         cc = TIFFReadFile(tif, buf, size);
612         if (cc != size)
613         {
614             TIFFErrorExtR(tif, module,
615                           "Read error at scanline %" PRIu32
616                           "; got %" TIFF_SSIZE_FORMAT
617                           " bytes, expected %" TIFF_SSIZE_FORMAT,
618                           tif->tif_row, cc, size);
619             return ((tmsize_t)(-1));
620         }
621     }
622     else
623     {
624         tmsize_t ma = 0;
625         tmsize_t n;
626         if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
627             ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size))
628         {
629             n = 0;
630         }
631         else if (ma > TIFF_TMSIZE_T_MAX - size)
632         {
633             n = 0;
634         }
635         else
636         {
637             tmsize_t mb = ma + size;
638             if (mb > tif->tif_size)
639                 n = tif->tif_size - ma;
640             else
641                 n = size;
642         }
643         if (n != size)
644         {
645             TIFFErrorExtR(tif, module,
646                           "Read error at scanline %" PRIu32 ", strip %" PRIu32
647                           "; got %" TIFF_SSIZE_FORMAT
648                           " bytes, expected %" TIFF_SSIZE_FORMAT,
649                           tif->tif_row, strip, n, size);
650             return ((tmsize_t)(-1));
651         }
652         _TIFFmemcpy(buf, tif->tif_base + ma, size);
653     }
654     return (size);
655 }
656 
TIFFReadRawStripOrTile2(TIFF * tif,uint32_t strip_or_tile,int is_strip,tmsize_t size,const char * module)657 static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
658                                         int is_strip, tmsize_t size,
659                                         const char *module)
660 {
661     assert(!isMapped(tif));
662     assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
663 
664     if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile)))
665     {
666         if (is_strip)
667         {
668             TIFFErrorExtR(tif, module,
669                           "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
670                           tif->tif_row, strip_or_tile);
671         }
672         else
673         {
674             TIFFErrorExtR(tif, module,
675                           "Seek error at row %" PRIu32 ", col %" PRIu32
676                           ", tile %" PRIu32,
677                           tif->tif_row, tif->tif_col, strip_or_tile);
678         }
679         return ((tmsize_t)(-1));
680     }
681 
682     if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module))
683     {
684         return ((tmsize_t)(-1));
685     }
686 
687     return (size);
688 }
689 
690 /*
691  * Read a strip of data from the file.
692  */
TIFFReadRawStrip(TIFF * tif,uint32_t strip,void * buf,tmsize_t size)693 tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size)
694 {
695     static const char module[] = "TIFFReadRawStrip";
696     TIFFDirectory *td = &tif->tif_dir;
697     uint64_t bytecount64;
698     tmsize_t bytecountm;
699 
700     if (!TIFFCheckRead(tif, 0))
701         return ((tmsize_t)(-1));
702     if (strip >= td->td_nstrips)
703     {
704         TIFFErrorExtR(tif, module,
705                       "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
706                       td->td_nstrips);
707         return ((tmsize_t)(-1));
708     }
709     if (tif->tif_flags & TIFF_NOREADRAW)
710     {
711         TIFFErrorExtR(tif, module,
712                       "Compression scheme does not support access to raw "
713                       "uncompressed data");
714         return ((tmsize_t)(-1));
715     }
716     bytecount64 = TIFFGetStrileByteCount(tif, strip);
717     if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
718         bytecountm = size;
719     else
720         bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
721     if (bytecountm == 0)
722     {
723         return ((tmsize_t)(-1));
724     }
725     return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
726 }
727 
728 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
NoSanitizeSubUInt64(uint64_t a,uint64_t b)729 static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; }
730 
731 /*
732  * Read the specified strip and setup for decoding. The data buffer is
733  * expanded, as necessary, to hold the strip's data.
734  */
TIFFFillStrip(TIFF * tif,uint32_t strip)735 int TIFFFillStrip(TIFF *tif, uint32_t strip)
736 {
737     static const char module[] = "TIFFFillStrip";
738     TIFFDirectory *td = &tif->tif_dir;
739 
740     if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
741     {
742         uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
743         if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
744         {
745             TIFFErrorExtR(tif, module,
746                           "Invalid strip byte count %" PRIu64
747                           ", strip %" PRIu32,
748                           bytecount, strip);
749             return (0);
750         }
751 
752         /* To avoid excessive memory allocations: */
753         /* Byte count should normally not be larger than a number of */
754         /* times the uncompressed size plus some margin */
755         if (bytecount > 1024 * 1024)
756         {
757             /* 10 and 4096 are just values that could be adjusted. */
758             /* Hopefully they are safe enough for all codecs */
759             tmsize_t stripsize = TIFFStripSize(tif);
760             if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
761             {
762                 uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
763                 TIFFErrorExtR(tif, module,
764                               "Too large strip byte count %" PRIu64
765                               ", strip %" PRIu32 ". Limiting to %" PRIu64,
766                               bytecount, strip, newbytecount);
767                 bytecount = newbytecount;
768             }
769         }
770 
771         if (isMapped(tif))
772         {
773             /*
774              * We must check for overflow, potentially causing
775              * an OOB read. Instead of simple
776              *
777              *  TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
778              *
779              * comparison (which can overflow) we do the following
780              * two comparisons:
781              */
782             if (bytecount > (uint64_t)tif->tif_size ||
783                 TIFFGetStrileOffset(tif, strip) >
784                     (uint64_t)tif->tif_size - bytecount)
785             {
786                 /*
787                  * This error message might seem strange, but
788                  * it's what would happen if a read were done
789                  * instead.
790                  */
791                 TIFFErrorExtR(
792                     tif, module,
793 
794                     "Read error on strip %" PRIu32 "; "
795                     "got %" PRIu64 " bytes, expected %" PRIu64,
796                     strip,
797                     NoSanitizeSubUInt64(tif->tif_size,
798                                         TIFFGetStrileOffset(tif, strip)),
799                     bytecount);
800                 tif->tif_curstrip = NOSTRIP;
801                 return (0);
802             }
803         }
804 
805         if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
806                               (tif->tif_flags & TIFF_NOBITREV)))
807         {
808             /*
809              * The image is mapped into memory and we either don't
810              * need to flip bits or the compression routine is
811              * going to handle this operation itself.  In this
812              * case, avoid copying the raw data and instead just
813              * reference the data from the memory mapped file
814              * image.  This assumes that the decompression
815              * routines do not modify the contents of the raw data
816              * buffer (if they try to, the application will get a
817              * fault since the file is mapped read-only).
818              */
819             if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
820             {
821                 _TIFFfreeExt(tif, tif->tif_rawdata);
822                 tif->tif_rawdata = NULL;
823                 tif->tif_rawdatasize = 0;
824             }
825             tif->tif_flags &= ~TIFF_MYBUFFER;
826             tif->tif_rawdatasize = (tmsize_t)bytecount;
827             tif->tif_rawdata =
828                 tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
829             tif->tif_rawdataoff = 0;
830             tif->tif_rawdataloaded = (tmsize_t)bytecount;
831 
832             /*
833              * When we have tif_rawdata reference directly into the memory
834              * mapped file we need to be pretty careful about how we use the
835              * rawdata.  It is not a general purpose working buffer as it
836              * normally otherwise is.  So we keep track of this fact to avoid
837              * using it improperly.
838              */
839             tif->tif_flags |= TIFF_BUFFERMMAP;
840         }
841         else
842         {
843             /*
844              * Expand raw data buffer, if needed, to hold data
845              * strip coming from file (perhaps should set upper
846              * bound on the size of a buffer we'll use?).
847              */
848             tmsize_t bytecountm;
849             bytecountm = (tmsize_t)bytecount;
850             if ((uint64_t)bytecountm != bytecount)
851             {
852                 TIFFErrorExtR(tif, module, "Integer overflow");
853                 return (0);
854             }
855             if (bytecountm > tif->tif_rawdatasize)
856             {
857                 tif->tif_curstrip = NOSTRIP;
858                 if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
859                 {
860                     TIFFErrorExtR(
861                         tif, module,
862                         "Data buffer too small to hold strip %" PRIu32, strip);
863                     return (0);
864                 }
865             }
866             if (tif->tif_flags & TIFF_BUFFERMMAP)
867             {
868                 tif->tif_curstrip = NOSTRIP;
869                 tif->tif_rawdata = NULL;
870                 tif->tif_rawdatasize = 0;
871                 tif->tif_flags &= ~TIFF_BUFFERMMAP;
872             }
873 
874             if (isMapped(tif))
875             {
876                 if (bytecountm > tif->tif_rawdatasize &&
877                     !TIFFReadBufferSetup(tif, 0, bytecountm))
878                 {
879                     return (0);
880                 }
881                 if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm,
882                                       module) != bytecountm)
883                 {
884                     return (0);
885                 }
886             }
887             else
888             {
889                 if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm,
890                                             module) != bytecountm)
891                 {
892                     return (0);
893                 }
894             }
895 
896             tif->tif_rawdataoff = 0;
897             tif->tif_rawdataloaded = bytecountm;
898 
899             if (!isFillOrder(tif, td->td_fillorder) &&
900                 (tif->tif_flags & TIFF_NOBITREV) == 0)
901                 TIFFReverseBits(tif->tif_rawdata, bytecountm);
902         }
903     }
904     return (TIFFStartStrip(tif, strip));
905 }
906 
907 /*
908  * Tile-oriented Read Support
909  * Contributed by Nancy Cam (Silicon Graphics).
910  */
911 
912 /*
913  * Read and decompress a tile of data.  The
914  * tile is selected by the (x,y,z,s) coordinates.
915  */
TIFFReadTile(TIFF * tif,void * buf,uint32_t x,uint32_t y,uint32_t z,uint16_t s)916 tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
917                       uint16_t s)
918 {
919     if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
920         return ((tmsize_t)(-1));
921     return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
922                                 (tmsize_t)(-1)));
923 }
924 
925 /*
926  * Read a tile of data and decompress the specified
927  * amount into the user-supplied buffer.
928  */
TIFFReadEncodedTile(TIFF * tif,uint32_t tile,void * buf,tmsize_t size)929 tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
930 {
931     static const char module[] = "TIFFReadEncodedTile";
932     TIFFDirectory *td = &tif->tif_dir;
933     tmsize_t tilesize = tif->tif_tilesize;
934 
935     if (!TIFFCheckRead(tif, 1))
936         return ((tmsize_t)(-1));
937     if (tile >= td->td_nstrips)
938     {
939         TIFFErrorExtR(tif, module,
940                       "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
941                       td->td_nstrips);
942         return ((tmsize_t)(-1));
943     }
944 
945     /* shortcut to avoid an extra memcpy() */
946     if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
947         size >= tilesize && !isMapped(tif) &&
948         ((tif->tif_flags & TIFF_NOREADRAW) == 0))
949     {
950         if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
951             return ((tmsize_t)(-1));
952 
953         if (!isFillOrder(tif, td->td_fillorder) &&
954             (tif->tif_flags & TIFF_NOBITREV) == 0)
955             TIFFReverseBits(buf, tilesize);
956 
957         (*tif->tif_postdecode)(tif, buf, tilesize);
958         return (tilesize);
959     }
960 
961     if (size == (tmsize_t)(-1))
962         size = tilesize;
963     else if (size > tilesize)
964         size = tilesize;
965     if (TIFFFillTile(tif, tile) &&
966         (*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
967                                (uint16_t)(tile / td->td_stripsperimage)))
968     {
969         (*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
970         return (size);
971     }
972     else
973         return ((tmsize_t)(-1));
974 }
975 
976 /* Variant of TIFFReadTile() that does
977  * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
978  * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
979  * of truncated file.
980  * * calls regular TIFFReadEncodedTile() if *buf != NULL
981  */
_TIFFReadTileAndAllocBuffer(TIFF * tif,void ** buf,tmsize_t bufsizetoalloc,uint32_t x,uint32_t y,uint32_t z,uint16_t s)982 tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
983                                      tmsize_t bufsizetoalloc, uint32_t x,
984                                      uint32_t y, uint32_t z, uint16_t s)
985 {
986     if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
987         return ((tmsize_t)(-1));
988     return (_TIFFReadEncodedTileAndAllocBuffer(
989         tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc,
990         (tmsize_t)(-1)));
991 }
992 
993 /* Variant of TIFFReadEncodedTile() that does
994  * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
995  * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
996  * of truncated file.
997  * * calls regular TIFFReadEncodedTile() if *buf != NULL
998  */
_TIFFReadEncodedTileAndAllocBuffer(TIFF * tif,uint32_t tile,void ** buf,tmsize_t bufsizetoalloc,tmsize_t size_to_read)999 tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
1000                                             void **buf, tmsize_t bufsizetoalloc,
1001                                             tmsize_t size_to_read)
1002 {
1003     static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
1004     TIFFDirectory *td = &tif->tif_dir;
1005     tmsize_t tilesize = tif->tif_tilesize;
1006 
1007     if (*buf != NULL)
1008     {
1009         return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
1010     }
1011 
1012     if (!TIFFCheckRead(tif, 1))
1013         return ((tmsize_t)(-1));
1014     if (tile >= td->td_nstrips)
1015     {
1016         TIFFErrorExtR(tif, module,
1017                       "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1018                       td->td_nstrips);
1019         return ((tmsize_t)(-1));
1020     }
1021 
1022     if (!TIFFFillTile(tif, tile))
1023         return ((tmsize_t)(-1));
1024 
1025     /* Sanity checks to avoid excessive memory allocation */
1026     /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */
1027     if (td->td_compression == COMPRESSION_NONE)
1028     {
1029         if (tif->tif_rawdatasize != tilesize)
1030         {
1031             TIFFErrorExtR(tif, TIFFFileName(tif),
1032                           "Invalid tile byte count for tile %u. "
1033                           "Expected %" PRIu64 ", got %" PRIu64,
1034                           tile, (uint64_t)tilesize,
1035                           (uint64_t)tif->tif_rawdatasize);
1036             return ((tmsize_t)(-1));
1037         }
1038     }
1039     else
1040     {
1041         /* Max compression ratio experimentally determined. Might be fragile...
1042          * Only apply this heuristics to situations where the memory allocation
1043          * would be big, to avoid breaking nominal use cases.
1044          */
1045         const int maxCompressionRatio =
1046             td->td_compression == COMPRESSION_ZSTD ? 33000
1047             : td->td_compression == COMPRESSION_JXL
1048                 ?
1049                 /* Evaluated on a 8000x8000 tile */
1050                 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
1051                              ? td->td_samplesperpixel
1052                              : 1)
1053                 : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
1054         if (bufsizetoalloc > 100 * 1000 * 1000 &&
1055             tif->tif_rawdatasize < tilesize / maxCompressionRatio)
1056         {
1057             TIFFErrorExtR(tif, TIFFFileName(tif),
1058                           "Likely invalid tile byte count for tile %u. "
1059                           "Uncompressed tile size is %" PRIu64 ", "
1060                           "compressed one is %" PRIu64,
1061                           tile, (uint64_t)tilesize,
1062                           (uint64_t)tif->tif_rawdatasize);
1063             return ((tmsize_t)(-1));
1064         }
1065     }
1066 
1067     *buf = _TIFFmallocExt(tif, bufsizetoalloc);
1068     if (*buf == NULL)
1069     {
1070         TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
1071         return ((tmsize_t)(-1));
1072     }
1073     _TIFFmemset(*buf, 0, bufsizetoalloc);
1074 
1075     if (size_to_read == (tmsize_t)(-1))
1076         size_to_read = tilesize;
1077     else if (size_to_read > tilesize)
1078         size_to_read = tilesize;
1079     if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read,
1080                                (uint16_t)(tile / td->td_stripsperimage)))
1081     {
1082         (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read);
1083         return (size_to_read);
1084     }
1085     else
1086         return ((tmsize_t)(-1));
1087 }
1088 
TIFFReadRawTile1(TIFF * tif,uint32_t tile,void * buf,tmsize_t size,const char * module)1089 static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
1090                                  tmsize_t size, const char *module)
1091 {
1092     assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1093     if (!isMapped(tif))
1094     {
1095         tmsize_t cc;
1096 
1097         if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile)))
1098         {
1099             TIFFErrorExtR(tif, module,
1100                           "Seek error at row %" PRIu32 ", col %" PRIu32
1101                           ", tile %" PRIu32,
1102                           tif->tif_row, tif->tif_col, tile);
1103             return ((tmsize_t)(-1));
1104         }
1105         cc = TIFFReadFile(tif, buf, size);
1106         if (cc != size)
1107         {
1108             TIFFErrorExtR(tif, module,
1109                           "Read error at row %" PRIu32 ", col %" PRIu32
1110                           "; got %" TIFF_SSIZE_FORMAT
1111                           " bytes, expected %" TIFF_SSIZE_FORMAT,
1112                           tif->tif_row, tif->tif_col, cc, size);
1113             return ((tmsize_t)(-1));
1114         }
1115     }
1116     else
1117     {
1118         tmsize_t ma, mb;
1119         tmsize_t n;
1120         ma = (tmsize_t)TIFFGetStrileOffset(tif, tile);
1121         mb = ma + size;
1122         if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
1123             (ma > tif->tif_size))
1124             n = 0;
1125         else if ((mb < ma) || (mb < size) || (mb > tif->tif_size))
1126             n = tif->tif_size - ma;
1127         else
1128             n = size;
1129         if (n != size)
1130         {
1131             TIFFErrorExtR(tif, module,
1132                           "Read error at row %" PRIu32 ", col %" PRIu32
1133                           ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
1134                           " bytes, expected %" TIFF_SSIZE_FORMAT,
1135                           tif->tif_row, tif->tif_col, tile, n, size);
1136             return ((tmsize_t)(-1));
1137         }
1138         _TIFFmemcpy(buf, tif->tif_base + ma, size);
1139     }
1140     return (size);
1141 }
1142 
1143 /*
1144  * Read a tile of data from the file.
1145  */
TIFFReadRawTile(TIFF * tif,uint32_t tile,void * buf,tmsize_t size)1146 tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
1147 {
1148     static const char module[] = "TIFFReadRawTile";
1149     TIFFDirectory *td = &tif->tif_dir;
1150     uint64_t bytecount64;
1151     tmsize_t bytecountm;
1152 
1153     if (!TIFFCheckRead(tif, 1))
1154         return ((tmsize_t)(-1));
1155     if (tile >= td->td_nstrips)
1156     {
1157         TIFFErrorExtR(tif, module,
1158                       "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1159                       td->td_nstrips);
1160         return ((tmsize_t)(-1));
1161     }
1162     if (tif->tif_flags & TIFF_NOREADRAW)
1163     {
1164         TIFFErrorExtR(tif, module,
1165                       "Compression scheme does not support access to raw "
1166                       "uncompressed data");
1167         return ((tmsize_t)(-1));
1168     }
1169     bytecount64 = TIFFGetStrileByteCount(tif, tile);
1170     if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
1171         bytecountm = size;
1172     else
1173         bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
1174     if (bytecountm == 0)
1175     {
1176         return ((tmsize_t)(-1));
1177     }
1178     return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
1179 }
1180 
1181 /*
1182  * Read the specified tile and setup for decoding. The data buffer is
1183  * expanded, as necessary, to hold the tile's data.
1184  */
TIFFFillTile(TIFF * tif,uint32_t tile)1185 int TIFFFillTile(TIFF *tif, uint32_t tile)
1186 {
1187     static const char module[] = "TIFFFillTile";
1188     TIFFDirectory *td = &tif->tif_dir;
1189 
1190     if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
1191     {
1192         uint64_t bytecount = TIFFGetStrileByteCount(tif, tile);
1193         if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
1194         {
1195             TIFFErrorExtR(tif, module,
1196                           "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32,
1197                           bytecount, tile);
1198             return (0);
1199         }
1200 
1201         /* To avoid excessive memory allocations: */
1202         /* Byte count should normally not be larger than a number of */
1203         /* times the uncompressed size plus some margin */
1204         if (bytecount > 1024 * 1024)
1205         {
1206             /* 10 and 4096 are just values that could be adjusted. */
1207             /* Hopefully they are safe enough for all codecs */
1208             tmsize_t stripsize = TIFFTileSize(tif);
1209             if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
1210             {
1211                 uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
1212                 TIFFErrorExtR(tif, module,
1213                               "Too large tile byte count %" PRIu64
1214                               ", tile %" PRIu32 ". Limiting to %" PRIu64,
1215                               bytecount, tile, newbytecount);
1216                 bytecount = newbytecount;
1217             }
1218         }
1219 
1220         if (isMapped(tif))
1221         {
1222             /*
1223              * We must check for overflow, potentially causing
1224              * an OOB read. Instead of simple
1225              *
1226              *  TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
1227              *
1228              * comparison (which can overflow) we do the following
1229              * two comparisons:
1230              */
1231             if (bytecount > (uint64_t)tif->tif_size ||
1232                 TIFFGetStrileOffset(tif, tile) >
1233                     (uint64_t)tif->tif_size - bytecount)
1234             {
1235                 tif->tif_curtile = NOTILE;
1236                 return (0);
1237             }
1238         }
1239 
1240         if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
1241                               (tif->tif_flags & TIFF_NOBITREV)))
1242         {
1243             /*
1244              * The image is mapped into memory and we either don't
1245              * need to flip bits or the compression routine is
1246              * going to handle this operation itself.  In this
1247              * case, avoid copying the raw data and instead just
1248              * reference the data from the memory mapped file
1249              * image.  This assumes that the decompression
1250              * routines do not modify the contents of the raw data
1251              * buffer (if they try to, the application will get a
1252              * fault since the file is mapped read-only).
1253              */
1254             if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
1255             {
1256                 _TIFFfreeExt(tif, tif->tif_rawdata);
1257                 tif->tif_rawdata = NULL;
1258                 tif->tif_rawdatasize = 0;
1259             }
1260             tif->tif_flags &= ~TIFF_MYBUFFER;
1261 
1262             tif->tif_rawdatasize = (tmsize_t)bytecount;
1263             tif->tif_rawdata =
1264                 tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
1265             tif->tif_rawdataoff = 0;
1266             tif->tif_rawdataloaded = (tmsize_t)bytecount;
1267             tif->tif_flags |= TIFF_BUFFERMMAP;
1268         }
1269         else
1270         {
1271             /*
1272              * Expand raw data buffer, if needed, to hold data
1273              * tile coming from file (perhaps should set upper
1274              * bound on the size of a buffer we'll use?).
1275              */
1276             tmsize_t bytecountm;
1277             bytecountm = (tmsize_t)bytecount;
1278             if ((uint64_t)bytecountm != bytecount)
1279             {
1280                 TIFFErrorExtR(tif, module, "Integer overflow");
1281                 return (0);
1282             }
1283             if (bytecountm > tif->tif_rawdatasize)
1284             {
1285                 tif->tif_curtile = NOTILE;
1286                 if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
1287                 {
1288                     TIFFErrorExtR(tif, module,
1289                                   "Data buffer too small to hold tile %" PRIu32,
1290                                   tile);
1291                     return (0);
1292                 }
1293             }
1294             if (tif->tif_flags & TIFF_BUFFERMMAP)
1295             {
1296                 tif->tif_curtile = NOTILE;
1297                 tif->tif_rawdata = NULL;
1298                 tif->tif_rawdatasize = 0;
1299                 tif->tif_flags &= ~TIFF_BUFFERMMAP;
1300             }
1301 
1302             if (isMapped(tif))
1303             {
1304                 if (bytecountm > tif->tif_rawdatasize &&
1305                     !TIFFReadBufferSetup(tif, 0, bytecountm))
1306                 {
1307                     return (0);
1308                 }
1309                 if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm,
1310                                      module) != bytecountm)
1311                 {
1312                     return (0);
1313                 }
1314             }
1315             else
1316             {
1317                 if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) !=
1318                     bytecountm)
1319                 {
1320                     return (0);
1321                 }
1322             }
1323 
1324             tif->tif_rawdataoff = 0;
1325             tif->tif_rawdataloaded = bytecountm;
1326 
1327             if (tif->tif_rawdata != NULL &&
1328                 !isFillOrder(tif, td->td_fillorder) &&
1329                 (tif->tif_flags & TIFF_NOBITREV) == 0)
1330                 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded);
1331         }
1332     }
1333     return (TIFFStartTile(tif, tile));
1334 }
1335 
1336 /*
1337  * Setup the raw data buffer in preparation for
1338  * reading a strip of raw data.  If the buffer
1339  * is specified as zero, then a buffer of appropriate
1340  * size is allocated by the library.  Otherwise,
1341  * the client must guarantee that the buffer is
1342  * large enough to hold any individual strip of
1343  * raw data.
1344  */
TIFFReadBufferSetup(TIFF * tif,void * bp,tmsize_t size)1345 int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
1346 {
1347     static const char module[] = "TIFFReadBufferSetup";
1348 
1349     assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1350     tif->tif_flags &= ~TIFF_BUFFERMMAP;
1351 
1352     if (tif->tif_rawdata)
1353     {
1354         if (tif->tif_flags & TIFF_MYBUFFER)
1355             _TIFFfreeExt(tif, tif->tif_rawdata);
1356         tif->tif_rawdata = NULL;
1357         tif->tif_rawdatasize = 0;
1358     }
1359     if (bp)
1360     {
1361         tif->tif_rawdatasize = size;
1362         tif->tif_rawdata = (uint8_t *)bp;
1363         tif->tif_flags &= ~TIFF_MYBUFFER;
1364     }
1365     else
1366     {
1367         tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024);
1368         if (tif->tif_rawdatasize == 0)
1369         {
1370             TIFFErrorExtR(tif, module, "Invalid buffer size");
1371             return (0);
1372         }
1373         /* Initialize to zero to avoid uninitialized buffers in case of */
1374         /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
1375         tif->tif_rawdata =
1376             (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize);
1377         tif->tif_flags |= TIFF_MYBUFFER;
1378     }
1379     if (tif->tif_rawdata == NULL)
1380     {
1381         TIFFErrorExtR(tif, module,
1382                       "No space for data buffer at scanline %" PRIu32,
1383                       tif->tif_row);
1384         tif->tif_rawdatasize = 0;
1385         return (0);
1386     }
1387     return (1);
1388 }
1389 
1390 /*
1391  * Set state to appear as if a
1392  * strip has just been read in.
1393  */
TIFFStartStrip(TIFF * tif,uint32_t strip)1394 static int TIFFStartStrip(TIFF *tif, uint32_t strip)
1395 {
1396     TIFFDirectory *td = &tif->tif_dir;
1397 
1398     if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1399     {
1400         if (!(*tif->tif_setupdecode)(tif))
1401             return (0);
1402         tif->tif_flags |= TIFF_CODERSETUP;
1403     }
1404     tif->tif_curstrip = strip;
1405     tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
1406     tif->tif_flags &= ~TIFF_BUF4WRITE;
1407 
1408     if (tif->tif_flags & TIFF_NOREADRAW)
1409     {
1410         tif->tif_rawcp = NULL;
1411         tif->tif_rawcc = 0;
1412     }
1413     else
1414     {
1415         tif->tif_rawcp = tif->tif_rawdata;
1416         if (tif->tif_rawdataloaded > 0)
1417             tif->tif_rawcc = tif->tif_rawdataloaded;
1418         else
1419             tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
1420     }
1421     if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) ==
1422         0)
1423     {
1424         /* Needed for example for scanline access, if tif_predecode */
1425         /* fails, and we try to read the same strip again. Without invalidating
1426          */
1427         /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
1428         /* codec state. */
1429         tif->tif_curstrip = NOSTRIP;
1430         return 0;
1431     }
1432     return 1;
1433 }
1434 
1435 /*
1436  * Set state to appear as if a
1437  * tile has just been read in.
1438  */
TIFFStartTile(TIFF * tif,uint32_t tile)1439 static int TIFFStartTile(TIFF *tif, uint32_t tile)
1440 {
1441     static const char module[] = "TIFFStartTile";
1442     TIFFDirectory *td = &tif->tif_dir;
1443     uint32_t howmany32;
1444 
1445     if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1446     {
1447         if (!(*tif->tif_setupdecode)(tif))
1448             return (0);
1449         tif->tif_flags |= TIFF_CODERSETUP;
1450     }
1451     tif->tif_curtile = tile;
1452     howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
1453     if (howmany32 == 0)
1454     {
1455         TIFFErrorExtR(tif, module, "Zero tiles");
1456         return 0;
1457     }
1458     tif->tif_row = (tile % howmany32) * td->td_tilelength;
1459     howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
1460     if (howmany32 == 0)
1461     {
1462         TIFFErrorExtR(tif, module, "Zero tiles");
1463         return 0;
1464     }
1465     tif->tif_col = (tile % howmany32) * td->td_tilewidth;
1466     tif->tif_flags &= ~TIFF_BUF4WRITE;
1467     if (tif->tif_flags & TIFF_NOREADRAW)
1468     {
1469         tif->tif_rawcp = NULL;
1470         tif->tif_rawcc = 0;
1471     }
1472     else
1473     {
1474         tif->tif_rawcp = tif->tif_rawdata;
1475         if (tif->tif_rawdataloaded > 0)
1476             tif->tif_rawcc = tif->tif_rawdataloaded;
1477         else
1478             tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
1479     }
1480     return (
1481         (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage)));
1482 }
1483 
TIFFCheckRead(TIFF * tif,int tiles)1484 static int TIFFCheckRead(TIFF *tif, int tiles)
1485 {
1486     if (tif->tif_mode == O_WRONLY)
1487     {
1488         TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1489         return (0);
1490     }
1491     if (tiles ^ isTiled(tif))
1492     {
1493         TIFFErrorExtR(tif, tif->tif_name,
1494                       tiles ? "Can not read tiles from a striped image"
1495                             : "Can not read scanlines from a tiled image");
1496         return (0);
1497     }
1498     return (1);
1499 }
1500 
1501 /* Use the provided input buffer (inbuf, insize) and decompress it into
1502  * (outbuf, outsize).
1503  * This function replaces the use of
1504  * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the
1505  * buffer for the input data, for example when he wants to avoid libtiff to read
1506  * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts]
1507  * array. inbuf content must be writable (if bit reversal is needed) Returns 1
1508  * in case of success, 0 otherwise.
1509  */
TIFFReadFromUserBuffer(TIFF * tif,uint32_t strile,void * inbuf,tmsize_t insize,void * outbuf,tmsize_t outsize)1510 int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
1511                            tmsize_t insize, void *outbuf, tmsize_t outsize)
1512 {
1513     static const char module[] = "TIFFReadFromUserBuffer";
1514     TIFFDirectory *td = &tif->tif_dir;
1515     int ret = 1;
1516     uint32_t old_tif_flags = tif->tif_flags;
1517     tmsize_t old_rawdatasize = tif->tif_rawdatasize;
1518     void *old_rawdata = tif->tif_rawdata;
1519 
1520     if (tif->tif_mode == O_WRONLY)
1521     {
1522         TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1523         return 0;
1524     }
1525     if (tif->tif_flags & TIFF_NOREADRAW)
1526     {
1527         TIFFErrorExtR(tif, module,
1528                       "Compression scheme does not support access to raw "
1529                       "uncompressed data");
1530         return 0;
1531     }
1532 
1533     tif->tif_flags &= ~TIFF_MYBUFFER;
1534     tif->tif_flags |= TIFF_BUFFERMMAP;
1535     tif->tif_rawdatasize = insize;
1536     tif->tif_rawdata = inbuf;
1537     tif->tif_rawdataoff = 0;
1538     tif->tif_rawdataloaded = insize;
1539 
1540     if (!isFillOrder(tif, td->td_fillorder) &&
1541         (tif->tif_flags & TIFF_NOBITREV) == 0)
1542     {
1543         TIFFReverseBits(inbuf, insize);
1544     }
1545 
1546     if (TIFFIsTiled(tif))
1547     {
1548         if (!TIFFStartTile(tif, strile) ||
1549             !(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize,
1550                                     (uint16_t)(strile / td->td_stripsperimage)))
1551         {
1552             ret = 0;
1553         }
1554     }
1555     else
1556     {
1557         uint32_t rowsperstrip = td->td_rowsperstrip;
1558         uint32_t stripsperplane;
1559         if (rowsperstrip > td->td_imagelength)
1560             rowsperstrip = td->td_imagelength;
1561         stripsperplane =
1562             TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
1563         if (!TIFFStartStrip(tif, strile) ||
1564             !(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize,
1565                                      (uint16_t)(strile / stripsperplane)))
1566         {
1567             ret = 0;
1568         }
1569     }
1570     if (ret)
1571     {
1572         (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize);
1573     }
1574 
1575     if (!isFillOrder(tif, td->td_fillorder) &&
1576         (tif->tif_flags & TIFF_NOBITREV) == 0)
1577     {
1578         TIFFReverseBits(inbuf, insize);
1579     }
1580 
1581     tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
1582                      (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
1583     tif->tif_rawdatasize = old_rawdatasize;
1584     tif->tif_rawdata = old_rawdata;
1585     tif->tif_rawdataoff = 0;
1586     tif->tif_rawdataloaded = 0;
1587 
1588     return ret;
1589 }
1590 
_TIFFNoPostDecode(TIFF * tif,uint8_t * buf,tmsize_t cc)1591 void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc)
1592 {
1593     (void)tif;
1594     (void)buf;
1595     (void)cc;
1596 }
1597 
_TIFFSwab16BitData(TIFF * tif,uint8_t * buf,tmsize_t cc)1598 void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1599 {
1600     (void)tif;
1601     assert((cc & 1) == 0);
1602     TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2);
1603 }
1604 
_TIFFSwab24BitData(TIFF * tif,uint8_t * buf,tmsize_t cc)1605 void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1606 {
1607     (void)tif;
1608     assert((cc % 3) == 0);
1609     TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3);
1610 }
1611 
_TIFFSwab32BitData(TIFF * tif,uint8_t * buf,tmsize_t cc)1612 void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1613 {
1614     (void)tif;
1615     assert((cc & 3) == 0);
1616     TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4);
1617 }
1618 
_TIFFSwab64BitData(TIFF * tif,uint8_t * buf,tmsize_t cc)1619 void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1620 {
1621     (void)tif;
1622     assert((cc & 7) == 0);
1623     TIFFSwabArrayOfDouble((double *)buf, cc / 8);
1624 }
1625