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

Generated by: LCOV version 1.14