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