LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_read.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 465 713 65.2 %
Date: 2026-06-25 09:54:50 Functions: 27 29 93.1 %

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

Generated by: LCOV version 1.14