blob: 4c3b75603a1fe1ab970b8f2a83b3ba332c05b327 [file] [log] [blame]
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001/*
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 *
28 * Directory Read Support Routines.
29 */
30
31/* Suggested pending improvements:
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080032 * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
33 * the pointer to the appropriate TIFFField structure early on in
34 * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
35 */
36
kumarashishg826308d2023-06-23 13:21:22 +000037#include "tiffconf.h"
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080038#include "tiffiop.h"
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070039#include <float.h>
40#include <limits.h>
Haibo Huang49cc9302020-04-27 16:14:24 -070041#include <stdlib.h>
kumarashishg826308d2023-06-23 13:21:22 +000042#include <string.h>
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080043
kumarashishg826308d2023-06-23 13:21:22 +000044#define FAILED_FII ((uint32_t)-1)
Haibo Huang49cc9302020-04-27 16:14:24 -070045
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080046#ifdef HAVE_IEEEFP
kumarashishg826308d2023-06-23 13:21:22 +000047#define TIFFCvtIEEEFloatToNative(tif, n, fp)
48#define TIFFCvtIEEEDoubleToNative(tif, n, dp)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080049#else
kumarashishg826308d2023-06-23 13:21:22 +000050extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *);
51extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080052#endif
53
kumarashishg826308d2023-06-23 13:21:22 +000054enum TIFFReadDirEntryErr
55{
56 TIFFReadDirEntryErrOk = 0,
57 TIFFReadDirEntryErrCount = 1,
58 TIFFReadDirEntryErrType = 2,
59 TIFFReadDirEntryErrIo = 3,
60 TIFFReadDirEntryErrRange = 4,
61 TIFFReadDirEntryErrPsdif = 5,
62 TIFFReadDirEntryErrSizesan = 6,
63 TIFFReadDirEntryErrAlloc = 7,
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080064};
65
kumarashishg826308d2023-06-23 13:21:22 +000066static enum TIFFReadDirEntryErr
67TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value);
68static enum TIFFReadDirEntryErr
69TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value);
70static enum TIFFReadDirEntryErr
71TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value);
72static enum TIFFReadDirEntryErr
73TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value);
74static enum TIFFReadDirEntryErr
75TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value);
76static enum TIFFReadDirEntryErr
77TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value);
78static enum TIFFReadDirEntryErr
79TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
80static enum TIFFReadDirEntryErr
81TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value);
82static enum TIFFReadDirEntryErr
83TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value);
84static enum TIFFReadDirEntryErr
85TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
86static enum TIFFReadDirEntryErr
87TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -080088
kumarashishg826308d2023-06-23 13:21:22 +000089static enum TIFFReadDirEntryErr
90TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
91 uint32_t desttypesize, void **value);
92static enum TIFFReadDirEntryErr
93TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value);
94static enum TIFFReadDirEntryErr
95TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value);
96static enum TIFFReadDirEntryErr
97TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value);
98static enum TIFFReadDirEntryErr
99TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value);
100static enum TIFFReadDirEntryErr
101TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value);
102static enum TIFFReadDirEntryErr
103TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value);
104static enum TIFFReadDirEntryErr
105TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
106static enum TIFFReadDirEntryErr
107TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value);
108static enum TIFFReadDirEntryErr
109TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value);
110static enum TIFFReadDirEntryErr
111TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value);
112static enum TIFFReadDirEntryErr
113TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800114
kumarashishg826308d2023-06-23 13:21:22 +0000115static enum TIFFReadDirEntryErr
116TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
117 uint16_t *value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800118
kumarashishg826308d2023-06-23 13:21:22 +0000119static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
120 uint8_t *value);
121static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
122 int8_t *value);
123static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
124 uint16_t *value);
125static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
126 int16_t *value);
127static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
128 uint32_t *value);
129static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
130 int32_t *value);
131static enum TIFFReadDirEntryErr
132TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry,
133 uint64_t *value);
134static enum TIFFReadDirEntryErr
135TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry,
136 int64_t *value);
137static enum TIFFReadDirEntryErr
138TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
139 double *value);
140static enum TIFFReadDirEntryErr
141TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
142 double *value);
143static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
144 float *value);
145static enum TIFFReadDirEntryErr
146TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800147
kumarashishg826308d2023-06-23 13:21:22 +0000148static enum TIFFReadDirEntryErr
149TIFFReadDirEntryCheckRangeByteSbyte(int8_t value);
150static enum TIFFReadDirEntryErr
151TIFFReadDirEntryCheckRangeByteShort(uint16_t value);
152static enum TIFFReadDirEntryErr
153TIFFReadDirEntryCheckRangeByteSshort(int16_t value);
154static enum TIFFReadDirEntryErr
155TIFFReadDirEntryCheckRangeByteLong(uint32_t value);
156static enum TIFFReadDirEntryErr
157TIFFReadDirEntryCheckRangeByteSlong(int32_t value);
158static enum TIFFReadDirEntryErr
159TIFFReadDirEntryCheckRangeByteLong8(uint64_t value);
160static enum TIFFReadDirEntryErr
161TIFFReadDirEntryCheckRangeByteSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800162
kumarashishg826308d2023-06-23 13:21:22 +0000163static enum TIFFReadDirEntryErr
164TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value);
165static enum TIFFReadDirEntryErr
166TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value);
167static enum TIFFReadDirEntryErr
168TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value);
169static enum TIFFReadDirEntryErr
170TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value);
171static enum TIFFReadDirEntryErr
172TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value);
173static enum TIFFReadDirEntryErr
174TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value);
175static enum TIFFReadDirEntryErr
176TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800177
kumarashishg826308d2023-06-23 13:21:22 +0000178static enum TIFFReadDirEntryErr
179TIFFReadDirEntryCheckRangeShortSbyte(int8_t value);
180static enum TIFFReadDirEntryErr
181TIFFReadDirEntryCheckRangeShortSshort(int16_t value);
182static enum TIFFReadDirEntryErr
183TIFFReadDirEntryCheckRangeShortLong(uint32_t value);
184static enum TIFFReadDirEntryErr
185TIFFReadDirEntryCheckRangeShortSlong(int32_t value);
186static enum TIFFReadDirEntryErr
187TIFFReadDirEntryCheckRangeShortLong8(uint64_t value);
188static enum TIFFReadDirEntryErr
189TIFFReadDirEntryCheckRangeShortSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800190
kumarashishg826308d2023-06-23 13:21:22 +0000191static enum TIFFReadDirEntryErr
192TIFFReadDirEntryCheckRangeSshortShort(uint16_t value);
193static enum TIFFReadDirEntryErr
194TIFFReadDirEntryCheckRangeSshortLong(uint32_t value);
195static enum TIFFReadDirEntryErr
196TIFFReadDirEntryCheckRangeSshortSlong(int32_t value);
197static enum TIFFReadDirEntryErr
198TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value);
199static enum TIFFReadDirEntryErr
200TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800201
kumarashishg826308d2023-06-23 13:21:22 +0000202static enum TIFFReadDirEntryErr
203TIFFReadDirEntryCheckRangeLongSbyte(int8_t value);
204static enum TIFFReadDirEntryErr
205TIFFReadDirEntryCheckRangeLongSshort(int16_t value);
206static enum TIFFReadDirEntryErr
207TIFFReadDirEntryCheckRangeLongSlong(int32_t value);
208static enum TIFFReadDirEntryErr
209TIFFReadDirEntryCheckRangeLongLong8(uint64_t value);
210static enum TIFFReadDirEntryErr
211TIFFReadDirEntryCheckRangeLongSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800212
kumarashishg826308d2023-06-23 13:21:22 +0000213static enum TIFFReadDirEntryErr
214TIFFReadDirEntryCheckRangeSlongLong(uint32_t value);
215static enum TIFFReadDirEntryErr
216TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value);
217static enum TIFFReadDirEntryErr
218TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800219
kumarashishg826308d2023-06-23 13:21:22 +0000220static enum TIFFReadDirEntryErr
221TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value);
222static enum TIFFReadDirEntryErr
223TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value);
224static enum TIFFReadDirEntryErr
225TIFFReadDirEntryCheckRangeLong8Slong(int32_t value);
226static enum TIFFReadDirEntryErr
227TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800228
kumarashishg826308d2023-06-23 13:21:22 +0000229static enum TIFFReadDirEntryErr
230TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800231
kumarashishg826308d2023-06-23 13:21:22 +0000232static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
233 tmsize_t size, void *dest);
234static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
235 const char *module, const char *tagname,
236 int recover);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800237
kumarashishg826308d2023-06-23 13:21:22 +0000238static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
239 uint16_t dircount);
240static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
241 uint16_t dircount,
242 uint16_t tagid);
243static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
244 uint32_t *fii);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800245
kumarashishg826308d2023-06-23 13:21:22 +0000246static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
247 uint16_t dircount);
248static void MissingRequired(TIFF *, const char *);
249static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t);
250static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
251 TIFFDirEntry **pdir, uint64_t *nextdiroff);
252static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover);
253static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
254 uint64_t **lpp);
255static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *);
256static void ChopUpSingleUncompressedStrip(TIFF *);
257static void TryChopUpUncompressedBigTiff(TIFF *);
258static uint64_t TIFFReadUInt64(const uint8_t *value);
259static int _TIFFGetMaxColorChannels(uint16_t photometric);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800260
kumarashishg826308d2023-06-23 13:21:22 +0000261static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700262
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800263typedef union _UInt64Aligned_t
264{
kumarashishg826308d2023-06-23 13:21:22 +0000265 double d;
266 uint64_t l;
267 uint32_t i[2];
268 uint16_t s[4];
269 uint8_t c[8];
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800270} UInt64Aligned_t;
271
272/*
kumarashishg826308d2023-06-23 13:21:22 +0000273 Unaligned safe copy of a uint64_t value from an octet array.
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800274*/
kumarashishg826308d2023-06-23 13:21:22 +0000275static uint64_t TIFFReadUInt64(const uint8_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800276{
kumarashishg826308d2023-06-23 13:21:22 +0000277 UInt64Aligned_t result;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800278
kumarashishg826308d2023-06-23 13:21:22 +0000279 result.c[0] = value[0];
280 result.c[1] = value[1];
281 result.c[2] = value[2];
282 result.c[3] = value[3];
283 result.c[4] = value[4];
284 result.c[5] = value[5];
285 result.c[6] = value[6];
286 result.c[7] = value[7];
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800287
kumarashishg826308d2023-06-23 13:21:22 +0000288 return result.l;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800289}
290
kumarashishg826308d2023-06-23 13:21:22 +0000291static enum TIFFReadDirEntryErr
292TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800293{
kumarashishg826308d2023-06-23 13:21:22 +0000294 enum TIFFReadDirEntryErr err;
295 if (direntry->tdir_count != 1)
296 return (TIFFReadDirEntryErrCount);
297 switch (direntry->tdir_type)
298 {
299 case TIFF_BYTE:
300 case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with
301 field_readcount==1 */
302 TIFFReadDirEntryCheckedByte(tif, direntry, value);
303 return (TIFFReadDirEntryErrOk);
304 case TIFF_SBYTE:
305 {
306 int8_t m;
307 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
308 err = TIFFReadDirEntryCheckRangeByteSbyte(m);
309 if (err != TIFFReadDirEntryErrOk)
310 return (err);
311 *value = (uint8_t)m;
312 return (TIFFReadDirEntryErrOk);
313 }
314 case TIFF_SHORT:
315 {
316 uint16_t m;
317 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
318 err = TIFFReadDirEntryCheckRangeByteShort(m);
319 if (err != TIFFReadDirEntryErrOk)
320 return (err);
321 *value = (uint8_t)m;
322 return (TIFFReadDirEntryErrOk);
323 }
324 case TIFF_SSHORT:
325 {
326 int16_t m;
327 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
328 err = TIFFReadDirEntryCheckRangeByteSshort(m);
329 if (err != TIFFReadDirEntryErrOk)
330 return (err);
331 *value = (uint8_t)m;
332 return (TIFFReadDirEntryErrOk);
333 }
334 case TIFF_LONG:
335 {
336 uint32_t m;
337 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
338 err = TIFFReadDirEntryCheckRangeByteLong(m);
339 if (err != TIFFReadDirEntryErrOk)
340 return (err);
341 *value = (uint8_t)m;
342 return (TIFFReadDirEntryErrOk);
343 }
344 case TIFF_SLONG:
345 {
346 int32_t m;
347 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
348 err = TIFFReadDirEntryCheckRangeByteSlong(m);
349 if (err != TIFFReadDirEntryErrOk)
350 return (err);
351 *value = (uint8_t)m;
352 return (TIFFReadDirEntryErrOk);
353 }
354 case TIFF_LONG8:
355 {
356 uint64_t m;
357 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
358 if (err != TIFFReadDirEntryErrOk)
359 return (err);
360 err = TIFFReadDirEntryCheckRangeByteLong8(m);
361 if (err != TIFFReadDirEntryErrOk)
362 return (err);
363 *value = (uint8_t)m;
364 return (TIFFReadDirEntryErrOk);
365 }
366 case TIFF_SLONG8:
367 {
368 int64_t m;
369 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
370 if (err != TIFFReadDirEntryErrOk)
371 return (err);
372 err = TIFFReadDirEntryCheckRangeByteSlong8(m);
373 if (err != TIFFReadDirEntryErrOk)
374 return (err);
375 *value = (uint8_t)m;
376 return (TIFFReadDirEntryErrOk);
377 }
378 default:
379 return (TIFFReadDirEntryErrType);
380 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800381}
382
kumarashishg826308d2023-06-23 13:21:22 +0000383static enum TIFFReadDirEntryErr
384TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800385{
kumarashishg826308d2023-06-23 13:21:22 +0000386 enum TIFFReadDirEntryErr err;
387 if (direntry->tdir_count != 1)
388 return (TIFFReadDirEntryErrCount);
389 switch (direntry->tdir_type)
390 {
391 case TIFF_BYTE:
392 case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with
393 field_readcount==1 */
394 {
395 uint8_t m;
396 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
397 err = TIFFReadDirEntryCheckRangeSbyteByte(m);
398 if (err != TIFFReadDirEntryErrOk)
399 return (err);
400 *value = (int8_t)m;
401 return (TIFFReadDirEntryErrOk);
402 }
403 case TIFF_SBYTE:
404 {
405 TIFFReadDirEntryCheckedSbyte(tif, direntry, value);
406 return (TIFFReadDirEntryErrOk);
407 }
408 case TIFF_SHORT:
409 {
410 uint16_t m;
411 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
412 err = TIFFReadDirEntryCheckRangeSbyteShort(m);
413 if (err != TIFFReadDirEntryErrOk)
414 return (err);
415 *value = (int8_t)m;
416 return (TIFFReadDirEntryErrOk);
417 }
418 case TIFF_SSHORT:
419 {
420 int16_t m;
421 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
422 err = TIFFReadDirEntryCheckRangeSbyteSshort(m);
423 if (err != TIFFReadDirEntryErrOk)
424 return (err);
425 *value = (int8_t)m;
426 return (TIFFReadDirEntryErrOk);
427 }
428 case TIFF_LONG:
429 {
430 uint32_t m;
431 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
432 err = TIFFReadDirEntryCheckRangeSbyteLong(m);
433 if (err != TIFFReadDirEntryErrOk)
434 return (err);
435 *value = (int8_t)m;
436 return (TIFFReadDirEntryErrOk);
437 }
438 case TIFF_SLONG:
439 {
440 int32_t m;
441 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
442 err = TIFFReadDirEntryCheckRangeSbyteSlong(m);
443 if (err != TIFFReadDirEntryErrOk)
444 return (err);
445 *value = (int8_t)m;
446 return (TIFFReadDirEntryErrOk);
447 }
448 case TIFF_LONG8:
449 {
450 uint64_t m;
451 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
452 if (err != TIFFReadDirEntryErrOk)
453 return (err);
454 err = TIFFReadDirEntryCheckRangeSbyteLong8(m);
455 if (err != TIFFReadDirEntryErrOk)
456 return (err);
457 *value = (int8_t)m;
458 return (TIFFReadDirEntryErrOk);
459 }
460 case TIFF_SLONG8:
461 {
462 int64_t m;
463 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
464 if (err != TIFFReadDirEntryErrOk)
465 return (err);
466 err = TIFFReadDirEntryCheckRangeSbyteSlong8(m);
467 if (err != TIFFReadDirEntryErrOk)
468 return (err);
469 *value = (int8_t)m;
470 return (TIFFReadDirEntryErrOk);
471 }
472 default:
473 return (TIFFReadDirEntryErrType);
474 }
475} /*-- TIFFReadDirEntrySbyte() --*/
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800476
kumarashishg826308d2023-06-23 13:21:22 +0000477static enum TIFFReadDirEntryErr
478TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800479{
kumarashishg826308d2023-06-23 13:21:22 +0000480 enum TIFFReadDirEntryErr err;
481 if (direntry->tdir_count != 1)
482 return (TIFFReadDirEntryErrCount);
483 switch (direntry->tdir_type)
484 {
485 case TIFF_BYTE:
486 {
487 uint8_t m;
488 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
489 *value = (uint16_t)m;
490 return (TIFFReadDirEntryErrOk);
491 }
492 case TIFF_SBYTE:
493 {
494 int8_t m;
495 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
496 err = TIFFReadDirEntryCheckRangeShortSbyte(m);
497 if (err != TIFFReadDirEntryErrOk)
498 return (err);
499 *value = (uint16_t)m;
500 return (TIFFReadDirEntryErrOk);
501 }
502 case TIFF_SHORT:
503 TIFFReadDirEntryCheckedShort(tif, direntry, value);
504 return (TIFFReadDirEntryErrOk);
505 case TIFF_SSHORT:
506 {
507 int16_t m;
508 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
509 err = TIFFReadDirEntryCheckRangeShortSshort(m);
510 if (err != TIFFReadDirEntryErrOk)
511 return (err);
512 *value = (uint16_t)m;
513 return (TIFFReadDirEntryErrOk);
514 }
515 case TIFF_LONG:
516 {
517 uint32_t m;
518 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
519 err = TIFFReadDirEntryCheckRangeShortLong(m);
520 if (err != TIFFReadDirEntryErrOk)
521 return (err);
522 *value = (uint16_t)m;
523 return (TIFFReadDirEntryErrOk);
524 }
525 case TIFF_SLONG:
526 {
527 int32_t m;
528 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
529 err = TIFFReadDirEntryCheckRangeShortSlong(m);
530 if (err != TIFFReadDirEntryErrOk)
531 return (err);
532 *value = (uint16_t)m;
533 return (TIFFReadDirEntryErrOk);
534 }
535 case TIFF_LONG8:
536 {
537 uint64_t m;
538 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
539 if (err != TIFFReadDirEntryErrOk)
540 return (err);
541 err = TIFFReadDirEntryCheckRangeShortLong8(m);
542 if (err != TIFFReadDirEntryErrOk)
543 return (err);
544 *value = (uint16_t)m;
545 return (TIFFReadDirEntryErrOk);
546 }
547 case TIFF_SLONG8:
548 {
549 int64_t m;
550 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
551 if (err != TIFFReadDirEntryErrOk)
552 return (err);
553 err = TIFFReadDirEntryCheckRangeShortSlong8(m);
554 if (err != TIFFReadDirEntryErrOk)
555 return (err);
556 *value = (uint16_t)m;
557 return (TIFFReadDirEntryErrOk);
558 }
559 default:
560 return (TIFFReadDirEntryErrType);
561 }
562} /*-- TIFFReadDirEntryShort() --*/
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800563
kumarashishg826308d2023-06-23 13:21:22 +0000564static enum TIFFReadDirEntryErr
565TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800566{
kumarashishg826308d2023-06-23 13:21:22 +0000567 enum TIFFReadDirEntryErr err;
568 if (direntry->tdir_count != 1)
569 return (TIFFReadDirEntryErrCount);
570 switch (direntry->tdir_type)
571 {
572 case TIFF_BYTE:
573 {
574 uint8_t m;
575 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
576 *value = (int16_t)m;
577 return (TIFFReadDirEntryErrOk);
578 }
579 case TIFF_SBYTE:
580 {
581 int8_t m;
582 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
583 *value = (int16_t)m;
584 return (TIFFReadDirEntryErrOk);
585 }
586 case TIFF_SHORT:
587 {
588 uint16_t m;
589 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
590 err = TIFFReadDirEntryCheckRangeSshortShort(m);
591 if (err != TIFFReadDirEntryErrOk)
592 return (err);
593 *value = (uint16_t)m;
594 return (TIFFReadDirEntryErrOk);
595 }
596 case TIFF_SSHORT:
597 TIFFReadDirEntryCheckedSshort(tif, direntry, value);
598 return (TIFFReadDirEntryErrOk);
599 case TIFF_LONG:
600 {
601 uint32_t m;
602 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
603 err = TIFFReadDirEntryCheckRangeSshortLong(m);
604 if (err != TIFFReadDirEntryErrOk)
605 return (err);
606 *value = (int16_t)m;
607 return (TIFFReadDirEntryErrOk);
608 }
609 case TIFF_SLONG:
610 {
611 int32_t m;
612 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
613 err = TIFFReadDirEntryCheckRangeSshortSlong(m);
614 if (err != TIFFReadDirEntryErrOk)
615 return (err);
616 *value = (int16_t)m;
617 return (TIFFReadDirEntryErrOk);
618 }
619 case TIFF_LONG8:
620 {
621 uint64_t m;
622 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
623 if (err != TIFFReadDirEntryErrOk)
624 return (err);
625 err = TIFFReadDirEntryCheckRangeSshortLong8(m);
626 if (err != TIFFReadDirEntryErrOk)
627 return (err);
628 *value = (int16_t)m;
629 return (TIFFReadDirEntryErrOk);
630 }
631 case TIFF_SLONG8:
632 {
633 int64_t m;
634 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
635 if (err != TIFFReadDirEntryErrOk)
636 return (err);
637 err = TIFFReadDirEntryCheckRangeSshortSlong8(m);
638 if (err != TIFFReadDirEntryErrOk)
639 return (err);
640 *value = (int16_t)m;
641 return (TIFFReadDirEntryErrOk);
642 }
643 default:
644 return (TIFFReadDirEntryErrType);
645 }
646} /*-- TIFFReadDirEntrySshort() --*/
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800647
kumarashishg826308d2023-06-23 13:21:22 +0000648static enum TIFFReadDirEntryErr
649TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -0800650{
kumarashishg826308d2023-06-23 13:21:22 +0000651 enum TIFFReadDirEntryErr err;
652 if (direntry->tdir_count != 1)
653 return (TIFFReadDirEntryErrCount);
654 switch (direntry->tdir_type)
655 {
656 case TIFF_BYTE:
657 {
658 uint8_t m;
659 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
660 *value = (uint32_t)m;
661 return (TIFFReadDirEntryErrOk);
662 }
663 case TIFF_SBYTE:
664 {
665 int8_t m;
666 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
667 err = TIFFReadDirEntryCheckRangeLongSbyte(m);
668 if (err != TIFFReadDirEntryErrOk)
669 return (err);
670 *value = (uint32_t)m;
671 return (TIFFReadDirEntryErrOk);
672 }
673 case TIFF_SHORT:
674 {
675 uint16_t m;
676 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
677 *value = (uint32_t)m;
678 return (TIFFReadDirEntryErrOk);
679 }
680 case TIFF_SSHORT:
681 {
682 int16_t m;
683 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
684 err = TIFFReadDirEntryCheckRangeLongSshort(m);
685 if (err != TIFFReadDirEntryErrOk)
686 return (err);
687 *value = (uint32_t)m;
688 return (TIFFReadDirEntryErrOk);
689 }
690 case TIFF_LONG:
691 TIFFReadDirEntryCheckedLong(tif, direntry, value);
692 return (TIFFReadDirEntryErrOk);
693 case TIFF_SLONG:
694 {
695 int32_t m;
696 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
697 err = TIFFReadDirEntryCheckRangeLongSlong(m);
698 if (err != TIFFReadDirEntryErrOk)
699 return (err);
700 *value = (uint32_t)m;
701 return (TIFFReadDirEntryErrOk);
702 }
703 case TIFF_LONG8:
704 {
705 uint64_t m;
706 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
707 if (err != TIFFReadDirEntryErrOk)
708 return (err);
709 err = TIFFReadDirEntryCheckRangeLongLong8(m);
710 if (err != TIFFReadDirEntryErrOk)
711 return (err);
712 *value = (uint32_t)m;
713 return (TIFFReadDirEntryErrOk);
714 }
715 case TIFF_SLONG8:
716 {
717 int64_t m;
718 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
719 if (err != TIFFReadDirEntryErrOk)
720 return (err);
721 err = TIFFReadDirEntryCheckRangeLongSlong8(m);
722 if (err != TIFFReadDirEntryErrOk)
723 return (err);
724 *value = (uint32_t)m;
725 return (TIFFReadDirEntryErrOk);
726 }
727 default:
728 return (TIFFReadDirEntryErrType);
729 }
730} /*-- TIFFReadDirEntryLong() --*/
731
732static enum TIFFReadDirEntryErr
733TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value)
734{
735 enum TIFFReadDirEntryErr err;
736 if (direntry->tdir_count != 1)
737 return (TIFFReadDirEntryErrCount);
738 switch (direntry->tdir_type)
739 {
740 case TIFF_BYTE:
741 {
742 uint8_t m;
743 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
744 *value = (int32_t)m;
745 return (TIFFReadDirEntryErrOk);
746 }
747 case TIFF_SBYTE:
748 {
749 int8_t m;
750 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
751 *value = (int32_t)m;
752 return (TIFFReadDirEntryErrOk);
753 }
754 case TIFF_SHORT:
755 {
756 uint16_t m;
757 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
758 *value = (int32_t)m;
759 return (TIFFReadDirEntryErrOk);
760 }
761 case TIFF_SSHORT:
762 {
763 int16_t m;
764 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
765 *value = (int32_t)m;
766 return (TIFFReadDirEntryErrOk);
767 }
768 case TIFF_LONG:
769 {
770 uint32_t m;
771 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
772 err = TIFFReadDirEntryCheckRangeSlongLong(m);
773 if (err != TIFFReadDirEntryErrOk)
774 return (err);
775 *value = (int32_t)m;
776 return (TIFFReadDirEntryErrOk);
777 }
778 case TIFF_SLONG:
779 TIFFReadDirEntryCheckedSlong(tif, direntry, value);
780 return (TIFFReadDirEntryErrOk);
781 case TIFF_LONG8:
782 {
783 uint64_t m;
784 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
785 if (err != TIFFReadDirEntryErrOk)
786 return (err);
787 err = TIFFReadDirEntryCheckRangeSlongLong8(m);
788 if (err != TIFFReadDirEntryErrOk)
789 return (err);
790 *value = (int32_t)m;
791 return (TIFFReadDirEntryErrOk);
792 }
793 case TIFF_SLONG8:
794 {
795 int64_t m;
796 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
797 if (err != TIFFReadDirEntryErrOk)
798 return (err);
799 err = TIFFReadDirEntryCheckRangeSlongSlong8(m);
800 if (err != TIFFReadDirEntryErrOk)
801 return (err);
802 *value = (int32_t)m;
803 return (TIFFReadDirEntryErrOk);
804 }
805 default:
806 return (TIFFReadDirEntryErrType);
807 }
808} /*-- TIFFReadDirEntrySlong() --*/
809
810static enum TIFFReadDirEntryErr
811TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
812{
813 enum TIFFReadDirEntryErr err;
814 if (direntry->tdir_count != 1)
815 return (TIFFReadDirEntryErrCount);
816 switch (direntry->tdir_type)
817 {
818 case TIFF_BYTE:
819 {
820 uint8_t m;
821 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
822 *value = (uint64_t)m;
823 return (TIFFReadDirEntryErrOk);
824 }
825 case TIFF_SBYTE:
826 {
827 int8_t m;
828 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
829 err = TIFFReadDirEntryCheckRangeLong8Sbyte(m);
830 if (err != TIFFReadDirEntryErrOk)
831 return (err);
832 *value = (uint64_t)m;
833 return (TIFFReadDirEntryErrOk);
834 }
835 case TIFF_SHORT:
836 {
837 uint16_t m;
838 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
839 *value = (uint64_t)m;
840 return (TIFFReadDirEntryErrOk);
841 }
842 case TIFF_SSHORT:
843 {
844 int16_t m;
845 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
846 err = TIFFReadDirEntryCheckRangeLong8Sshort(m);
847 if (err != TIFFReadDirEntryErrOk)
848 return (err);
849 *value = (uint64_t)m;
850 return (TIFFReadDirEntryErrOk);
851 }
852 case TIFF_LONG:
853 {
854 uint32_t m;
855 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
856 *value = (uint64_t)m;
857 return (TIFFReadDirEntryErrOk);
858 }
859 case TIFF_SLONG:
860 {
861 int32_t m;
862 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
863 err = TIFFReadDirEntryCheckRangeLong8Slong(m);
864 if (err != TIFFReadDirEntryErrOk)
865 return (err);
866 *value = (uint64_t)m;
867 return (TIFFReadDirEntryErrOk);
868 }
869 case TIFF_LONG8:
870 err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
871 return (err);
872 case TIFF_SLONG8:
873 {
874 int64_t m;
875 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
876 if (err != TIFFReadDirEntryErrOk)
877 return (err);
878 err = TIFFReadDirEntryCheckRangeLong8Slong8(m);
879 if (err != TIFFReadDirEntryErrOk)
880 return (err);
881 *value = (uint64_t)m;
882 return (TIFFReadDirEntryErrOk);
883 }
884 default:
885 return (TIFFReadDirEntryErrType);
886 }
887} /*-- TIFFReadDirEntryLong8() --*/
888
889static enum TIFFReadDirEntryErr
890TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
891{
892 enum TIFFReadDirEntryErr err;
893 if (direntry->tdir_count != 1)
894 return (TIFFReadDirEntryErrCount);
895 switch (direntry->tdir_type)
896 {
897 case TIFF_BYTE:
898 {
899 uint8_t m;
900 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
901 *value = (int64_t)m;
902 return (TIFFReadDirEntryErrOk);
903 }
904 case TIFF_SBYTE:
905 {
906 int8_t m;
907 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
908 *value = (int64_t)m;
909 return (TIFFReadDirEntryErrOk);
910 }
911 case TIFF_SHORT:
912 {
913 uint16_t m;
914 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
915 *value = (int64_t)m;
916 return (TIFFReadDirEntryErrOk);
917 }
918 case TIFF_SSHORT:
919 {
920 int16_t m;
921 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
922 *value = (int64_t)m;
923 return (TIFFReadDirEntryErrOk);
924 }
925 case TIFF_LONG:
926 {
927 uint32_t m;
928 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
929 *value = (int64_t)m;
930 return (TIFFReadDirEntryErrOk);
931 }
932 case TIFF_SLONG:
933 {
934 int32_t m;
935 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
936 *value = (int64_t)m;
937 return (TIFFReadDirEntryErrOk);
938 }
939 case TIFF_LONG8:
940 {
941 uint64_t m;
942 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
943 if (err != TIFFReadDirEntryErrOk)
944 return (err);
945 err = TIFFReadDirEntryCheckRangeSlong8Long8(m);
946 if (err != TIFFReadDirEntryErrOk)
947 return (err);
948 *value = (int64_t)m;
949 return (TIFFReadDirEntryErrOk);
950 }
951 case TIFF_SLONG8:
952 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value);
953 return (err);
954 default:
955 return (TIFFReadDirEntryErrType);
956 }
957} /*-- TIFFReadDirEntrySlong8() --*/
958
959static enum TIFFReadDirEntryErr
960TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value)
961{
962 enum TIFFReadDirEntryErr err;
963 if (direntry->tdir_count != 1)
964 return (TIFFReadDirEntryErrCount);
965 switch (direntry->tdir_type)
966 {
967 case TIFF_BYTE:
968 {
969 uint8_t m;
970 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
971 *value = (float)m;
972 return (TIFFReadDirEntryErrOk);
973 }
974 case TIFF_SBYTE:
975 {
976 int8_t m;
977 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
978 *value = (float)m;
979 return (TIFFReadDirEntryErrOk);
980 }
981 case TIFF_SHORT:
982 {
983 uint16_t m;
984 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
985 *value = (float)m;
986 return (TIFFReadDirEntryErrOk);
987 }
988 case TIFF_SSHORT:
989 {
990 int16_t m;
991 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
992 *value = (float)m;
993 return (TIFFReadDirEntryErrOk);
994 }
995 case TIFF_LONG:
996 {
997 uint32_t m;
998 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
999 *value = (float)m;
1000 return (TIFFReadDirEntryErrOk);
1001 }
1002 case TIFF_SLONG:
1003 {
1004 int32_t m;
1005 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
1006 *value = (float)m;
1007 return (TIFFReadDirEntryErrOk);
1008 }
1009 case TIFF_LONG8:
1010 {
1011 uint64_t m;
1012 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
1013 if (err != TIFFReadDirEntryErrOk)
1014 return (err);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001015#if defined(__WIN32__) && (_MSC_VER < 1500)
kumarashishg826308d2023-06-23 13:21:22 +00001016 /*
1017 * XXX: MSVC 6.0 does not support conversion
1018 * of 64-bit integers into floating point
1019 * values.
1020 */
1021 *value = _TIFFUInt64ToFloat(m);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001022#else
kumarashishg826308d2023-06-23 13:21:22 +00001023 *value = (float)m;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001024#endif
kumarashishg826308d2023-06-23 13:21:22 +00001025 return (TIFFReadDirEntryErrOk);
1026 }
1027 case TIFF_SLONG8:
1028 {
1029 int64_t m;
1030 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
1031 if (err != TIFFReadDirEntryErrOk)
1032 return (err);
1033 *value = (float)m;
1034 return (TIFFReadDirEntryErrOk);
1035 }
1036 case TIFF_RATIONAL:
1037 {
1038 double m;
1039 err = TIFFReadDirEntryCheckedRational(tif, direntry, &m);
1040 if (err != TIFFReadDirEntryErrOk)
1041 return (err);
1042 *value = (float)m;
1043 return (TIFFReadDirEntryErrOk);
1044 }
1045 case TIFF_SRATIONAL:
1046 {
1047 double m;
1048 err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m);
1049 if (err != TIFFReadDirEntryErrOk)
1050 return (err);
1051 *value = (float)m;
1052 return (TIFFReadDirEntryErrOk);
1053 }
1054 case TIFF_FLOAT:
1055 TIFFReadDirEntryCheckedFloat(tif, direntry, value);
1056 return (TIFFReadDirEntryErrOk);
1057 case TIFF_DOUBLE:
1058 {
1059 double m;
1060 err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m);
1061 if (err != TIFFReadDirEntryErrOk)
1062 return (err);
1063 if ((m > FLT_MAX) || (m < -FLT_MAX))
1064 return (TIFFReadDirEntryErrRange);
1065 *value = (float)m;
1066 return (TIFFReadDirEntryErrOk);
1067 }
1068 default:
1069 return (TIFFReadDirEntryErrType);
1070 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001071}
1072
kumarashishg826308d2023-06-23 13:21:22 +00001073static enum TIFFReadDirEntryErr
1074TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001075{
kumarashishg826308d2023-06-23 13:21:22 +00001076 enum TIFFReadDirEntryErr err;
1077 if (direntry->tdir_count != 1)
1078 return (TIFFReadDirEntryErrCount);
1079 switch (direntry->tdir_type)
1080 {
1081 case TIFF_BYTE:
1082 {
1083 uint8_t m;
1084 TIFFReadDirEntryCheckedByte(tif, direntry, &m);
1085 *value = (double)m;
1086 return (TIFFReadDirEntryErrOk);
1087 }
1088 case TIFF_SBYTE:
1089 {
1090 int8_t m;
1091 TIFFReadDirEntryCheckedSbyte(tif, direntry, &m);
1092 *value = (double)m;
1093 return (TIFFReadDirEntryErrOk);
1094 }
1095 case TIFF_SHORT:
1096 {
1097 uint16_t m;
1098 TIFFReadDirEntryCheckedShort(tif, direntry, &m);
1099 *value = (double)m;
1100 return (TIFFReadDirEntryErrOk);
1101 }
1102 case TIFF_SSHORT:
1103 {
1104 int16_t m;
1105 TIFFReadDirEntryCheckedSshort(tif, direntry, &m);
1106 *value = (double)m;
1107 return (TIFFReadDirEntryErrOk);
1108 }
1109 case TIFF_LONG:
1110 {
1111 uint32_t m;
1112 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
1113 *value = (double)m;
1114 return (TIFFReadDirEntryErrOk);
1115 }
1116 case TIFF_SLONG:
1117 {
1118 int32_t m;
1119 TIFFReadDirEntryCheckedSlong(tif, direntry, &m);
1120 *value = (double)m;
1121 return (TIFFReadDirEntryErrOk);
1122 }
1123 case TIFF_LONG8:
1124 {
1125 uint64_t m;
1126 err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m);
1127 if (err != TIFFReadDirEntryErrOk)
1128 return (err);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001129#if defined(__WIN32__) && (_MSC_VER < 1500)
kumarashishg826308d2023-06-23 13:21:22 +00001130 /*
1131 * XXX: MSVC 6.0 does not support conversion
1132 * of 64-bit integers into floating point
1133 * values.
1134 */
1135 *value = _TIFFUInt64ToDouble(m);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001136#else
kumarashishg826308d2023-06-23 13:21:22 +00001137 *value = (double)m;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001138#endif
kumarashishg826308d2023-06-23 13:21:22 +00001139 return (TIFFReadDirEntryErrOk);
1140 }
1141 case TIFF_SLONG8:
1142 {
1143 int64_t m;
1144 err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m);
1145 if (err != TIFFReadDirEntryErrOk)
1146 return (err);
1147 *value = (double)m;
1148 return (TIFFReadDirEntryErrOk);
1149 }
1150 case TIFF_RATIONAL:
1151 err = TIFFReadDirEntryCheckedRational(tif, direntry, value);
1152 return (err);
1153 case TIFF_SRATIONAL:
1154 err = TIFFReadDirEntryCheckedSrational(tif, direntry, value);
1155 return (err);
1156 case TIFF_FLOAT:
1157 {
1158 float m;
1159 TIFFReadDirEntryCheckedFloat(tif, direntry, &m);
1160 *value = (double)m;
1161 return (TIFFReadDirEntryErrOk);
1162 }
1163 case TIFF_DOUBLE:
1164 err = TIFFReadDirEntryCheckedDouble(tif, direntry, value);
1165 return (err);
1166 default:
1167 return (TIFFReadDirEntryErrType);
1168 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001169}
1170
kumarashishg826308d2023-06-23 13:21:22 +00001171static enum TIFFReadDirEntryErr
1172TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001173{
kumarashishg826308d2023-06-23 13:21:22 +00001174 enum TIFFReadDirEntryErr err;
1175 if (direntry->tdir_count != 1)
1176 return (TIFFReadDirEntryErrCount);
1177 switch (direntry->tdir_type)
1178 {
1179 case TIFF_LONG:
1180 case TIFF_IFD:
1181 {
1182 uint32_t m;
1183 TIFFReadDirEntryCheckedLong(tif, direntry, &m);
1184 *value = (uint64_t)m;
1185 return (TIFFReadDirEntryErrOk);
1186 }
1187 case TIFF_LONG8:
1188 case TIFF_IFD8:
1189 err = TIFFReadDirEntryCheckedLong8(tif, direntry, value);
1190 return (err);
1191 default:
1192 return (TIFFReadDirEntryErrType);
1193 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001194}
1195
Haibo Huang49cc9302020-04-27 16:14:24 -07001196#define INITIAL_THRESHOLD (1024 * 1024)
1197#define THRESHOLD_MULTIPLIER 10
kumarashishg826308d2023-06-23 13:21:22 +00001198#define MAX_THRESHOLD \
1199 (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \
1200 INITIAL_THRESHOLD)
Haibo Huang49cc9302020-04-27 16:14:24 -07001201
kumarashishg826308d2023-06-23 13:21:22 +00001202static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
1203 uint64_t offset,
1204 tmsize_t size,
1205 void **pdest)
Haibo Huang49cc9302020-04-27 16:14:24 -07001206{
1207#if SIZEOF_SIZE_T == 8
kumarashishg826308d2023-06-23 13:21:22 +00001208 tmsize_t threshold = INITIAL_THRESHOLD;
Haibo Huang49cc9302020-04-27 16:14:24 -07001209#endif
kumarashishg826308d2023-06-23 13:21:22 +00001210 tmsize_t already_read = 0;
Haibo Huang49cc9302020-04-27 16:14:24 -07001211
kumarashishg826308d2023-06-23 13:21:22 +00001212 assert(!isMapped(tif));
Haibo Huang49cc9302020-04-27 16:14:24 -07001213
kumarashishg826308d2023-06-23 13:21:22 +00001214 if (!SeekOK(tif, offset))
1215 return (TIFFReadDirEntryErrIo);
Haibo Huang49cc9302020-04-27 16:14:24 -07001216
kumarashishg826308d2023-06-23 13:21:22 +00001217 /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
1218 /* so as to avoid allocating too much memory in case the file is too */
1219 /* short. We could ask for the file size, but this might be */
1220 /* expensive with some I/O layers (think of reading a gzipped file) */
1221 /* Restrict to 64 bit processes, so as to avoid reallocs() */
1222 /* on 32 bit processes where virtual memory is scarce. */
1223 while (already_read < size)
1224 {
1225 void *new_dest;
1226 tmsize_t bytes_read;
1227 tmsize_t to_read = size - already_read;
Haibo Huang49cc9302020-04-27 16:14:24 -07001228#if SIZEOF_SIZE_T == 8
kumarashishg826308d2023-06-23 13:21:22 +00001229 if (to_read >= threshold && threshold < MAX_THRESHOLD)
1230 {
1231 to_read = threshold;
1232 threshold *= THRESHOLD_MULTIPLIER;
1233 }
Haibo Huang49cc9302020-04-27 16:14:24 -07001234#endif
1235
kumarashishg826308d2023-06-23 13:21:22 +00001236 new_dest =
1237 (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read);
1238 if (new_dest == NULL)
1239 {
1240 TIFFErrorExtR(tif, tif->tif_name,
1241 "Failed to allocate memory for %s "
1242 "(%" TIFF_SSIZE_FORMAT
1243 " elements of %" TIFF_SSIZE_FORMAT " bytes each)",
1244 "TIFFReadDirEntryArray", (tmsize_t)1,
1245 already_read + to_read);
1246 return TIFFReadDirEntryErrAlloc;
1247 }
1248 *pdest = new_dest;
Haibo Huang49cc9302020-04-27 16:14:24 -07001249
kumarashishg826308d2023-06-23 13:21:22 +00001250 bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read);
1251 already_read += bytes_read;
1252 if (bytes_read != to_read)
1253 {
1254 return TIFFReadDirEntryErrIo;
1255 }
1256 }
1257 return TIFFReadDirEntryErrOk;
1258}
1259
1260/* Caution: if raising that value, make sure int32 / uint32 overflows can't
1261 * occur elsewhere */
1262#define MAX_SIZE_TAG_DATA 2147483647U
1263
1264static enum TIFFReadDirEntryErr
1265TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
1266 uint32_t *count, uint32_t desttypesize,
1267 void **value, uint64_t maxcount)
1268{
1269 int typesize;
1270 uint32_t datasize;
1271 void *data;
1272 uint64_t target_count64;
1273 int original_datasize_clamped;
1274 typesize = TIFFDataWidth(direntry->tdir_type);
1275
1276 target_count64 =
1277 (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count;
1278
1279 if ((target_count64 == 0) || (typesize == 0))
1280 {
1281 *value = 0;
1282 return (TIFFReadDirEntryErrOk);
1283 }
1284 (void)desttypesize;
1285
1286 /* We just want to know if the original tag size is more than 4 bytes
1287 * (classic TIFF) or 8 bytes (BigTIFF)
1288 */
1289 original_datasize_clamped =
1290 ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) *
1291 typesize;
1292
1293 /*
1294 * As a sanity check, make sure we have no more than a 2GB tag array
1295 * in either the current data type or the dest data type. This also
1296 * avoids problems with overflow of tmsize_t on 32bit systems.
1297 */
1298 if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64)
1299 return (TIFFReadDirEntryErrSizesan);
1300 if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64)
1301 return (TIFFReadDirEntryErrSizesan);
1302
1303 *count = (uint32_t)target_count64;
1304 datasize = (*count) * typesize;
1305 assert((tmsize_t)datasize > 0);
1306
1307 if (isMapped(tif) && datasize > (uint64_t)tif->tif_size)
1308 return TIFFReadDirEntryErrIo;
1309
1310 if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) ||
1311 (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4)))
1312 {
1313 data = NULL;
1314 }
1315 else
1316 {
1317 data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
1318 if (data == 0)
1319 return (TIFFReadDirEntryErrAlloc);
1320 }
1321 if (!(tif->tif_flags & TIFF_BIGTIFF))
1322 {
1323 /* Only the condition on original_datasize_clamped. The second
1324 * one is implied, but Coverity Scan cannot see it. */
1325 if (original_datasize_clamped <= 4 && datasize <= 4)
1326 _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
1327 else
1328 {
1329 enum TIFFReadDirEntryErr err;
1330 uint32_t offset = direntry->tdir_offset.toff_long;
1331 if (tif->tif_flags & TIFF_SWAB)
1332 TIFFSwabLong(&offset);
1333 if (isMapped(tif))
1334 err = TIFFReadDirEntryData(tif, (uint64_t)offset,
1335 (tmsize_t)datasize, data);
1336 else
1337 err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
1338 (tmsize_t)datasize, &data);
1339 if (err != TIFFReadDirEntryErrOk)
1340 {
1341 _TIFFfreeExt(tif, data);
1342 return (err);
Haibo Huang49cc9302020-04-27 16:14:24 -07001343 }
1344 }
kumarashishg826308d2023-06-23 13:21:22 +00001345 }
1346 else
1347 {
1348 /* See above comment for the Classic TIFF case */
1349 if (original_datasize_clamped <= 8 && datasize <= 8)
1350 _TIFFmemcpy(data, &direntry->tdir_offset, datasize);
1351 else
1352 {
1353 enum TIFFReadDirEntryErr err;
1354 uint64_t offset = direntry->tdir_offset.toff_long8;
1355 if (tif->tif_flags & TIFF_SWAB)
1356 TIFFSwabLong8(&offset);
1357 if (isMapped(tif))
1358 err = TIFFReadDirEntryData(tif, (uint64_t)offset,
1359 (tmsize_t)datasize, data);
1360 else
1361 err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset,
1362 (tmsize_t)datasize, &data);
1363 if (err != TIFFReadDirEntryErrOk)
1364 {
1365 _TIFFfreeExt(tif, data);
1366 return (err);
1367 }
1368 }
1369 }
1370 *value = data;
1371 return (TIFFReadDirEntryErrOk);
Haibo Huang49cc9302020-04-27 16:14:24 -07001372}
1373
kumarashishg826308d2023-06-23 13:21:22 +00001374static enum TIFFReadDirEntryErr
1375TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
1376 uint32_t desttypesize, void **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001377{
kumarashishg826308d2023-06-23 13:21:22 +00001378 return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize,
1379 value, ~((uint64_t)0));
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001380}
1381
kumarashishg826308d2023-06-23 13:21:22 +00001382static enum TIFFReadDirEntryErr
1383TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
Haibo Huang49cc9302020-04-27 16:14:24 -07001384{
kumarashishg826308d2023-06-23 13:21:22 +00001385 enum TIFFReadDirEntryErr err;
1386 uint32_t count;
1387 void *origdata;
1388 uint8_t *data;
1389 switch (direntry->tdir_type)
1390 {
1391 case TIFF_ASCII:
1392 case TIFF_UNDEFINED:
1393 case TIFF_BYTE:
1394 case TIFF_SBYTE:
1395 case TIFF_SHORT:
1396 case TIFF_SSHORT:
1397 case TIFF_LONG:
1398 case TIFF_SLONG:
1399 case TIFF_LONG8:
1400 case TIFF_SLONG8:
1401 break;
1402 default:
1403 return (TIFFReadDirEntryErrType);
1404 }
1405 err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
1406 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1407 {
1408 *value = 0;
1409 return (err);
1410 }
1411 switch (direntry->tdir_type)
1412 {
1413 case TIFF_ASCII:
1414 case TIFF_UNDEFINED:
1415 case TIFF_BYTE:
1416 *value = (uint8_t *)origdata;
1417 return (TIFFReadDirEntryErrOk);
1418 case TIFF_SBYTE:
1419 {
1420 int8_t *m;
1421 uint32_t n;
1422 m = (int8_t *)origdata;
1423 for (n = 0; n < count; n++)
1424 {
1425 err = TIFFReadDirEntryCheckRangeByteSbyte(*m);
1426 if (err != TIFFReadDirEntryErrOk)
1427 {
1428 _TIFFfreeExt(tif, origdata);
1429 return (err);
1430 }
1431 m++;
1432 }
1433 *value = (uint8_t *)origdata;
1434 return (TIFFReadDirEntryErrOk);
1435 }
1436 }
1437 data = (uint8_t *)_TIFFmallocExt(tif, count);
1438 if (data == 0)
1439 {
1440 _TIFFfreeExt(tif, origdata);
1441 return (TIFFReadDirEntryErrAlloc);
1442 }
1443 switch (direntry->tdir_type)
1444 {
1445 case TIFF_SHORT:
1446 {
1447 uint16_t *ma;
1448 uint8_t *mb;
1449 uint32_t n;
1450 ma = (uint16_t *)origdata;
1451 mb = data;
1452 for (n = 0; n < count; n++)
1453 {
1454 if (tif->tif_flags & TIFF_SWAB)
1455 TIFFSwabShort(ma);
1456 err = TIFFReadDirEntryCheckRangeByteShort(*ma);
1457 if (err != TIFFReadDirEntryErrOk)
1458 break;
1459 *mb++ = (uint8_t)(*ma++);
1460 }
1461 }
1462 break;
1463 case TIFF_SSHORT:
1464 {
1465 int16_t *ma;
1466 uint8_t *mb;
1467 uint32_t n;
1468 ma = (int16_t *)origdata;
1469 mb = data;
1470 for (n = 0; n < count; n++)
1471 {
1472 if (tif->tif_flags & TIFF_SWAB)
1473 TIFFSwabShort((uint16_t *)ma);
1474 err = TIFFReadDirEntryCheckRangeByteSshort(*ma);
1475 if (err != TIFFReadDirEntryErrOk)
1476 break;
1477 *mb++ = (uint8_t)(*ma++);
1478 }
1479 }
1480 break;
1481 case TIFF_LONG:
1482 {
1483 uint32_t *ma;
1484 uint8_t *mb;
1485 uint32_t n;
1486 ma = (uint32_t *)origdata;
1487 mb = data;
1488 for (n = 0; n < count; n++)
1489 {
1490 if (tif->tif_flags & TIFF_SWAB)
1491 TIFFSwabLong(ma);
1492 err = TIFFReadDirEntryCheckRangeByteLong(*ma);
1493 if (err != TIFFReadDirEntryErrOk)
1494 break;
1495 *mb++ = (uint8_t)(*ma++);
1496 }
1497 }
1498 break;
1499 case TIFF_SLONG:
1500 {
1501 int32_t *ma;
1502 uint8_t *mb;
1503 uint32_t n;
1504 ma = (int32_t *)origdata;
1505 mb = data;
1506 for (n = 0; n < count; n++)
1507 {
1508 if (tif->tif_flags & TIFF_SWAB)
1509 TIFFSwabLong((uint32_t *)ma);
1510 err = TIFFReadDirEntryCheckRangeByteSlong(*ma);
1511 if (err != TIFFReadDirEntryErrOk)
1512 break;
1513 *mb++ = (uint8_t)(*ma++);
1514 }
1515 }
1516 break;
1517 case TIFF_LONG8:
1518 {
1519 uint64_t *ma;
1520 uint8_t *mb;
1521 uint32_t n;
1522 ma = (uint64_t *)origdata;
1523 mb = data;
1524 for (n = 0; n < count; n++)
1525 {
1526 if (tif->tif_flags & TIFF_SWAB)
1527 TIFFSwabLong8(ma);
1528 err = TIFFReadDirEntryCheckRangeByteLong8(*ma);
1529 if (err != TIFFReadDirEntryErrOk)
1530 break;
1531 *mb++ = (uint8_t)(*ma++);
1532 }
1533 }
1534 break;
1535 case TIFF_SLONG8:
1536 {
1537 int64_t *ma;
1538 uint8_t *mb;
1539 uint32_t n;
1540 ma = (int64_t *)origdata;
1541 mb = data;
1542 for (n = 0; n < count; n++)
1543 {
1544 if (tif->tif_flags & TIFF_SWAB)
1545 TIFFSwabLong8((uint64_t *)ma);
1546 err = TIFFReadDirEntryCheckRangeByteSlong8(*ma);
1547 if (err != TIFFReadDirEntryErrOk)
1548 break;
1549 *mb++ = (uint8_t)(*ma++);
1550 }
1551 }
1552 break;
1553 }
1554 _TIFFfreeExt(tif, origdata);
1555 if (err != TIFFReadDirEntryErrOk)
1556 {
1557 _TIFFfreeExt(tif, data);
1558 return (err);
1559 }
1560 *value = data;
1561 return (TIFFReadDirEntryErrOk);
Haibo Huang49cc9302020-04-27 16:14:24 -07001562}
1563
kumarashishg826308d2023-06-23 13:21:22 +00001564static enum TIFFReadDirEntryErr
1565TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001566{
kumarashishg826308d2023-06-23 13:21:22 +00001567 enum TIFFReadDirEntryErr err;
1568 uint32_t count;
1569 void *origdata;
1570 int8_t *data;
1571 switch (direntry->tdir_type)
1572 {
1573 case TIFF_UNDEFINED:
1574 case TIFF_BYTE:
1575 case TIFF_SBYTE:
1576 case TIFF_SHORT:
1577 case TIFF_SSHORT:
1578 case TIFF_LONG:
1579 case TIFF_SLONG:
1580 case TIFF_LONG8:
1581 case TIFF_SLONG8:
1582 break;
1583 default:
1584 return (TIFFReadDirEntryErrType);
1585 }
1586 err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata);
1587 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1588 {
1589 *value = 0;
1590 return (err);
1591 }
1592 switch (direntry->tdir_type)
1593 {
1594 case TIFF_UNDEFINED:
1595 case TIFF_BYTE:
1596 {
1597 uint8_t *m;
1598 uint32_t n;
1599 m = (uint8_t *)origdata;
1600 for (n = 0; n < count; n++)
1601 {
1602 err = TIFFReadDirEntryCheckRangeSbyteByte(*m);
1603 if (err != TIFFReadDirEntryErrOk)
1604 {
1605 _TIFFfreeExt(tif, origdata);
1606 return (err);
1607 }
1608 m++;
1609 }
1610 *value = (int8_t *)origdata;
1611 return (TIFFReadDirEntryErrOk);
1612 }
1613 case TIFF_SBYTE:
1614 *value = (int8_t *)origdata;
1615 return (TIFFReadDirEntryErrOk);
1616 }
1617 data = (int8_t *)_TIFFmallocExt(tif, count);
1618 if (data == 0)
1619 {
1620 _TIFFfreeExt(tif, origdata);
1621 return (TIFFReadDirEntryErrAlloc);
1622 }
1623 switch (direntry->tdir_type)
1624 {
1625 case TIFF_SHORT:
1626 {
1627 uint16_t *ma;
1628 int8_t *mb;
1629 uint32_t n;
1630 ma = (uint16_t *)origdata;
1631 mb = data;
1632 for (n = 0; n < count; n++)
1633 {
1634 if (tif->tif_flags & TIFF_SWAB)
1635 TIFFSwabShort(ma);
1636 err = TIFFReadDirEntryCheckRangeSbyteShort(*ma);
1637 if (err != TIFFReadDirEntryErrOk)
1638 break;
1639 *mb++ = (int8_t)(*ma++);
1640 }
1641 }
1642 break;
1643 case TIFF_SSHORT:
1644 {
1645 int16_t *ma;
1646 int8_t *mb;
1647 uint32_t n;
1648 ma = (int16_t *)origdata;
1649 mb = data;
1650 for (n = 0; n < count; n++)
1651 {
1652 if (tif->tif_flags & TIFF_SWAB)
1653 TIFFSwabShort((uint16_t *)ma);
1654 err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
1655 if (err != TIFFReadDirEntryErrOk)
1656 break;
1657 *mb++ = (int8_t)(*ma++);
1658 }
1659 }
1660 break;
1661 case TIFF_LONG:
1662 {
1663 uint32_t *ma;
1664 int8_t *mb;
1665 uint32_t n;
1666 ma = (uint32_t *)origdata;
1667 mb = data;
1668 for (n = 0; n < count; n++)
1669 {
1670 if (tif->tif_flags & TIFF_SWAB)
1671 TIFFSwabLong(ma);
1672 err = TIFFReadDirEntryCheckRangeSbyteLong(*ma);
1673 if (err != TIFFReadDirEntryErrOk)
1674 break;
1675 *mb++ = (int8_t)(*ma++);
1676 }
1677 }
1678 break;
1679 case TIFF_SLONG:
1680 {
1681 int32_t *ma;
1682 int8_t *mb;
1683 uint32_t n;
1684 ma = (int32_t *)origdata;
1685 mb = data;
1686 for (n = 0; n < count; n++)
1687 {
1688 if (tif->tif_flags & TIFF_SWAB)
1689 TIFFSwabLong((uint32_t *)ma);
1690 err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
1691 if (err != TIFFReadDirEntryErrOk)
1692 break;
1693 *mb++ = (int8_t)(*ma++);
1694 }
1695 }
1696 break;
1697 case TIFF_LONG8:
1698 {
1699 uint64_t *ma;
1700 int8_t *mb;
1701 uint32_t n;
1702 ma = (uint64_t *)origdata;
1703 mb = data;
1704 for (n = 0; n < count; n++)
1705 {
1706 if (tif->tif_flags & TIFF_SWAB)
1707 TIFFSwabLong8(ma);
1708 err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
1709 if (err != TIFFReadDirEntryErrOk)
1710 break;
1711 *mb++ = (int8_t)(*ma++);
1712 }
1713 }
1714 break;
1715 case TIFF_SLONG8:
1716 {
1717 int64_t *ma;
1718 int8_t *mb;
1719 uint32_t n;
1720 ma = (int64_t *)origdata;
1721 mb = data;
1722 for (n = 0; n < count; n++)
1723 {
1724 if (tif->tif_flags & TIFF_SWAB)
1725 TIFFSwabLong8((uint64_t *)ma);
1726 err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
1727 if (err != TIFFReadDirEntryErrOk)
1728 break;
1729 *mb++ = (int8_t)(*ma++);
1730 }
1731 }
1732 break;
1733 }
1734 _TIFFfreeExt(tif, origdata);
1735 if (err != TIFFReadDirEntryErrOk)
1736 {
1737 _TIFFfreeExt(tif, data);
1738 return (err);
1739 }
1740 *value = data;
1741 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001742}
1743
kumarashishg826308d2023-06-23 13:21:22 +00001744static enum TIFFReadDirEntryErr
1745TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001746{
kumarashishg826308d2023-06-23 13:21:22 +00001747 enum TIFFReadDirEntryErr err;
1748 uint32_t count;
1749 void *origdata;
1750 uint16_t *data;
1751 switch (direntry->tdir_type)
1752 {
1753 case TIFF_BYTE:
1754 case TIFF_SBYTE:
1755 case TIFF_SHORT:
1756 case TIFF_SSHORT:
1757 case TIFF_LONG:
1758 case TIFF_SLONG:
1759 case TIFF_LONG8:
1760 case TIFF_SLONG8:
1761 break;
1762 default:
1763 return (TIFFReadDirEntryErrType);
1764 }
1765 err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
1766 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1767 {
1768 *value = 0;
1769 return (err);
1770 }
1771 switch (direntry->tdir_type)
1772 {
1773 case TIFF_SHORT:
1774 *value = (uint16_t *)origdata;
1775 if (tif->tif_flags & TIFF_SWAB)
1776 TIFFSwabArrayOfShort(*value, count);
1777 return (TIFFReadDirEntryErrOk);
1778 case TIFF_SSHORT:
1779 {
1780 int16_t *m;
1781 uint32_t n;
1782 m = (int16_t *)origdata;
1783 for (n = 0; n < count; n++)
1784 {
1785 if (tif->tif_flags & TIFF_SWAB)
1786 TIFFSwabShort((uint16_t *)m);
1787 err = TIFFReadDirEntryCheckRangeShortSshort(*m);
1788 if (err != TIFFReadDirEntryErrOk)
1789 {
1790 _TIFFfreeExt(tif, origdata);
1791 return (err);
1792 }
1793 m++;
1794 }
1795 *value = (uint16_t *)origdata;
1796 return (TIFFReadDirEntryErrOk);
1797 }
1798 }
1799 data = (uint16_t *)_TIFFmallocExt(tif, count * 2);
1800 if (data == 0)
1801 {
1802 _TIFFfreeExt(tif, origdata);
1803 return (TIFFReadDirEntryErrAlloc);
1804 }
1805 switch (direntry->tdir_type)
1806 {
1807 case TIFF_BYTE:
1808 {
1809 uint8_t *ma;
1810 uint16_t *mb;
1811 uint32_t n;
1812 ma = (uint8_t *)origdata;
1813 mb = data;
1814 for (n = 0; n < count; n++)
1815 *mb++ = (uint16_t)(*ma++);
1816 }
1817 break;
1818 case TIFF_SBYTE:
1819 {
1820 int8_t *ma;
1821 uint16_t *mb;
1822 uint32_t n;
1823 ma = (int8_t *)origdata;
1824 mb = data;
1825 for (n = 0; n < count; n++)
1826 {
1827 err = TIFFReadDirEntryCheckRangeShortSbyte(*ma);
1828 if (err != TIFFReadDirEntryErrOk)
1829 break;
1830 *mb++ = (uint16_t)(*ma++);
1831 }
1832 }
1833 break;
1834 case TIFF_LONG:
1835 {
1836 uint32_t *ma;
1837 uint16_t *mb;
1838 uint32_t n;
1839 ma = (uint32_t *)origdata;
1840 mb = data;
1841 for (n = 0; n < count; n++)
1842 {
1843 if (tif->tif_flags & TIFF_SWAB)
1844 TIFFSwabLong(ma);
1845 err = TIFFReadDirEntryCheckRangeShortLong(*ma);
1846 if (err != TIFFReadDirEntryErrOk)
1847 break;
1848 *mb++ = (uint16_t)(*ma++);
1849 }
1850 }
1851 break;
1852 case TIFF_SLONG:
1853 {
1854 int32_t *ma;
1855 uint16_t *mb;
1856 uint32_t n;
1857 ma = (int32_t *)origdata;
1858 mb = data;
1859 for (n = 0; n < count; n++)
1860 {
1861 if (tif->tif_flags & TIFF_SWAB)
1862 TIFFSwabLong((uint32_t *)ma);
1863 err = TIFFReadDirEntryCheckRangeShortSlong(*ma);
1864 if (err != TIFFReadDirEntryErrOk)
1865 break;
1866 *mb++ = (uint16_t)(*ma++);
1867 }
1868 }
1869 break;
1870 case TIFF_LONG8:
1871 {
1872 uint64_t *ma;
1873 uint16_t *mb;
1874 uint32_t n;
1875 ma = (uint64_t *)origdata;
1876 mb = data;
1877 for (n = 0; n < count; n++)
1878 {
1879 if (tif->tif_flags & TIFF_SWAB)
1880 TIFFSwabLong8(ma);
1881 err = TIFFReadDirEntryCheckRangeShortLong8(*ma);
1882 if (err != TIFFReadDirEntryErrOk)
1883 break;
1884 *mb++ = (uint16_t)(*ma++);
1885 }
1886 }
1887 break;
1888 case TIFF_SLONG8:
1889 {
1890 int64_t *ma;
1891 uint16_t *mb;
1892 uint32_t n;
1893 ma = (int64_t *)origdata;
1894 mb = data;
1895 for (n = 0; n < count; n++)
1896 {
1897 if (tif->tif_flags & TIFF_SWAB)
1898 TIFFSwabLong8((uint64_t *)ma);
1899 err = TIFFReadDirEntryCheckRangeShortSlong8(*ma);
1900 if (err != TIFFReadDirEntryErrOk)
1901 break;
1902 *mb++ = (uint16_t)(*ma++);
1903 }
1904 }
1905 break;
1906 }
1907 _TIFFfreeExt(tif, origdata);
1908 if (err != TIFFReadDirEntryErrOk)
1909 {
1910 _TIFFfreeExt(tif, data);
1911 return (err);
1912 }
1913 *value = data;
1914 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001915}
1916
kumarashishg826308d2023-06-23 13:21:22 +00001917static enum TIFFReadDirEntryErr
1918TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08001919{
kumarashishg826308d2023-06-23 13:21:22 +00001920 enum TIFFReadDirEntryErr err;
1921 uint32_t count;
1922 void *origdata;
1923 int16_t *data;
1924 switch (direntry->tdir_type)
1925 {
1926 case TIFF_BYTE:
1927 case TIFF_SBYTE:
1928 case TIFF_SHORT:
1929 case TIFF_SSHORT:
1930 case TIFF_LONG:
1931 case TIFF_SLONG:
1932 case TIFF_LONG8:
1933 case TIFF_SLONG8:
1934 break;
1935 default:
1936 return (TIFFReadDirEntryErrType);
1937 }
1938 err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata);
1939 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
1940 {
1941 *value = 0;
1942 return (err);
1943 }
1944 switch (direntry->tdir_type)
1945 {
1946 case TIFF_SHORT:
1947 {
1948 uint16_t *m;
1949 uint32_t n;
1950 m = (uint16_t *)origdata;
1951 for (n = 0; n < count; n++)
1952 {
1953 if (tif->tif_flags & TIFF_SWAB)
1954 TIFFSwabShort(m);
1955 err = TIFFReadDirEntryCheckRangeSshortShort(*m);
1956 if (err != TIFFReadDirEntryErrOk)
1957 {
1958 _TIFFfreeExt(tif, origdata);
1959 return (err);
1960 }
1961 m++;
1962 }
1963 *value = (int16_t *)origdata;
1964 return (TIFFReadDirEntryErrOk);
1965 }
1966 case TIFF_SSHORT:
1967 *value = (int16_t *)origdata;
1968 if (tif->tif_flags & TIFF_SWAB)
1969 TIFFSwabArrayOfShort((uint16_t *)(*value), count);
1970 return (TIFFReadDirEntryErrOk);
1971 }
1972 data = (int16_t *)_TIFFmallocExt(tif, count * 2);
1973 if (data == 0)
1974 {
1975 _TIFFfreeExt(tif, origdata);
1976 return (TIFFReadDirEntryErrAlloc);
1977 }
1978 switch (direntry->tdir_type)
1979 {
1980 case TIFF_BYTE:
1981 {
1982 uint8_t *ma;
1983 int16_t *mb;
1984 uint32_t n;
1985 ma = (uint8_t *)origdata;
1986 mb = data;
1987 for (n = 0; n < count; n++)
1988 *mb++ = (int16_t)(*ma++);
1989 }
1990 break;
1991 case TIFF_SBYTE:
1992 {
1993 int8_t *ma;
1994 int16_t *mb;
1995 uint32_t n;
1996 ma = (int8_t *)origdata;
1997 mb = data;
1998 for (n = 0; n < count; n++)
1999 *mb++ = (int16_t)(*ma++);
2000 }
2001 break;
2002 case TIFF_LONG:
2003 {
2004 uint32_t *ma;
2005 int16_t *mb;
2006 uint32_t n;
2007 ma = (uint32_t *)origdata;
2008 mb = data;
2009 for (n = 0; n < count; n++)
2010 {
2011 if (tif->tif_flags & TIFF_SWAB)
2012 TIFFSwabLong(ma);
2013 err = TIFFReadDirEntryCheckRangeSshortLong(*ma);
2014 if (err != TIFFReadDirEntryErrOk)
2015 break;
2016 *mb++ = (int16_t)(*ma++);
2017 }
2018 }
2019 break;
2020 case TIFF_SLONG:
2021 {
2022 int32_t *ma;
2023 int16_t *mb;
2024 uint32_t n;
2025 ma = (int32_t *)origdata;
2026 mb = data;
2027 for (n = 0; n < count; n++)
2028 {
2029 if (tif->tif_flags & TIFF_SWAB)
2030 TIFFSwabLong((uint32_t *)ma);
2031 err = TIFFReadDirEntryCheckRangeSshortSlong(*ma);
2032 if (err != TIFFReadDirEntryErrOk)
2033 break;
2034 *mb++ = (int16_t)(*ma++);
2035 }
2036 }
2037 break;
2038 case TIFF_LONG8:
2039 {
2040 uint64_t *ma;
2041 int16_t *mb;
2042 uint32_t n;
2043 ma = (uint64_t *)origdata;
2044 mb = data;
2045 for (n = 0; n < count; n++)
2046 {
2047 if (tif->tif_flags & TIFF_SWAB)
2048 TIFFSwabLong8(ma);
2049 err = TIFFReadDirEntryCheckRangeSshortLong8(*ma);
2050 if (err != TIFFReadDirEntryErrOk)
2051 break;
2052 *mb++ = (int16_t)(*ma++);
2053 }
2054 }
2055 break;
2056 case TIFF_SLONG8:
2057 {
2058 int64_t *ma;
2059 int16_t *mb;
2060 uint32_t n;
2061 ma = (int64_t *)origdata;
2062 mb = data;
2063 for (n = 0; n < count; n++)
2064 {
2065 if (tif->tif_flags & TIFF_SWAB)
2066 TIFFSwabLong8((uint64_t *)ma);
2067 err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
2068 if (err != TIFFReadDirEntryErrOk)
2069 break;
2070 *mb++ = (int16_t)(*ma++);
2071 }
2072 }
2073 break;
2074 }
2075 _TIFFfreeExt(tif, origdata);
2076 if (err != TIFFReadDirEntryErrOk)
2077 {
2078 _TIFFfreeExt(tif, data);
2079 return (err);
2080 }
2081 *value = data;
2082 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002083}
2084
kumarashishg826308d2023-06-23 13:21:22 +00002085static enum TIFFReadDirEntryErr
2086TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002087{
kumarashishg826308d2023-06-23 13:21:22 +00002088 enum TIFFReadDirEntryErr err;
2089 uint32_t count;
2090 void *origdata;
2091 uint32_t *data;
2092 switch (direntry->tdir_type)
2093 {
2094 case TIFF_BYTE:
2095 case TIFF_SBYTE:
2096 case TIFF_SHORT:
2097 case TIFF_SSHORT:
2098 case TIFF_LONG:
2099 case TIFF_SLONG:
2100 case TIFF_LONG8:
2101 case TIFF_SLONG8:
2102 break;
2103 default:
2104 return (TIFFReadDirEntryErrType);
2105 }
2106 err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2107 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2108 {
2109 *value = 0;
2110 return (err);
2111 }
2112 switch (direntry->tdir_type)
2113 {
2114 case TIFF_LONG:
2115 *value = (uint32_t *)origdata;
2116 if (tif->tif_flags & TIFF_SWAB)
2117 TIFFSwabArrayOfLong(*value, count);
2118 return (TIFFReadDirEntryErrOk);
2119 case TIFF_SLONG:
2120 {
2121 int32_t *m;
2122 uint32_t n;
2123 m = (int32_t *)origdata;
2124 for (n = 0; n < count; n++)
2125 {
2126 if (tif->tif_flags & TIFF_SWAB)
2127 TIFFSwabLong((uint32_t *)m);
2128 err = TIFFReadDirEntryCheckRangeLongSlong(*m);
2129 if (err != TIFFReadDirEntryErrOk)
2130 {
2131 _TIFFfreeExt(tif, origdata);
2132 return (err);
2133 }
2134 m++;
2135 }
2136 *value = (uint32_t *)origdata;
2137 return (TIFFReadDirEntryErrOk);
2138 }
2139 }
2140 data = (uint32_t *)_TIFFmallocExt(tif, count * 4);
2141 if (data == 0)
2142 {
2143 _TIFFfreeExt(tif, origdata);
2144 return (TIFFReadDirEntryErrAlloc);
2145 }
2146 switch (direntry->tdir_type)
2147 {
2148 case TIFF_BYTE:
2149 {
2150 uint8_t *ma;
2151 uint32_t *mb;
2152 uint32_t n;
2153 ma = (uint8_t *)origdata;
2154 mb = data;
2155 for (n = 0; n < count; n++)
2156 *mb++ = (uint32_t)(*ma++);
2157 }
2158 break;
2159 case TIFF_SBYTE:
2160 {
2161 int8_t *ma;
2162 uint32_t *mb;
2163 uint32_t n;
2164 ma = (int8_t *)origdata;
2165 mb = data;
2166 for (n = 0; n < count; n++)
2167 {
2168 err = TIFFReadDirEntryCheckRangeLongSbyte(*ma);
2169 if (err != TIFFReadDirEntryErrOk)
2170 break;
2171 *mb++ = (uint32_t)(*ma++);
2172 }
2173 }
2174 break;
2175 case TIFF_SHORT:
2176 {
2177 uint16_t *ma;
2178 uint32_t *mb;
2179 uint32_t n;
2180 ma = (uint16_t *)origdata;
2181 mb = data;
2182 for (n = 0; n < count; n++)
2183 {
2184 if (tif->tif_flags & TIFF_SWAB)
2185 TIFFSwabShort(ma);
2186 *mb++ = (uint32_t)(*ma++);
2187 }
2188 }
2189 break;
2190 case TIFF_SSHORT:
2191 {
2192 int16_t *ma;
2193 uint32_t *mb;
2194 uint32_t n;
2195 ma = (int16_t *)origdata;
2196 mb = data;
2197 for (n = 0; n < count; n++)
2198 {
2199 if (tif->tif_flags & TIFF_SWAB)
2200 TIFFSwabShort((uint16_t *)ma);
2201 err = TIFFReadDirEntryCheckRangeLongSshort(*ma);
2202 if (err != TIFFReadDirEntryErrOk)
2203 break;
2204 *mb++ = (uint32_t)(*ma++);
2205 }
2206 }
2207 break;
2208 case TIFF_LONG8:
2209 {
2210 uint64_t *ma;
2211 uint32_t *mb;
2212 uint32_t n;
2213 ma = (uint64_t *)origdata;
2214 mb = data;
2215 for (n = 0; n < count; n++)
2216 {
2217 if (tif->tif_flags & TIFF_SWAB)
2218 TIFFSwabLong8(ma);
2219 err = TIFFReadDirEntryCheckRangeLongLong8(*ma);
2220 if (err != TIFFReadDirEntryErrOk)
2221 break;
2222 *mb++ = (uint32_t)(*ma++);
2223 }
2224 }
2225 break;
2226 case TIFF_SLONG8:
2227 {
2228 int64_t *ma;
2229 uint32_t *mb;
2230 uint32_t n;
2231 ma = (int64_t *)origdata;
2232 mb = data;
2233 for (n = 0; n < count; n++)
2234 {
2235 if (tif->tif_flags & TIFF_SWAB)
2236 TIFFSwabLong8((uint64_t *)ma);
2237 err = TIFFReadDirEntryCheckRangeLongSlong8(*ma);
2238 if (err != TIFFReadDirEntryErrOk)
2239 break;
2240 *mb++ = (uint32_t)(*ma++);
2241 }
2242 }
2243 break;
2244 }
2245 _TIFFfreeExt(tif, origdata);
2246 if (err != TIFFReadDirEntryErrOk)
2247 {
2248 _TIFFfreeExt(tif, data);
2249 return (err);
2250 }
2251 *value = data;
2252 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002253}
2254
kumarashishg826308d2023-06-23 13:21:22 +00002255static enum TIFFReadDirEntryErr
2256TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002257{
kumarashishg826308d2023-06-23 13:21:22 +00002258 enum TIFFReadDirEntryErr err;
2259 uint32_t count;
2260 void *origdata;
2261 int32_t *data;
2262 switch (direntry->tdir_type)
2263 {
2264 case TIFF_BYTE:
2265 case TIFF_SBYTE:
2266 case TIFF_SHORT:
2267 case TIFF_SSHORT:
2268 case TIFF_LONG:
2269 case TIFF_SLONG:
2270 case TIFF_LONG8:
2271 case TIFF_SLONG8:
2272 break;
2273 default:
2274 return (TIFFReadDirEntryErrType);
2275 }
2276 err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2277 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2278 {
2279 *value = 0;
2280 return (err);
2281 }
2282 switch (direntry->tdir_type)
2283 {
2284 case TIFF_LONG:
2285 {
2286 uint32_t *m;
2287 uint32_t n;
2288 m = (uint32_t *)origdata;
2289 for (n = 0; n < count; n++)
2290 {
2291 if (tif->tif_flags & TIFF_SWAB)
2292 TIFFSwabLong((uint32_t *)m);
2293 err = TIFFReadDirEntryCheckRangeSlongLong(*m);
2294 if (err != TIFFReadDirEntryErrOk)
2295 {
2296 _TIFFfreeExt(tif, origdata);
2297 return (err);
2298 }
2299 m++;
2300 }
2301 *value = (int32_t *)origdata;
2302 return (TIFFReadDirEntryErrOk);
2303 }
2304 case TIFF_SLONG:
2305 *value = (int32_t *)origdata;
2306 if (tif->tif_flags & TIFF_SWAB)
2307 TIFFSwabArrayOfLong((uint32_t *)(*value), count);
2308 return (TIFFReadDirEntryErrOk);
2309 }
2310 data = (int32_t *)_TIFFmallocExt(tif, count * 4);
2311 if (data == 0)
2312 {
2313 _TIFFfreeExt(tif, origdata);
2314 return (TIFFReadDirEntryErrAlloc);
2315 }
2316 switch (direntry->tdir_type)
2317 {
2318 case TIFF_BYTE:
2319 {
2320 uint8_t *ma;
2321 int32_t *mb;
2322 uint32_t n;
2323 ma = (uint8_t *)origdata;
2324 mb = data;
2325 for (n = 0; n < count; n++)
2326 *mb++ = (int32_t)(*ma++);
2327 }
2328 break;
2329 case TIFF_SBYTE:
2330 {
2331 int8_t *ma;
2332 int32_t *mb;
2333 uint32_t n;
2334 ma = (int8_t *)origdata;
2335 mb = data;
2336 for (n = 0; n < count; n++)
2337 *mb++ = (int32_t)(*ma++);
2338 }
2339 break;
2340 case TIFF_SHORT:
2341 {
2342 uint16_t *ma;
2343 int32_t *mb;
2344 uint32_t n;
2345 ma = (uint16_t *)origdata;
2346 mb = data;
2347 for (n = 0; n < count; n++)
2348 {
2349 if (tif->tif_flags & TIFF_SWAB)
2350 TIFFSwabShort(ma);
2351 *mb++ = (int32_t)(*ma++);
2352 }
2353 }
2354 break;
2355 case TIFF_SSHORT:
2356 {
2357 int16_t *ma;
2358 int32_t *mb;
2359 uint32_t n;
2360 ma = (int16_t *)origdata;
2361 mb = data;
2362 for (n = 0; n < count; n++)
2363 {
2364 if (tif->tif_flags & TIFF_SWAB)
2365 TIFFSwabShort((uint16_t *)ma);
2366 *mb++ = (int32_t)(*ma++);
2367 }
2368 }
2369 break;
2370 case TIFF_LONG8:
2371 {
2372 uint64_t *ma;
2373 int32_t *mb;
2374 uint32_t n;
2375 ma = (uint64_t *)origdata;
2376 mb = data;
2377 for (n = 0; n < count; n++)
2378 {
2379 if (tif->tif_flags & TIFF_SWAB)
2380 TIFFSwabLong8(ma);
2381 err = TIFFReadDirEntryCheckRangeSlongLong8(*ma);
2382 if (err != TIFFReadDirEntryErrOk)
2383 break;
2384 *mb++ = (int32_t)(*ma++);
2385 }
2386 }
2387 break;
2388 case TIFF_SLONG8:
2389 {
2390 int64_t *ma;
2391 int32_t *mb;
2392 uint32_t n;
2393 ma = (int64_t *)origdata;
2394 mb = data;
2395 for (n = 0; n < count; n++)
2396 {
2397 if (tif->tif_flags & TIFF_SWAB)
2398 TIFFSwabLong8((uint64_t *)ma);
2399 err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
2400 if (err != TIFFReadDirEntryErrOk)
2401 break;
2402 *mb++ = (int32_t)(*ma++);
2403 }
2404 }
2405 break;
2406 }
2407 _TIFFfreeExt(tif, origdata);
2408 if (err != TIFFReadDirEntryErrOk)
2409 {
2410 _TIFFfreeExt(tif, data);
2411 return (err);
2412 }
2413 *value = data;
2414 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002415}
2416
kumarashishg826308d2023-06-23 13:21:22 +00002417static enum TIFFReadDirEntryErr
2418TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
2419 uint64_t **value, uint64_t maxcount)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002420{
kumarashishg826308d2023-06-23 13:21:22 +00002421 enum TIFFReadDirEntryErr err;
2422 uint32_t count;
2423 void *origdata;
2424 uint64_t *data;
2425 switch (direntry->tdir_type)
2426 {
2427 case TIFF_BYTE:
2428 case TIFF_SBYTE:
2429 case TIFF_SHORT:
2430 case TIFF_SSHORT:
2431 case TIFF_LONG:
2432 case TIFF_SLONG:
2433 case TIFF_LONG8:
2434 case TIFF_SLONG8:
2435 break;
2436 default:
2437 return (TIFFReadDirEntryErrType);
2438 }
2439 err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata,
2440 maxcount);
2441 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2442 {
2443 *value = 0;
2444 return (err);
2445 }
2446 switch (direntry->tdir_type)
2447 {
2448 case TIFF_LONG8:
2449 *value = (uint64_t *)origdata;
2450 if (tif->tif_flags & TIFF_SWAB)
2451 TIFFSwabArrayOfLong8(*value, count);
2452 return (TIFFReadDirEntryErrOk);
2453 case TIFF_SLONG8:
2454 {
2455 int64_t *m;
2456 uint32_t n;
2457 m = (int64_t *)origdata;
2458 for (n = 0; n < count; n++)
2459 {
2460 if (tif->tif_flags & TIFF_SWAB)
2461 TIFFSwabLong8((uint64_t *)m);
2462 err = TIFFReadDirEntryCheckRangeLong8Slong8(*m);
2463 if (err != TIFFReadDirEntryErrOk)
2464 {
2465 _TIFFfreeExt(tif, origdata);
2466 return (err);
2467 }
2468 m++;
2469 }
2470 *value = (uint64_t *)origdata;
2471 return (TIFFReadDirEntryErrOk);
2472 }
2473 }
2474 data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
2475 if (data == 0)
2476 {
2477 _TIFFfreeExt(tif, origdata);
2478 return (TIFFReadDirEntryErrAlloc);
2479 }
2480 switch (direntry->tdir_type)
2481 {
2482 case TIFF_BYTE:
2483 {
2484 uint8_t *ma;
2485 uint64_t *mb;
2486 uint32_t n;
2487 ma = (uint8_t *)origdata;
2488 mb = data;
2489 for (n = 0; n < count; n++)
2490 *mb++ = (uint64_t)(*ma++);
2491 }
2492 break;
2493 case TIFF_SBYTE:
2494 {
2495 int8_t *ma;
2496 uint64_t *mb;
2497 uint32_t n;
2498 ma = (int8_t *)origdata;
2499 mb = data;
2500 for (n = 0; n < count; n++)
2501 {
2502 err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
2503 if (err != TIFFReadDirEntryErrOk)
2504 break;
2505 *mb++ = (uint64_t)(*ma++);
2506 }
2507 }
2508 break;
2509 case TIFF_SHORT:
2510 {
2511 uint16_t *ma;
2512 uint64_t *mb;
2513 uint32_t n;
2514 ma = (uint16_t *)origdata;
2515 mb = data;
2516 for (n = 0; n < count; n++)
2517 {
2518 if (tif->tif_flags & TIFF_SWAB)
2519 TIFFSwabShort(ma);
2520 *mb++ = (uint64_t)(*ma++);
2521 }
2522 }
2523 break;
2524 case TIFF_SSHORT:
2525 {
2526 int16_t *ma;
2527 uint64_t *mb;
2528 uint32_t n;
2529 ma = (int16_t *)origdata;
2530 mb = data;
2531 for (n = 0; n < count; n++)
2532 {
2533 if (tif->tif_flags & TIFF_SWAB)
2534 TIFFSwabShort((uint16_t *)ma);
2535 err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
2536 if (err != TIFFReadDirEntryErrOk)
2537 break;
2538 *mb++ = (uint64_t)(*ma++);
2539 }
2540 }
2541 break;
2542 case TIFF_LONG:
2543 {
2544 uint32_t *ma;
2545 uint64_t *mb;
2546 uint32_t n;
2547 ma = (uint32_t *)origdata;
2548 mb = data;
2549 for (n = 0; n < count; n++)
2550 {
2551 if (tif->tif_flags & TIFF_SWAB)
2552 TIFFSwabLong(ma);
2553 *mb++ = (uint64_t)(*ma++);
2554 }
2555 }
2556 break;
2557 case TIFF_SLONG:
2558 {
2559 int32_t *ma;
2560 uint64_t *mb;
2561 uint32_t n;
2562 ma = (int32_t *)origdata;
2563 mb = data;
2564 for (n = 0; n < count; n++)
2565 {
2566 if (tif->tif_flags & TIFF_SWAB)
2567 TIFFSwabLong((uint32_t *)ma);
2568 err = TIFFReadDirEntryCheckRangeLong8Slong(*ma);
2569 if (err != TIFFReadDirEntryErrOk)
2570 break;
2571 *mb++ = (uint64_t)(*ma++);
2572 }
2573 }
2574 break;
2575 }
2576 _TIFFfreeExt(tif, origdata);
2577 if (err != TIFFReadDirEntryErrOk)
2578 {
2579 _TIFFfreeExt(tif, data);
2580 return (err);
2581 }
2582 *value = data;
2583 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002584}
2585
kumarashishg826308d2023-06-23 13:21:22 +00002586static enum TIFFReadDirEntryErr
2587TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002588{
kumarashishg826308d2023-06-23 13:21:22 +00002589 return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value,
2590 ~((uint64_t)0));
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002591}
2592
kumarashishg826308d2023-06-23 13:21:22 +00002593static enum TIFFReadDirEntryErr
2594TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
Haibo Huang49cc9302020-04-27 16:14:24 -07002595{
kumarashishg826308d2023-06-23 13:21:22 +00002596 enum TIFFReadDirEntryErr err;
2597 uint32_t count;
2598 void *origdata;
2599 int64_t *data;
2600 switch (direntry->tdir_type)
2601 {
2602 case TIFF_BYTE:
2603 case TIFF_SBYTE:
2604 case TIFF_SHORT:
2605 case TIFF_SSHORT:
2606 case TIFF_LONG:
2607 case TIFF_SLONG:
2608 case TIFF_LONG8:
2609 case TIFF_SLONG8:
2610 break;
2611 default:
2612 return (TIFFReadDirEntryErrType);
2613 }
2614 err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
2615 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2616 {
2617 *value = 0;
2618 return (err);
2619 }
2620 switch (direntry->tdir_type)
2621 {
2622 case TIFF_LONG8:
2623 {
2624 uint64_t *m;
2625 uint32_t n;
2626 m = (uint64_t *)origdata;
2627 for (n = 0; n < count; n++)
2628 {
2629 if (tif->tif_flags & TIFF_SWAB)
2630 TIFFSwabLong8(m);
2631 err = TIFFReadDirEntryCheckRangeSlong8Long8(*m);
2632 if (err != TIFFReadDirEntryErrOk)
2633 {
2634 _TIFFfreeExt(tif, origdata);
2635 return (err);
2636 }
2637 m++;
2638 }
2639 *value = (int64_t *)origdata;
2640 return (TIFFReadDirEntryErrOk);
2641 }
2642 case TIFF_SLONG8:
2643 *value = (int64_t *)origdata;
2644 if (tif->tif_flags & TIFF_SWAB)
2645 TIFFSwabArrayOfLong8((uint64_t *)(*value), count);
2646 return (TIFFReadDirEntryErrOk);
2647 }
2648 data = (int64_t *)_TIFFmallocExt(tif, count * 8);
2649 if (data == 0)
2650 {
2651 _TIFFfreeExt(tif, origdata);
2652 return (TIFFReadDirEntryErrAlloc);
2653 }
2654 switch (direntry->tdir_type)
2655 {
2656 case TIFF_BYTE:
2657 {
2658 uint8_t *ma;
2659 int64_t *mb;
2660 uint32_t n;
2661 ma = (uint8_t *)origdata;
2662 mb = data;
2663 for (n = 0; n < count; n++)
2664 *mb++ = (int64_t)(*ma++);
2665 }
2666 break;
2667 case TIFF_SBYTE:
2668 {
2669 int8_t *ma;
2670 int64_t *mb;
2671 uint32_t n;
2672 ma = (int8_t *)origdata;
2673 mb = data;
2674 for (n = 0; n < count; n++)
2675 *mb++ = (int64_t)(*ma++);
2676 }
2677 break;
2678 case TIFF_SHORT:
2679 {
2680 uint16_t *ma;
2681 int64_t *mb;
2682 uint32_t n;
2683 ma = (uint16_t *)origdata;
2684 mb = data;
2685 for (n = 0; n < count; n++)
2686 {
2687 if (tif->tif_flags & TIFF_SWAB)
2688 TIFFSwabShort(ma);
2689 *mb++ = (int64_t)(*ma++);
2690 }
2691 }
2692 break;
2693 case TIFF_SSHORT:
2694 {
2695 int16_t *ma;
2696 int64_t *mb;
2697 uint32_t n;
2698 ma = (int16_t *)origdata;
2699 mb = data;
2700 for (n = 0; n < count; n++)
2701 {
2702 if (tif->tif_flags & TIFF_SWAB)
2703 TIFFSwabShort((uint16_t *)ma);
2704 *mb++ = (int64_t)(*ma++);
2705 }
2706 }
2707 break;
2708 case TIFF_LONG:
2709 {
2710 uint32_t *ma;
2711 int64_t *mb;
2712 uint32_t n;
2713 ma = (uint32_t *)origdata;
2714 mb = data;
2715 for (n = 0; n < count; n++)
2716 {
2717 if (tif->tif_flags & TIFF_SWAB)
2718 TIFFSwabLong(ma);
2719 *mb++ = (int64_t)(*ma++);
2720 }
2721 }
2722 break;
2723 case TIFF_SLONG:
2724 {
2725 int32_t *ma;
2726 int64_t *mb;
2727 uint32_t n;
2728 ma = (int32_t *)origdata;
2729 mb = data;
2730 for (n = 0; n < count; n++)
2731 {
2732 if (tif->tif_flags & TIFF_SWAB)
2733 TIFFSwabLong((uint32_t *)ma);
2734 *mb++ = (int64_t)(*ma++);
2735 }
2736 }
2737 break;
2738 }
2739 _TIFFfreeExt(tif, origdata);
2740 *value = data;
2741 return (TIFFReadDirEntryErrOk);
Haibo Huang49cc9302020-04-27 16:14:24 -07002742}
2743
kumarashishg826308d2023-06-23 13:21:22 +00002744static enum TIFFReadDirEntryErr
2745TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002746{
kumarashishg826308d2023-06-23 13:21:22 +00002747 enum TIFFReadDirEntryErr err;
2748 uint32_t count;
2749 void *origdata;
2750 float *data;
2751 switch (direntry->tdir_type)
2752 {
2753 case TIFF_BYTE:
2754 case TIFF_SBYTE:
2755 case TIFF_SHORT:
2756 case TIFF_SSHORT:
2757 case TIFF_LONG:
2758 case TIFF_SLONG:
2759 case TIFF_LONG8:
2760 case TIFF_SLONG8:
2761 case TIFF_RATIONAL:
2762 case TIFF_SRATIONAL:
2763 case TIFF_FLOAT:
2764 case TIFF_DOUBLE:
2765 break;
2766 default:
2767 return (TIFFReadDirEntryErrType);
2768 }
2769 err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata);
2770 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
2771 {
2772 *value = 0;
2773 return (err);
2774 }
2775 switch (direntry->tdir_type)
2776 {
2777 case TIFF_FLOAT:
2778 if (tif->tif_flags & TIFF_SWAB)
2779 TIFFSwabArrayOfLong((uint32_t *)origdata, count);
2780 TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata);
2781 *value = (float *)origdata;
2782 return (TIFFReadDirEntryErrOk);
2783 }
2784 data = (float *)_TIFFmallocExt(tif, count * sizeof(float));
2785 if (data == 0)
2786 {
2787 _TIFFfreeExt(tif, origdata);
2788 return (TIFFReadDirEntryErrAlloc);
2789 }
2790 switch (direntry->tdir_type)
2791 {
2792 case TIFF_BYTE:
2793 {
2794 uint8_t *ma;
2795 float *mb;
2796 uint32_t n;
2797 ma = (uint8_t *)origdata;
2798 mb = data;
2799 for (n = 0; n < count; n++)
2800 *mb++ = (float)(*ma++);
2801 }
2802 break;
2803 case TIFF_SBYTE:
2804 {
2805 int8_t *ma;
2806 float *mb;
2807 uint32_t n;
2808 ma = (int8_t *)origdata;
2809 mb = data;
2810 for (n = 0; n < count; n++)
2811 *mb++ = (float)(*ma++);
2812 }
2813 break;
2814 case TIFF_SHORT:
2815 {
2816 uint16_t *ma;
2817 float *mb;
2818 uint32_t n;
2819 ma = (uint16_t *)origdata;
2820 mb = data;
2821 for (n = 0; n < count; n++)
2822 {
2823 if (tif->tif_flags & TIFF_SWAB)
2824 TIFFSwabShort(ma);
2825 *mb++ = (float)(*ma++);
2826 }
2827 }
2828 break;
2829 case TIFF_SSHORT:
2830 {
2831 int16_t *ma;
2832 float *mb;
2833 uint32_t n;
2834 ma = (int16_t *)origdata;
2835 mb = data;
2836 for (n = 0; n < count; n++)
2837 {
2838 if (tif->tif_flags & TIFF_SWAB)
2839 TIFFSwabShort((uint16_t *)ma);
2840 *mb++ = (float)(*ma++);
2841 }
2842 }
2843 break;
2844 case TIFF_LONG:
2845 {
2846 uint32_t *ma;
2847 float *mb;
2848 uint32_t n;
2849 ma = (uint32_t *)origdata;
2850 mb = data;
2851 for (n = 0; n < count; n++)
2852 {
2853 if (tif->tif_flags & TIFF_SWAB)
2854 TIFFSwabLong(ma);
2855 *mb++ = (float)(*ma++);
2856 }
2857 }
2858 break;
2859 case TIFF_SLONG:
2860 {
2861 int32_t *ma;
2862 float *mb;
2863 uint32_t n;
2864 ma = (int32_t *)origdata;
2865 mb = data;
2866 for (n = 0; n < count; n++)
2867 {
2868 if (tif->tif_flags & TIFF_SWAB)
2869 TIFFSwabLong((uint32_t *)ma);
2870 *mb++ = (float)(*ma++);
2871 }
2872 }
2873 break;
2874 case TIFF_LONG8:
2875 {
2876 uint64_t *ma;
2877 float *mb;
2878 uint32_t n;
2879 ma = (uint64_t *)origdata;
2880 mb = data;
2881 for (n = 0; n < count; n++)
2882 {
2883 if (tif->tif_flags & TIFF_SWAB)
2884 TIFFSwabLong8(ma);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002885#if defined(__WIN32__) && (_MSC_VER < 1500)
kumarashishg826308d2023-06-23 13:21:22 +00002886 /*
2887 * XXX: MSVC 6.0 does not support
2888 * conversion of 64-bit integers into
2889 * floating point values.
2890 */
2891 *mb++ = _TIFFUInt64ToFloat(*ma++);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002892#else
kumarashishg826308d2023-06-23 13:21:22 +00002893 *mb++ = (float)(*ma++);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002894#endif
kumarashishg826308d2023-06-23 13:21:22 +00002895 }
2896 }
2897 break;
2898 case TIFF_SLONG8:
2899 {
2900 int64_t *ma;
2901 float *mb;
2902 uint32_t n;
2903 ma = (int64_t *)origdata;
2904 mb = data;
2905 for (n = 0; n < count; n++)
2906 {
2907 if (tif->tif_flags & TIFF_SWAB)
2908 TIFFSwabLong8((uint64_t *)ma);
2909 *mb++ = (float)(*ma++);
2910 }
2911 }
2912 break;
2913 case TIFF_RATIONAL:
2914 {
2915 uint32_t *ma;
2916 uint32_t maa;
2917 uint32_t mab;
2918 float *mb;
2919 uint32_t n;
2920 ma = (uint32_t *)origdata;
2921 mb = data;
2922 for (n = 0; n < count; n++)
2923 {
2924 if (tif->tif_flags & TIFF_SWAB)
2925 TIFFSwabLong(ma);
2926 maa = *ma++;
2927 if (tif->tif_flags & TIFF_SWAB)
2928 TIFFSwabLong(ma);
2929 mab = *ma++;
2930 if (mab == 0)
2931 *mb++ = 0.0;
2932 else
2933 *mb++ = (float)maa / (float)mab;
2934 }
2935 }
2936 break;
2937 case TIFF_SRATIONAL:
2938 {
2939 uint32_t *ma;
2940 int32_t maa;
2941 uint32_t mab;
2942 float *mb;
2943 uint32_t n;
2944 ma = (uint32_t *)origdata;
2945 mb = data;
2946 for (n = 0; n < count; n++)
2947 {
2948 if (tif->tif_flags & TIFF_SWAB)
2949 TIFFSwabLong(ma);
2950 maa = *(int32_t *)ma;
2951 ma++;
2952 if (tif->tif_flags & TIFF_SWAB)
2953 TIFFSwabLong(ma);
2954 mab = *ma++;
2955 if (mab == 0)
2956 *mb++ = 0.0;
2957 else
2958 *mb++ = (float)maa / (float)mab;
2959 }
2960 }
2961 break;
2962 case TIFF_DOUBLE:
2963 {
2964 double *ma;
2965 float *mb;
2966 uint32_t n;
2967 if (tif->tif_flags & TIFF_SWAB)
2968 TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
2969 TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
2970 ma = (double *)origdata;
2971 mb = data;
2972 for (n = 0; n < count; n++)
2973 {
2974 double val = *ma++;
2975 if (val > FLT_MAX)
2976 val = FLT_MAX;
2977 else if (val < -FLT_MAX)
2978 val = -FLT_MAX;
2979 *mb++ = (float)val;
2980 }
2981 }
2982 break;
2983 }
2984 _TIFFfreeExt(tif, origdata);
2985 *value = data;
2986 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002987}
2988
2989static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00002990TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08002991{
kumarashishg826308d2023-06-23 13:21:22 +00002992 enum TIFFReadDirEntryErr err;
2993 uint32_t count;
2994 void *origdata;
2995 double *data;
2996 switch (direntry->tdir_type)
2997 {
2998 case TIFF_BYTE:
2999 case TIFF_SBYTE:
3000 case TIFF_SHORT:
3001 case TIFF_SSHORT:
3002 case TIFF_LONG:
3003 case TIFF_SLONG:
3004 case TIFF_LONG8:
3005 case TIFF_SLONG8:
3006 case TIFF_RATIONAL:
3007 case TIFF_SRATIONAL:
3008 case TIFF_FLOAT:
3009 case TIFF_DOUBLE:
3010 break;
3011 default:
3012 return (TIFFReadDirEntryErrType);
3013 }
3014 err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
3015 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
3016 {
3017 *value = 0;
3018 return (err);
3019 }
3020 switch (direntry->tdir_type)
3021 {
3022 case TIFF_DOUBLE:
3023 if (tif->tif_flags & TIFF_SWAB)
3024 TIFFSwabArrayOfLong8((uint64_t *)origdata, count);
3025 TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata);
3026 *value = (double *)origdata;
3027 return (TIFFReadDirEntryErrOk);
3028 }
3029 data = (double *)_TIFFmallocExt(tif, count * sizeof(double));
3030 if (data == 0)
3031 {
3032 _TIFFfreeExt(tif, origdata);
3033 return (TIFFReadDirEntryErrAlloc);
3034 }
3035 switch (direntry->tdir_type)
3036 {
3037 case TIFF_BYTE:
3038 {
3039 uint8_t *ma;
3040 double *mb;
3041 uint32_t n;
3042 ma = (uint8_t *)origdata;
3043 mb = data;
3044 for (n = 0; n < count; n++)
3045 *mb++ = (double)(*ma++);
3046 }
3047 break;
3048 case TIFF_SBYTE:
3049 {
3050 int8_t *ma;
3051 double *mb;
3052 uint32_t n;
3053 ma = (int8_t *)origdata;
3054 mb = data;
3055 for (n = 0; n < count; n++)
3056 *mb++ = (double)(*ma++);
3057 }
3058 break;
3059 case TIFF_SHORT:
3060 {
3061 uint16_t *ma;
3062 double *mb;
3063 uint32_t n;
3064 ma = (uint16_t *)origdata;
3065 mb = data;
3066 for (n = 0; n < count; n++)
3067 {
3068 if (tif->tif_flags & TIFF_SWAB)
3069 TIFFSwabShort(ma);
3070 *mb++ = (double)(*ma++);
3071 }
3072 }
3073 break;
3074 case TIFF_SSHORT:
3075 {
3076 int16_t *ma;
3077 double *mb;
3078 uint32_t n;
3079 ma = (int16_t *)origdata;
3080 mb = data;
3081 for (n = 0; n < count; n++)
3082 {
3083 if (tif->tif_flags & TIFF_SWAB)
3084 TIFFSwabShort((uint16_t *)ma);
3085 *mb++ = (double)(*ma++);
3086 }
3087 }
3088 break;
3089 case TIFF_LONG:
3090 {
3091 uint32_t *ma;
3092 double *mb;
3093 uint32_t n;
3094 ma = (uint32_t *)origdata;
3095 mb = data;
3096 for (n = 0; n < count; n++)
3097 {
3098 if (tif->tif_flags & TIFF_SWAB)
3099 TIFFSwabLong(ma);
3100 *mb++ = (double)(*ma++);
3101 }
3102 }
3103 break;
3104 case TIFF_SLONG:
3105 {
3106 int32_t *ma;
3107 double *mb;
3108 uint32_t n;
3109 ma = (int32_t *)origdata;
3110 mb = data;
3111 for (n = 0; n < count; n++)
3112 {
3113 if (tif->tif_flags & TIFF_SWAB)
3114 TIFFSwabLong((uint32_t *)ma);
3115 *mb++ = (double)(*ma++);
3116 }
3117 }
3118 break;
3119 case TIFF_LONG8:
3120 {
3121 uint64_t *ma;
3122 double *mb;
3123 uint32_t n;
3124 ma = (uint64_t *)origdata;
3125 mb = data;
3126 for (n = 0; n < count; n++)
3127 {
3128 if (tif->tif_flags & TIFF_SWAB)
3129 TIFFSwabLong8(ma);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003130#if defined(__WIN32__) && (_MSC_VER < 1500)
kumarashishg826308d2023-06-23 13:21:22 +00003131 /*
3132 * XXX: MSVC 6.0 does not support
3133 * conversion of 64-bit integers into
3134 * floating point values.
3135 */
3136 *mb++ = _TIFFUInt64ToDouble(*ma++);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003137#else
kumarashishg826308d2023-06-23 13:21:22 +00003138 *mb++ = (double)(*ma++);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003139#endif
kumarashishg826308d2023-06-23 13:21:22 +00003140 }
3141 }
3142 break;
3143 case TIFF_SLONG8:
3144 {
3145 int64_t *ma;
3146 double *mb;
3147 uint32_t n;
3148 ma = (int64_t *)origdata;
3149 mb = data;
3150 for (n = 0; n < count; n++)
3151 {
3152 if (tif->tif_flags & TIFF_SWAB)
3153 TIFFSwabLong8((uint64_t *)ma);
3154 *mb++ = (double)(*ma++);
3155 }
3156 }
3157 break;
3158 case TIFF_RATIONAL:
3159 {
3160 uint32_t *ma;
3161 uint32_t maa;
3162 uint32_t mab;
3163 double *mb;
3164 uint32_t n;
3165 ma = (uint32_t *)origdata;
3166 mb = data;
3167 for (n = 0; n < count; n++)
3168 {
3169 if (tif->tif_flags & TIFF_SWAB)
3170 TIFFSwabLong(ma);
3171 maa = *ma++;
3172 if (tif->tif_flags & TIFF_SWAB)
3173 TIFFSwabLong(ma);
3174 mab = *ma++;
3175 if (mab == 0)
3176 *mb++ = 0.0;
3177 else
3178 *mb++ = (double)maa / (double)mab;
3179 }
3180 }
3181 break;
3182 case TIFF_SRATIONAL:
3183 {
3184 uint32_t *ma;
3185 int32_t maa;
3186 uint32_t mab;
3187 double *mb;
3188 uint32_t n;
3189 ma = (uint32_t *)origdata;
3190 mb = data;
3191 for (n = 0; n < count; n++)
3192 {
3193 if (tif->tif_flags & TIFF_SWAB)
3194 TIFFSwabLong(ma);
3195 maa = *(int32_t *)ma;
3196 ma++;
3197 if (tif->tif_flags & TIFF_SWAB)
3198 TIFFSwabLong(ma);
3199 mab = *ma++;
3200 if (mab == 0)
3201 *mb++ = 0.0;
3202 else
3203 *mb++ = (double)maa / (double)mab;
3204 }
3205 }
3206 break;
3207 case TIFF_FLOAT:
3208 {
3209 float *ma;
3210 double *mb;
3211 uint32_t n;
3212 if (tif->tif_flags & TIFF_SWAB)
3213 TIFFSwabArrayOfLong((uint32_t *)origdata, count);
3214 TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
3215 ma = (float *)origdata;
3216 mb = data;
3217 for (n = 0; n < count; n++)
3218 *mb++ = (double)(*ma++);
3219 }
3220 break;
3221 }
3222 _TIFFfreeExt(tif, origdata);
3223 *value = data;
3224 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003225}
3226
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003227static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003228TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003229{
kumarashishg826308d2023-06-23 13:21:22 +00003230 enum TIFFReadDirEntryErr err;
3231 uint32_t count;
3232 void *origdata;
3233 uint64_t *data;
3234 switch (direntry->tdir_type)
3235 {
3236 case TIFF_LONG:
3237 case TIFF_LONG8:
3238 case TIFF_IFD:
3239 case TIFF_IFD8:
3240 break;
3241 default:
3242 return (TIFFReadDirEntryErrType);
3243 }
3244 err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata);
3245 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
3246 {
3247 *value = 0;
3248 return (err);
3249 }
3250 switch (direntry->tdir_type)
3251 {
3252 case TIFF_LONG8:
3253 case TIFF_IFD8:
3254 *value = (uint64_t *)origdata;
3255 if (tif->tif_flags & TIFF_SWAB)
3256 TIFFSwabArrayOfLong8(*value, count);
3257 return (TIFFReadDirEntryErrOk);
3258 }
3259 data = (uint64_t *)_TIFFmallocExt(tif, count * 8);
3260 if (data == 0)
3261 {
3262 _TIFFfreeExt(tif, origdata);
3263 return (TIFFReadDirEntryErrAlloc);
3264 }
3265 switch (direntry->tdir_type)
3266 {
3267 case TIFF_LONG:
3268 case TIFF_IFD:
3269 {
3270 uint32_t *ma;
3271 uint64_t *mb;
3272 uint32_t n;
3273 ma = (uint32_t *)origdata;
3274 mb = data;
3275 for (n = 0; n < count; n++)
3276 {
3277 if (tif->tif_flags & TIFF_SWAB)
3278 TIFFSwabLong(ma);
3279 *mb++ = (uint64_t)(*ma++);
3280 }
3281 }
3282 break;
3283 }
3284 _TIFFfreeExt(tif, origdata);
3285 *value = data;
3286 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003287}
3288
3289static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003290TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
3291 uint16_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003292{
kumarashishg826308d2023-06-23 13:21:22 +00003293 enum TIFFReadDirEntryErr err;
3294 uint16_t *m;
3295 uint16_t *na;
3296 uint16_t nb;
3297 if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel)
3298 return (TIFFReadDirEntryErrCount);
3299 err = TIFFReadDirEntryShortArray(tif, direntry, &m);
3300 if (err != TIFFReadDirEntryErrOk || m == NULL)
3301 return (err);
3302 na = m;
3303 nb = tif->tif_dir.td_samplesperpixel;
3304 *value = *na++;
3305 nb--;
3306 while (nb > 0)
3307 {
3308 if (*na++ != *value)
3309 {
3310 err = TIFFReadDirEntryErrPsdif;
3311 break;
3312 }
3313 nb--;
3314 }
3315 _TIFFfreeExt(tif, m);
3316 return (err);
3317}
3318
3319static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
3320 uint8_t *value)
3321{
3322 (void)tif;
3323 *value = *(uint8_t *)(&direntry->tdir_offset);
3324}
3325
3326static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
3327 int8_t *value)
3328{
3329 (void)tif;
3330 *value = *(int8_t *)(&direntry->tdir_offset);
3331}
3332
3333static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
3334 uint16_t *value)
3335{
3336 *value = direntry->tdir_offset.toff_short;
3337 /* *value=*(uint16_t*)(&direntry->tdir_offset); */
3338 if (tif->tif_flags & TIFF_SWAB)
3339 TIFFSwabShort(value);
3340}
3341
3342static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
3343 int16_t *value)
3344{
3345 *value = *(int16_t *)(&direntry->tdir_offset);
3346 if (tif->tif_flags & TIFF_SWAB)
3347 TIFFSwabShort((uint16_t *)value);
3348}
3349
3350static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
3351 uint32_t *value)
3352{
3353 *value = *(uint32_t *)(&direntry->tdir_offset);
3354 if (tif->tif_flags & TIFF_SWAB)
3355 TIFFSwabLong(value);
3356}
3357
3358static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
3359 int32_t *value)
3360{
3361 *value = *(int32_t *)(&direntry->tdir_offset);
3362 if (tif->tif_flags & TIFF_SWAB)
3363 TIFFSwabLong((uint32_t *)value);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003364}
3365
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003366static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003367TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003368{
kumarashishg826308d2023-06-23 13:21:22 +00003369 if (!(tif->tif_flags & TIFF_BIGTIFF))
3370 {
3371 enum TIFFReadDirEntryErr err;
3372 uint32_t offset = direntry->tdir_offset.toff_long;
3373 if (tif->tif_flags & TIFF_SWAB)
3374 TIFFSwabLong(&offset);
3375 err = TIFFReadDirEntryData(tif, offset, 8, value);
3376 if (err != TIFFReadDirEntryErrOk)
3377 return (err);
3378 }
3379 else
3380 *value = direntry->tdir_offset.toff_long8;
3381 if (tif->tif_flags & TIFF_SWAB)
3382 TIFFSwabLong8(value);
3383 return (TIFFReadDirEntryErrOk);
3384}
3385
3386static enum TIFFReadDirEntryErr
3387TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value)
3388{
3389 if (!(tif->tif_flags & TIFF_BIGTIFF))
3390 {
3391 enum TIFFReadDirEntryErr err;
3392 uint32_t offset = direntry->tdir_offset.toff_long;
3393 if (tif->tif_flags & TIFF_SWAB)
3394 TIFFSwabLong(&offset);
3395 err = TIFFReadDirEntryData(tif, offset, 8, value);
3396 if (err != TIFFReadDirEntryErrOk)
3397 return (err);
3398 }
3399 else
3400 *value = *(int64_t *)(&direntry->tdir_offset);
3401 if (tif->tif_flags & TIFF_SWAB)
3402 TIFFSwabLong8((uint64_t *)value);
3403 return (TIFFReadDirEntryErrOk);
3404}
3405
3406static enum TIFFReadDirEntryErr
3407TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
3408 double *value)
3409{
3410 UInt64Aligned_t m;
3411
3412 assert(sizeof(double) == 8);
3413 assert(sizeof(uint64_t) == 8);
3414 assert(sizeof(uint32_t) == 4);
3415 if (!(tif->tif_flags & TIFF_BIGTIFF))
3416 {
3417 enum TIFFReadDirEntryErr err;
3418 uint32_t offset = direntry->tdir_offset.toff_long;
3419 if (tif->tif_flags & TIFF_SWAB)
3420 TIFFSwabLong(&offset);
3421 err = TIFFReadDirEntryData(tif, offset, 8, m.i);
3422 if (err != TIFFReadDirEntryErrOk)
3423 return (err);
3424 }
3425 else
3426 m.l = direntry->tdir_offset.toff_long8;
3427 if (tif->tif_flags & TIFF_SWAB)
3428 TIFFSwabArrayOfLong(m.i, 2);
3429 /* Not completely sure what we should do when m.i[1]==0, but some */
3430 /* sanitizers do not like division by 0.0: */
3431 /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
3432 if (m.i[0] == 0 || m.i[1] == 0)
3433 *value = 0.0;
3434 else
3435 *value = (double)m.i[0] / (double)m.i[1];
3436 return (TIFFReadDirEntryErrOk);
3437}
3438
3439static enum TIFFReadDirEntryErr
3440TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
3441 double *value)
3442{
3443 UInt64Aligned_t m;
3444 assert(sizeof(double) == 8);
3445 assert(sizeof(uint64_t) == 8);
3446 assert(sizeof(int32_t) == 4);
3447 assert(sizeof(uint32_t) == 4);
3448 if (!(tif->tif_flags & TIFF_BIGTIFF))
3449 {
3450 enum TIFFReadDirEntryErr err;
3451 uint32_t offset = direntry->tdir_offset.toff_long;
3452 if (tif->tif_flags & TIFF_SWAB)
3453 TIFFSwabLong(&offset);
3454 err = TIFFReadDirEntryData(tif, offset, 8, m.i);
3455 if (err != TIFFReadDirEntryErrOk)
3456 return (err);
3457 }
3458 else
3459 m.l = direntry->tdir_offset.toff_long8;
3460 if (tif->tif_flags & TIFF_SWAB)
3461 TIFFSwabArrayOfLong(m.i, 2);
3462 /* Not completely sure what we should do when m.i[1]==0, but some */
3463 /* sanitizers do not like division by 0.0: */
3464 /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
3465 if ((int32_t)m.i[0] == 0 || m.i[1] == 0)
3466 *value = 0.0;
3467 else
3468 *value = (double)((int32_t)m.i[0]) / (double)m.i[1];
3469 return (TIFFReadDirEntryErrOk);
3470}
3471
3472static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
3473 float *value)
3474{
3475 union
3476 {
3477 float f;
3478 uint32_t i;
3479 } float_union;
3480 assert(sizeof(float) == 4);
3481 assert(sizeof(uint32_t) == 4);
3482 assert(sizeof(float_union) == 4);
3483 float_union.i = *(uint32_t *)(&direntry->tdir_offset);
3484 *value = float_union.f;
3485 if (tif->tif_flags & TIFF_SWAB)
3486 TIFFSwabLong((uint32_t *)value);
3487}
3488
3489static enum TIFFReadDirEntryErr
3490TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
3491{
3492 assert(sizeof(double) == 8);
3493 assert(sizeof(uint64_t) == 8);
3494 assert(sizeof(UInt64Aligned_t) == 8);
3495 if (!(tif->tif_flags & TIFF_BIGTIFF))
3496 {
3497 enum TIFFReadDirEntryErr err;
3498 uint32_t offset = direntry->tdir_offset.toff_long;
3499 if (tif->tif_flags & TIFF_SWAB)
3500 TIFFSwabLong(&offset);
3501 err = TIFFReadDirEntryData(tif, offset, 8, value);
3502 if (err != TIFFReadDirEntryErrOk)
3503 return (err);
3504 }
3505 else
3506 {
3507 UInt64Aligned_t uint64_union;
3508 uint64_union.l = direntry->tdir_offset.toff_long8;
3509 *value = uint64_union.d;
3510 }
3511 if (tif->tif_flags & TIFF_SWAB)
3512 TIFFSwabLong8((uint64_t *)value);
3513 return (TIFFReadDirEntryErrOk);
3514}
3515
3516static enum TIFFReadDirEntryErr
3517TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)
3518{
3519 if (value < 0)
3520 return (TIFFReadDirEntryErrRange);
3521 else
3522 return (TIFFReadDirEntryErrOk);
3523}
3524
3525static enum TIFFReadDirEntryErr
3526TIFFReadDirEntryCheckRangeByteShort(uint16_t value)
3527{
3528 if (value > 0xFF)
3529 return (TIFFReadDirEntryErrRange);
3530 else
3531 return (TIFFReadDirEntryErrOk);
3532}
3533
3534static enum TIFFReadDirEntryErr
3535TIFFReadDirEntryCheckRangeByteSshort(int16_t value)
3536{
3537 if ((value < 0) || (value > 0xFF))
3538 return (TIFFReadDirEntryErrRange);
3539 else
3540 return (TIFFReadDirEntryErrOk);
3541}
3542
3543static enum TIFFReadDirEntryErr
3544TIFFReadDirEntryCheckRangeByteLong(uint32_t value)
3545{
3546 if (value > 0xFF)
3547 return (TIFFReadDirEntryErrRange);
3548 else
3549 return (TIFFReadDirEntryErrOk);
3550}
3551
3552static enum TIFFReadDirEntryErr
3553TIFFReadDirEntryCheckRangeByteSlong(int32_t value)
3554{
3555 if ((value < 0) || (value > 0xFF))
3556 return (TIFFReadDirEntryErrRange);
3557 else
3558 return (TIFFReadDirEntryErrOk);
3559}
3560
3561static enum TIFFReadDirEntryErr
3562TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)
3563{
3564 if (value > 0xFF)
3565 return (TIFFReadDirEntryErrRange);
3566 else
3567 return (TIFFReadDirEntryErrOk);
3568}
3569
3570static enum TIFFReadDirEntryErr
3571TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)
3572{
3573 if ((value < 0) || (value > 0xFF))
3574 return (TIFFReadDirEntryErrRange);
3575 else
3576 return (TIFFReadDirEntryErrOk);
3577}
3578
3579static enum TIFFReadDirEntryErr
3580TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)
3581{
3582 if (value > 0x7F)
3583 return (TIFFReadDirEntryErrRange);
3584 else
3585 return (TIFFReadDirEntryErrOk);
3586}
3587
3588static enum TIFFReadDirEntryErr
3589TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)
3590{
3591 if (value > 0x7F)
3592 return (TIFFReadDirEntryErrRange);
3593 else
3594 return (TIFFReadDirEntryErrOk);
3595}
3596
3597static enum TIFFReadDirEntryErr
3598TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)
3599{
3600 if ((value < -0x80) || (value > 0x7F))
3601 return (TIFFReadDirEntryErrRange);
3602 else
3603 return (TIFFReadDirEntryErrOk);
3604}
3605
3606static enum TIFFReadDirEntryErr
3607TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)
3608{
3609 if (value > 0x7F)
3610 return (TIFFReadDirEntryErrRange);
3611 else
3612 return (TIFFReadDirEntryErrOk);
3613}
3614
3615static enum TIFFReadDirEntryErr
3616TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)
3617{
3618 if ((value < -0x80) || (value > 0x7F))
3619 return (TIFFReadDirEntryErrRange);
3620 else
3621 return (TIFFReadDirEntryErrOk);
3622}
3623
3624static enum TIFFReadDirEntryErr
3625TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)
3626{
3627 if (value > 0x7F)
3628 return (TIFFReadDirEntryErrRange);
3629 else
3630 return (TIFFReadDirEntryErrOk);
3631}
3632
3633static enum TIFFReadDirEntryErr
3634TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)
3635{
3636 if ((value < -0x80) || (value > 0x7F))
3637 return (TIFFReadDirEntryErrRange);
3638 else
3639 return (TIFFReadDirEntryErrOk);
3640}
3641
3642static enum TIFFReadDirEntryErr
3643TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)
3644{
3645 if (value < 0)
3646 return (TIFFReadDirEntryErrRange);
3647 else
3648 return (TIFFReadDirEntryErrOk);
3649}
3650
3651static enum TIFFReadDirEntryErr
3652TIFFReadDirEntryCheckRangeShortSshort(int16_t value)
3653{
3654 if (value < 0)
3655 return (TIFFReadDirEntryErrRange);
3656 else
3657 return (TIFFReadDirEntryErrOk);
3658}
3659
3660static enum TIFFReadDirEntryErr
3661TIFFReadDirEntryCheckRangeShortLong(uint32_t value)
3662{
3663 if (value > 0xFFFF)
3664 return (TIFFReadDirEntryErrRange);
3665 else
3666 return (TIFFReadDirEntryErrOk);
3667}
3668
3669static enum TIFFReadDirEntryErr
3670TIFFReadDirEntryCheckRangeShortSlong(int32_t value)
3671{
3672 if ((value < 0) || (value > 0xFFFF))
3673 return (TIFFReadDirEntryErrRange);
3674 else
3675 return (TIFFReadDirEntryErrOk);
3676}
3677
3678static enum TIFFReadDirEntryErr
3679TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)
3680{
3681 if (value > 0xFFFF)
3682 return (TIFFReadDirEntryErrRange);
3683 else
3684 return (TIFFReadDirEntryErrOk);
3685}
3686
3687static enum TIFFReadDirEntryErr
3688TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)
3689{
3690 if ((value < 0) || (value > 0xFFFF))
3691 return (TIFFReadDirEntryErrRange);
3692 else
3693 return (TIFFReadDirEntryErrOk);
3694}
3695
3696static enum TIFFReadDirEntryErr
3697TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)
3698{
3699 if (value > 0x7FFF)
3700 return (TIFFReadDirEntryErrRange);
3701 else
3702 return (TIFFReadDirEntryErrOk);
3703}
3704
3705static enum TIFFReadDirEntryErr
3706TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)
3707{
3708 if (value > 0x7FFF)
3709 return (TIFFReadDirEntryErrRange);
3710 else
3711 return (TIFFReadDirEntryErrOk);
3712}
3713
3714static enum TIFFReadDirEntryErr
3715TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)
3716{
3717 if ((value < -0x8000) || (value > 0x7FFF))
3718 return (TIFFReadDirEntryErrRange);
3719 else
3720 return (TIFFReadDirEntryErrOk);
3721}
3722
3723static enum TIFFReadDirEntryErr
3724TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)
3725{
3726 if (value > 0x7FFF)
3727 return (TIFFReadDirEntryErrRange);
3728 else
3729 return (TIFFReadDirEntryErrOk);
3730}
3731
3732static enum TIFFReadDirEntryErr
3733TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)
3734{
3735 if ((value < -0x8000) || (value > 0x7FFF))
3736 return (TIFFReadDirEntryErrRange);
3737 else
3738 return (TIFFReadDirEntryErrOk);
3739}
3740
3741static enum TIFFReadDirEntryErr
3742TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)
3743{
3744 if (value < 0)
3745 return (TIFFReadDirEntryErrRange);
3746 else
3747 return (TIFFReadDirEntryErrOk);
3748}
3749
3750static enum TIFFReadDirEntryErr
3751TIFFReadDirEntryCheckRangeLongSshort(int16_t value)
3752{
3753 if (value < 0)
3754 return (TIFFReadDirEntryErrRange);
3755 else
3756 return (TIFFReadDirEntryErrOk);
3757}
3758
3759static enum TIFFReadDirEntryErr
3760TIFFReadDirEntryCheckRangeLongSlong(int32_t value)
3761{
3762 if (value < 0)
3763 return (TIFFReadDirEntryErrRange);
3764 else
3765 return (TIFFReadDirEntryErrOk);
3766}
3767
3768static enum TIFFReadDirEntryErr
3769TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)
3770{
3771 if (value > UINT32_MAX)
3772 return (TIFFReadDirEntryErrRange);
3773 else
3774 return (TIFFReadDirEntryErrOk);
3775}
3776
3777static enum TIFFReadDirEntryErr
3778TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)
3779{
3780 if ((value < 0) || (value > (int64_t)UINT32_MAX))
3781 return (TIFFReadDirEntryErrRange);
3782 else
3783 return (TIFFReadDirEntryErrOk);
3784}
3785
3786static enum TIFFReadDirEntryErr
3787TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)
3788{
3789 if (value > 0x7FFFFFFFUL)
3790 return (TIFFReadDirEntryErrRange);
3791 else
3792 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003793}
3794
3795/* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
3796static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003797TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003798{
kumarashishg826308d2023-06-23 13:21:22 +00003799 if (value > 0x7FFFFFFF)
3800 return (TIFFReadDirEntryErrRange);
3801 else
3802 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003803}
3804
3805/* Check that the 8-byte signed value can fit in a 4-byte signed range */
3806static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003807TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003808{
kumarashishg826308d2023-06-23 13:21:22 +00003809 if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF))
3810 return (TIFFReadDirEntryErrRange);
3811 else
3812 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003813}
3814
3815static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003816TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003817{
kumarashishg826308d2023-06-23 13:21:22 +00003818 if (value < 0)
3819 return (TIFFReadDirEntryErrRange);
3820 else
3821 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003822}
3823
3824static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003825TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003826{
kumarashishg826308d2023-06-23 13:21:22 +00003827 if (value < 0)
3828 return (TIFFReadDirEntryErrRange);
3829 else
3830 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003831}
3832
3833static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003834TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003835{
kumarashishg826308d2023-06-23 13:21:22 +00003836 if (value < 0)
3837 return (TIFFReadDirEntryErrRange);
3838 else
3839 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003840}
3841
3842static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003843TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003844{
kumarashishg826308d2023-06-23 13:21:22 +00003845 if (value < 0)
3846 return (TIFFReadDirEntryErrRange);
3847 else
3848 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003849}
3850
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003851static enum TIFFReadDirEntryErr
kumarashishg826308d2023-06-23 13:21:22 +00003852TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003853{
kumarashishg826308d2023-06-23 13:21:22 +00003854 if (value > INT64_MAX)
3855 return (TIFFReadDirEntryErrRange);
3856 else
3857 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003858}
3859
kumarashishg826308d2023-06-23 13:21:22 +00003860static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
3861 tmsize_t size, void *dest)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003862{
kumarashishg826308d2023-06-23 13:21:22 +00003863 assert(size > 0);
3864 if (!isMapped(tif))
3865 {
3866 if (!SeekOK(tif, offset))
3867 return (TIFFReadDirEntryErrIo);
3868 if (!ReadOK(tif, dest, size))
3869 return (TIFFReadDirEntryErrIo);
3870 }
3871 else
3872 {
3873 size_t ma, mb;
3874 ma = (size_t)offset;
3875 if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size)
3876 {
3877 return TIFFReadDirEntryErrIo;
3878 }
3879 mb = ma + size;
3880 if (mb > (uint64_t)tif->tif_size)
3881 return (TIFFReadDirEntryErrIo);
3882 _TIFFmemcpy(dest, tif->tif_base + ma, size);
3883 }
3884 return (TIFFReadDirEntryErrOk);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003885}
3886
kumarashishg826308d2023-06-23 13:21:22 +00003887static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
3888 const char *module, const char *tagname,
3889 int recover)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003890{
kumarashishg826308d2023-06-23 13:21:22 +00003891 if (!recover)
3892 {
3893 switch (err)
3894 {
3895 case TIFFReadDirEntryErrCount:
3896 TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"",
3897 tagname);
3898 break;
3899 case TIFFReadDirEntryErrType:
3900 TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"",
3901 tagname);
3902 break;
3903 case TIFFReadDirEntryErrIo:
3904 TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"",
3905 tagname);
3906 break;
3907 case TIFFReadDirEntryErrRange:
3908 TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"",
3909 tagname);
3910 break;
3911 case TIFFReadDirEntryErrPsdif:
3912 TIFFErrorExtR(
3913 tif, module,
3914 "Cannot handle different values per sample for \"%s\"",
3915 tagname);
3916 break;
3917 case TIFFReadDirEntryErrSizesan:
3918 TIFFErrorExtR(tif, module,
3919 "Sanity check on size of \"%s\" value failed",
3920 tagname);
3921 break;
3922 case TIFFReadDirEntryErrAlloc:
3923 TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"",
3924 tagname);
3925 break;
3926 default:
3927 assert(0); /* we should never get here */
3928 break;
3929 }
3930 }
3931 else
3932 {
3933 switch (err)
3934 {
3935 case TIFFReadDirEntryErrCount:
3936 TIFFWarningExtR(tif, module,
3937 "Incorrect count for \"%s\"; tag ignored",
3938 tagname);
3939 break;
3940 case TIFFReadDirEntryErrType:
3941 TIFFWarningExtR(tif, module,
3942 "Incompatible type for \"%s\"; tag ignored",
3943 tagname);
3944 break;
3945 case TIFFReadDirEntryErrIo:
3946 TIFFWarningExtR(
3947 tif, module,
3948 "IO error during reading of \"%s\"; tag ignored", tagname);
3949 break;
3950 case TIFFReadDirEntryErrRange:
3951 TIFFWarningExtR(tif, module,
3952 "Incorrect value for \"%s\"; tag ignored",
3953 tagname);
3954 break;
3955 case TIFFReadDirEntryErrPsdif:
3956 TIFFWarningExtR(tif, module,
3957 "Cannot handle different values per sample for "
3958 "\"%s\"; tag ignored",
3959 tagname);
3960 break;
3961 case TIFFReadDirEntryErrSizesan:
3962 TIFFWarningExtR(
3963 tif, module,
3964 "Sanity check on size of \"%s\" value failed; tag ignored",
3965 tagname);
3966 break;
3967 case TIFFReadDirEntryErrAlloc:
3968 TIFFWarningExtR(tif, module,
3969 "Out of memory reading of \"%s\"; tag ignored",
3970 tagname);
3971 break;
3972 default:
3973 assert(0); /* we should never get here */
3974 break;
3975 }
3976 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08003977}
3978
3979/*
Haibo Huang49cc9302020-04-27 16:14:24 -07003980 * Return the maximum number of color channels specified for a given photometric
3981 * type. 0 is returned if photometric type isn't supported or no default value
3982 * is defined by the specification.
3983 */
kumarashishg826308d2023-06-23 13:21:22 +00003984static int _TIFFGetMaxColorChannels(uint16_t photometric)
Haibo Huang49cc9302020-04-27 16:14:24 -07003985{
kumarashishg826308d2023-06-23 13:21:22 +00003986 switch (photometric)
3987 {
3988 case PHOTOMETRIC_PALETTE:
3989 case PHOTOMETRIC_MINISWHITE:
3990 case PHOTOMETRIC_MINISBLACK:
Haibo Huang49cc9302020-04-27 16:14:24 -07003991 return 1;
kumarashishg826308d2023-06-23 13:21:22 +00003992 case PHOTOMETRIC_YCBCR:
3993 case PHOTOMETRIC_RGB:
3994 case PHOTOMETRIC_CIELAB:
3995 case PHOTOMETRIC_LOGLUV:
3996 case PHOTOMETRIC_ITULAB:
3997 case PHOTOMETRIC_ICCLAB:
Haibo Huang49cc9302020-04-27 16:14:24 -07003998 return 3;
kumarashishg826308d2023-06-23 13:21:22 +00003999 case PHOTOMETRIC_SEPARATED:
4000 case PHOTOMETRIC_MASK:
Haibo Huang49cc9302020-04-27 16:14:24 -07004001 return 4;
kumarashishg826308d2023-06-23 13:21:22 +00004002 case PHOTOMETRIC_LOGL:
4003 case PHOTOMETRIC_CFA:
4004 default:
Haibo Huang49cc9302020-04-27 16:14:24 -07004005 return 0;
4006 }
4007}
4008
kumarashishg826308d2023-06-23 13:21:22 +00004009static int ByteCountLooksBad(TIFF *tif)
Haibo Huang49cc9302020-04-27 16:14:24 -07004010{
4011 /*
kumarashishg826308d2023-06-23 13:21:22 +00004012 * Assume we have wrong StripByteCount value (in case
4013 * of single strip) in following cases:
4014 * - it is equal to zero along with StripOffset;
4015 * - it is larger than file itself (in case of uncompressed
4016 * image);
4017 * - it is smaller than the size of the bytes per row
4018 * multiplied on the number of rows. The last case should
4019 * not be checked in the case of writing new image,
4020 * because we may do not know the exact strip size
4021 * until the whole image will be written and directory
4022 * dumped out.
4023 */
4024 uint64_t bytecount = TIFFGetStrileByteCount(tif, 0);
4025 uint64_t offset = TIFFGetStrileOffset(tif, 0);
4026 uint64_t filesize;
Haibo Huang49cc9302020-04-27 16:14:24 -07004027
kumarashishg826308d2023-06-23 13:21:22 +00004028 if (offset == 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07004029 return 0;
4030 if (bytecount == 0)
4031 return 1;
kumarashishg826308d2023-06-23 13:21:22 +00004032 if (tif->tif_dir.td_compression != COMPRESSION_NONE)
Haibo Huang49cc9302020-04-27 16:14:24 -07004033 return 0;
4034 filesize = TIFFGetFileSize(tif);
kumarashishg826308d2023-06-23 13:21:22 +00004035 if (offset <= filesize && bytecount > filesize - offset)
Haibo Huang49cc9302020-04-27 16:14:24 -07004036 return 1;
kumarashishg826308d2023-06-23 13:21:22 +00004037 if (tif->tif_mode == O_RDONLY)
Haibo Huang49cc9302020-04-27 16:14:24 -07004038 {
kumarashishg826308d2023-06-23 13:21:22 +00004039 uint64_t scanlinesize = TIFFScanlineSize64(tif);
4040 if (tif->tif_dir.td_imagelength > 0 &&
4041 scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength)
Haibo Huang49cc9302020-04-27 16:14:24 -07004042 {
4043 return 1;
4044 }
kumarashishg826308d2023-06-23 13:21:22 +00004045 if (bytecount < scanlinesize * tif->tif_dir.td_imagelength)
Haibo Huang49cc9302020-04-27 16:14:24 -07004046 return 1;
4047 }
4048 return 0;
4049}
4050
Haibo Huang49cc9302020-04-27 16:14:24 -07004051/*
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004052 * Read the next TIFF directory from a file and convert it to the internal
4053 * format. We read directories sequentially.
4054 */
kumarashishg826308d2023-06-23 13:21:22 +00004055int TIFFReadDirectory(TIFF *tif)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004056{
kumarashishg826308d2023-06-23 13:21:22 +00004057 static const char module[] = "TIFFReadDirectory";
4058 TIFFDirEntry *dir;
4059 uint16_t dircount;
4060 TIFFDirEntry *dp;
4061 uint16_t di;
4062 const TIFFField *fip;
4063 uint32_t fii = FAILED_FII;
4064 toff_t nextdiroff;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004065 int bitspersample_read = FALSE;
kumarashishg826308d2023-06-23 13:21:22 +00004066 int color_channels;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004067
kumarashishg826308d2023-06-23 13:21:22 +00004068 if (tif->tif_nextdiroff == 0)
4069 {
4070 /* In this special case, tif_diroff needs also to be set to 0. */
4071 tif->tif_diroff = tif->tif_nextdiroff;
4072 return 0; /* last offset, thus no checking necessary */
4073 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004074
kumarashishg826308d2023-06-23 13:21:22 +00004075 nextdiroff = tif->tif_nextdiroff;
4076 /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL
4077 * reading of the directory. Otherwise, invalid IFD offsets could corrupt
4078 * the IFD list. */
4079 if (!_TIFFCheckDirNumberAndOffset(tif,
4080 tif->tif_curdir ==
4081 TIFF_NON_EXISTENT_DIR_NUMBER
4082 ? 0
4083 : tif->tif_curdir + 1,
4084 nextdiroff))
4085 {
4086 return 0; /* bad offset (IFD looping or more than TIFF_MAX_DIR_COUNT
4087 IFDs) */
4088 }
4089 dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff);
4090 if (!dircount)
4091 {
4092 TIFFErrorExtR(tif, module,
4093 "Failed to read directory at offset %" PRIu64,
4094 nextdiroff);
4095 return 0;
4096 }
4097 /* Set global values after a valid directory has been fetched.
4098 * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the
4099 * beginning. */
4100 if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
4101 tif->tif_curdir = 0;
4102 else
4103 tif->tif_curdir++;
4104 (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
4105
4106 TIFFReadDirectoryCheckOrder(tif, dir, dircount);
4107
4108 /*
4109 * Mark duplicates of any tag to be ignored (bugzilla 1994)
4110 * to avoid certain pathological problems.
4111 */
4112 {
4113 TIFFDirEntry *ma;
4114 uint16_t mb;
4115 for (ma = dir, mb = 0; mb < dircount; ma++, mb++)
4116 {
4117 TIFFDirEntry *na;
4118 uint16_t nb;
4119 for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++)
4120 {
4121 if (ma->tdir_tag == na->tdir_tag)
4122 {
4123 na->tdir_ignore = TRUE;
4124 }
4125 }
4126 }
4127 }
4128
4129 tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
4130 tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
4131 tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
4132
4133 /* free any old stuff and reinit */
4134 TIFFFreeDirectory(tif);
4135 TIFFDefaultDirectory(tif);
4136 /*
4137 * Electronic Arts writes gray-scale TIFF files
4138 * without a PlanarConfiguration directory entry.
4139 * Thus we setup a default value here, even though
4140 * the TIFF spec says there is no default value.
4141 * After PlanarConfiguration is preset in TIFFDefaultDirectory()
4142 * the following setting is not needed, but does not harm either.
4143 */
4144 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
4145 /*
4146 * Setup default value and then make a pass over
4147 * the fields to check type and tag information,
4148 * and to extract info required to size data
4149 * structures. A second pass is made afterwards
4150 * to read in everything not taken in the first pass.
4151 * But we must process the Compression tag first
4152 * in order to merge in codec-private tag definitions (otherwise
4153 * we may get complaints about unknown tags). However, the
4154 * Compression tag may be dependent on the SamplesPerPixel
4155 * tag value because older TIFF specs permitted Compression
4156 * to be written as a SamplesPerPixel-count tag entry.
4157 * Thus if we don't first figure out the correct SamplesPerPixel
4158 * tag value then we may end up ignoring the Compression tag
4159 * value because it has an incorrect count value (if the
4160 * true value of SamplesPerPixel is not 1).
4161 */
4162 dp =
4163 TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL);
4164 if (dp)
4165 {
4166 if (!TIFFFetchNormalTag(tif, dp, 0))
4167 goto bad;
4168 dp->tdir_ignore = TRUE;
4169 }
4170 dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION);
4171 if (dp)
4172 {
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004173 /*
kumarashishg826308d2023-06-23 13:21:22 +00004174 * The 5.0 spec says the Compression tag has one value, while
4175 * earlier specs say it has one value per sample. Because of
4176 * this, we accept the tag if one value is supplied with either
4177 * count.
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004178 */
kumarashishg826308d2023-06-23 13:21:22 +00004179 uint16_t value;
4180 enum TIFFReadDirEntryErr err;
4181 err = TIFFReadDirEntryShort(tif, dp, &value);
4182 if (err == TIFFReadDirEntryErrCount)
4183 err = TIFFReadDirEntryPersampleShort(tif, dp, &value);
4184 if (err != TIFFReadDirEntryErrOk)
4185 {
4186 TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0);
4187 goto bad;
4188 }
4189 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value))
4190 goto bad;
4191 dp->tdir_ignore = TRUE;
4192 }
4193 else
4194 {
4195 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE))
4196 goto bad;
4197 }
4198 /*
4199 * First real pass over the directory.
4200 */
4201 for (di = 0, dp = dir; di < dircount; di++, dp++)
4202 {
4203 if (!dp->tdir_ignore)
4204 {
4205 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
4206 if (fii == FAILED_FII)
4207 {
4208 TIFFWarningExtR(tif, module,
4209 "Unknown field with tag %" PRIu16 " (0x%" PRIx16
4210 ") encountered",
4211 dp->tdir_tag, dp->tdir_tag);
4212 /* the following knowingly leaks the
4213 anonymous field structure */
4214 if (!_TIFFMergeFields(
4215 tif,
4216 _TIFFCreateAnonField(tif, dp->tdir_tag,
4217 (TIFFDataType)dp->tdir_type),
4218 1))
4219 {
4220 TIFFWarningExtR(
4221 tif, module,
4222 "Registering anonymous field with tag %" PRIu16
4223 " (0x%" PRIx16 ") failed",
4224 dp->tdir_tag, dp->tdir_tag);
4225 dp->tdir_ignore = TRUE;
4226 }
4227 else
4228 {
4229 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
4230 assert(fii != FAILED_FII);
4231 }
4232 }
4233 }
4234 if (!dp->tdir_ignore)
4235 {
4236 fip = tif->tif_fields[fii];
4237 if (fip->field_bit == FIELD_IGNORE)
4238 dp->tdir_ignore = TRUE;
4239 else
4240 {
4241 switch (dp->tdir_tag)
4242 {
4243 case TIFFTAG_STRIPOFFSETS:
4244 case TIFFTAG_STRIPBYTECOUNTS:
4245 case TIFFTAG_TILEOFFSETS:
4246 case TIFFTAG_TILEBYTECOUNTS:
4247 TIFFSetFieldBit(tif, fip->field_bit);
4248 break;
4249 case TIFFTAG_IMAGEWIDTH:
4250 case TIFFTAG_IMAGELENGTH:
4251 case TIFFTAG_IMAGEDEPTH:
4252 case TIFFTAG_TILELENGTH:
4253 case TIFFTAG_TILEWIDTH:
4254 case TIFFTAG_TILEDEPTH:
4255 case TIFFTAG_PLANARCONFIG:
4256 case TIFFTAG_ROWSPERSTRIP:
4257 case TIFFTAG_EXTRASAMPLES:
4258 if (!TIFFFetchNormalTag(tif, dp, 0))
4259 goto bad;
4260 dp->tdir_ignore = TRUE;
4261 break;
4262 default:
4263 if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag))
4264 dp->tdir_ignore = TRUE;
4265 break;
4266 }
4267 }
4268 }
4269 }
4270 /*
4271 * XXX: OJPEG hack.
4272 * If a) compression is OJPEG, b) planarconfig tag says it's separate,
4273 * c) strip offsets/bytecounts tag are both present and
4274 * d) both contain exactly one value, then we consistently find
4275 * that the buggy implementation of the buggy compression scheme
4276 * matches contig planarconfig best. So we 'fix-up' the tag here
4277 */
4278 if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) &&
4279 (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE))
4280 {
4281 if (!_TIFFFillStriles(tif))
4282 goto bad;
4283 dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
4284 TIFFTAG_STRIPOFFSETS);
4285 if ((dp != 0) && (dp->tdir_count == 1))
4286 {
4287 dp = TIFFReadDirectoryFindEntry(tif, dir, dircount,
4288 TIFFTAG_STRIPBYTECOUNTS);
4289 if ((dp != 0) && (dp->tdir_count == 1))
4290 {
4291 tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
4292 TIFFWarningExtR(tif, module,
4293 "Planarconfig tag value assumed incorrect, "
4294 "assuming data is contig instead of chunky");
4295 }
4296 }
4297 }
4298 /*
4299 * Allocate directory structure and setup defaults.
4300 */
4301 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
4302 {
4303 MissingRequired(tif, "ImageLength");
4304 goto bad;
4305 }
Haibo Huang49cc9302020-04-27 16:14:24 -07004306
kumarashishg826308d2023-06-23 13:21:22 +00004307 /*
4308 * Second pass: extract other information.
4309 */
4310 for (di = 0, dp = dir; di < dircount; di++, dp++)
4311 {
4312 if (!dp->tdir_ignore)
4313 {
4314 switch (dp->tdir_tag)
4315 {
4316 case TIFFTAG_MINSAMPLEVALUE:
4317 case TIFFTAG_MAXSAMPLEVALUE:
4318 case TIFFTAG_BITSPERSAMPLE:
4319 case TIFFTAG_DATATYPE:
4320 case TIFFTAG_SAMPLEFORMAT:
4321 /*
4322 * The MinSampleValue, MaxSampleValue, BitsPerSample
4323 * DataType and SampleFormat tags are supposed to be
4324 * written as one value/sample, but some vendors
4325 * incorrectly write one value only -- so we accept
4326 * that as well (yuck). Other vendors write correct
4327 * value for NumberOfSamples, but incorrect one for
4328 * BitsPerSample and friends, and we will read this
4329 * too.
4330 */
4331 {
4332 uint16_t value;
4333 enum TIFFReadDirEntryErr err;
4334 err = TIFFReadDirEntryShort(tif, dp, &value);
4335 if (err == TIFFReadDirEntryErrCount)
4336 err =
4337 TIFFReadDirEntryPersampleShort(tif, dp, &value);
4338 if (err != TIFFReadDirEntryErrOk)
4339 {
4340 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4341 TIFFReadDirEntryOutputErr(
4342 tif, err, module,
4343 fip ? fip->field_name : "unknown tagname", 0);
4344 goto bad;
4345 }
4346 if (!TIFFSetField(tif, dp->tdir_tag, value))
4347 goto bad;
4348 if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE)
4349 bitspersample_read = TRUE;
4350 }
4351 break;
4352 case TIFFTAG_SMINSAMPLEVALUE:
4353 case TIFFTAG_SMAXSAMPLEVALUE:
4354 {
4355
4356 double *data = NULL;
4357 enum TIFFReadDirEntryErr err;
4358 uint32_t saved_flags;
4359 int m;
4360 if (dp->tdir_count !=
4361 (uint64_t)tif->tif_dir.td_samplesperpixel)
4362 err = TIFFReadDirEntryErrCount;
4363 else
4364 err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
4365 if (err != TIFFReadDirEntryErrOk)
4366 {
4367 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4368 TIFFReadDirEntryOutputErr(
4369 tif, err, module,
4370 fip ? fip->field_name : "unknown tagname", 0);
4371 goto bad;
4372 }
4373 saved_flags = tif->tif_flags;
4374 tif->tif_flags |= TIFF_PERSAMPLE;
4375 m = TIFFSetField(tif, dp->tdir_tag, data);
4376 tif->tif_flags = saved_flags;
4377 _TIFFfreeExt(tif, data);
4378 if (!m)
4379 goto bad;
4380 }
4381 break;
4382 case TIFFTAG_STRIPOFFSETS:
4383 case TIFFTAG_TILEOFFSETS:
4384 switch (dp->tdir_type)
4385 {
4386 case TIFF_SHORT:
4387 case TIFF_LONG:
4388 case TIFF_LONG8:
4389 break;
4390 default:
4391 /* Warn except if directory typically created with
4392 * TIFFDeferStrileArrayWriting() */
4393 if (!(tif->tif_mode == O_RDWR &&
4394 dp->tdir_count == 0 && dp->tdir_type == 0 &&
4395 dp->tdir_offset.toff_long8 == 0))
4396 {
4397 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4398 TIFFWarningExtR(
4399 tif, module, "Invalid data type for tag %s",
4400 fip ? fip->field_name : "unknown tagname");
4401 }
4402 break;
4403 }
4404 _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp,
4405 sizeof(TIFFDirEntry));
4406 break;
4407 case TIFFTAG_STRIPBYTECOUNTS:
4408 case TIFFTAG_TILEBYTECOUNTS:
4409 switch (dp->tdir_type)
4410 {
4411 case TIFF_SHORT:
4412 case TIFF_LONG:
4413 case TIFF_LONG8:
4414 break;
4415 default:
4416 /* Warn except if directory typically created with
4417 * TIFFDeferStrileArrayWriting() */
4418 if (!(tif->tif_mode == O_RDWR &&
4419 dp->tdir_count == 0 && dp->tdir_type == 0 &&
4420 dp->tdir_offset.toff_long8 == 0))
4421 {
4422 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4423 TIFFWarningExtR(
4424 tif, module, "Invalid data type for tag %s",
4425 fip ? fip->field_name : "unknown tagname");
4426 }
4427 break;
4428 }
4429 _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp,
4430 sizeof(TIFFDirEntry));
4431 break;
4432 case TIFFTAG_COLORMAP:
4433 case TIFFTAG_TRANSFERFUNCTION:
4434 {
4435 enum TIFFReadDirEntryErr err;
4436 uint32_t countpersample;
4437 uint32_t countrequired;
4438 uint32_t incrementpersample;
4439 uint16_t *value = NULL;
4440 /* It would be dangerous to instantiate those tag values */
4441 /* since if td_bitspersample has not yet been read (due to
4442 */
4443 /* unordered tags), it could be read afterwards with a */
4444 /* values greater than the default one (1), which may cause
4445 */
4446 /* crashes in user code */
4447 if (!bitspersample_read)
4448 {
4449 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4450 TIFFWarningExtR(
4451 tif, module,
4452 "Ignoring %s since BitsPerSample tag not found",
4453 fip ? fip->field_name : "unknown tagname");
4454 continue;
4455 }
4456 /* ColorMap or TransferFunction for high bit */
4457 /* depths do not make much sense and could be */
4458 /* used as a denial of service vector */
4459 if (tif->tif_dir.td_bitspersample > 24)
4460 {
4461 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4462 TIFFWarningExtR(
4463 tif, module,
4464 "Ignoring %s because BitsPerSample=%" PRIu16 ">24",
4465 fip ? fip->field_name : "unknown tagname",
4466 tif->tif_dir.td_bitspersample);
4467 continue;
4468 }
4469 countpersample = (1U << tif->tif_dir.td_bitspersample);
4470 if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) &&
4471 (dp->tdir_count == (uint64_t)countpersample))
4472 {
4473 countrequired = countpersample;
4474 incrementpersample = 0;
4475 }
4476 else
4477 {
4478 countrequired = 3 * countpersample;
4479 incrementpersample = countpersample;
4480 }
4481 if (dp->tdir_count != (uint64_t)countrequired)
4482 err = TIFFReadDirEntryErrCount;
4483 else
4484 err = TIFFReadDirEntryShortArray(tif, dp, &value);
4485 if (err != TIFFReadDirEntryErrOk)
4486 {
4487 fip = TIFFFieldWithTag(tif, dp->tdir_tag);
4488 TIFFReadDirEntryOutputErr(
4489 tif, err, module,
4490 fip ? fip->field_name : "unknown tagname", 1);
4491 }
4492 else
4493 {
4494 TIFFSetField(tif, dp->tdir_tag, value,
4495 value + incrementpersample,
4496 value + 2 * incrementpersample);
4497 _TIFFfreeExt(tif, value);
4498 }
4499 }
4500 break;
4501 /* BEGIN REV 4.0 COMPATIBILITY */
4502 case TIFFTAG_OSUBFILETYPE:
4503 {
4504 uint16_t valueo;
4505 uint32_t value;
4506 if (TIFFReadDirEntryShort(tif, dp, &valueo) ==
4507 TIFFReadDirEntryErrOk)
4508 {
4509 switch (valueo)
4510 {
4511 case OFILETYPE_REDUCEDIMAGE:
4512 value = FILETYPE_REDUCEDIMAGE;
4513 break;
4514 case OFILETYPE_PAGE:
4515 value = FILETYPE_PAGE;
4516 break;
4517 default:
4518 value = 0;
4519 break;
4520 }
4521 if (value != 0)
4522 TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value);
4523 }
4524 }
4525 break;
4526 /* END REV 4.0 COMPATIBILITY */
4527 default:
4528 (void)TIFFFetchNormalTag(tif, dp, TRUE);
4529 break;
4530 }
4531 } /* -- if (!dp->tdir_ignore) */
4532 } /* -- for-loop -- */
4533
4534 /*
4535 * OJPEG hack:
4536 * - If a) compression is OJPEG, and b) photometric tag is missing,
4537 * then we consistently find that photometric should be YCbCr
4538 * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
4539 * then we consistently find that the buggy implementation of the
4540 * buggy compression scheme matches photometric YCbCr instead.
4541 * - If a) compression is OJPEG, and b) bitspersample tag is missing,
4542 * then we consistently find bitspersample should be 8.
4543 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
4544 * and c) photometric is RGB or YCbCr, then we consistently find
4545 * samplesperpixel should be 3
4546 * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
4547 * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
4548 * find samplesperpixel should be 3
4549 */
4550 if (tif->tif_dir.td_compression == COMPRESSION_OJPEG)
4551 {
4552 if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
4553 {
4554 TIFFWarningExtR(
4555 tif, module,
4556 "Photometric tag is missing, assuming data is YCbCr");
4557 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR))
4558 goto bad;
4559 }
4560 else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
4561 {
4562 tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR;
4563 TIFFWarningExtR(tif, module,
4564 "Photometric tag value assumed incorrect, "
4565 "assuming data is YCbCr instead of RGB");
4566 }
4567 if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
4568 {
4569 TIFFWarningExtR(
4570 tif, module,
4571 "BitsPerSample tag is missing, assuming 8 bits per sample");
4572 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8))
4573 goto bad;
4574 }
4575 if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
4576 {
4577 if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB)
4578 {
4579 TIFFWarningExtR(tif, module,
4580 "SamplesPerPixel tag is missing, "
4581 "assuming correct SamplesPerPixel value is 3");
4582 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
4583 goto bad;
4584 }
4585 if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR)
4586 {
4587 TIFFWarningExtR(tif, module,
4588 "SamplesPerPixel tag is missing, "
4589 "applying correct SamplesPerPixel value of 3");
4590 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3))
4591 goto bad;
4592 }
4593 else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) ||
4594 (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK))
4595 {
4596 /*
4597 * SamplesPerPixel tag is missing, but is not required
4598 * by spec. Assume correct SamplesPerPixel value of 1.
4599 */
4600 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
4601 goto bad;
4602 }
4603 }
4604 }
4605
4606 /*
4607 * Setup appropriate structures (by strip or by tile)
4608 * We do that only after the above OJPEG hack which alters SamplesPerPixel
4609 * and thus influences the number of strips in the separate planarconfig.
4610 */
4611 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
4612 {
4613 tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
4614 tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
4615 tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
4616 tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
4617 tif->tif_flags &= ~TIFF_ISTILED;
4618 }
4619 else
4620 {
4621 tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
4622 tif->tif_flags |= TIFF_ISTILED;
4623 }
4624 if (!tif->tif_dir.td_nstrips)
4625 {
4626 TIFFErrorExtR(tif, module, "Cannot handle zero number of %s",
4627 isTiled(tif) ? "tiles" : "strips");
4628 goto bad;
4629 }
4630 if (tif->tif_dir.td_nstrips > INT_MAX)
4631 {
4632 TIFFErrorExt(tif->tif_clientdata, module,
4633 "Cannot handle %u number of %s",
4634 tif->tif_dir.td_nstrips,
4635 isTiled(tif) ? "tiles" : "strips");
4636 goto bad;
4637 }
4638 tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
4639 if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
4640 tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
4641 if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
4642 {
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07004643#ifdef OJPEG_SUPPORT
kumarashishg826308d2023-06-23 13:21:22 +00004644 if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) &&
4645 (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1))
4646 {
4647 /*
4648 * XXX: OJPEG hack.
4649 * If a) compression is OJPEG, b) it's not a tiled TIFF,
4650 * and c) the number of strips is 1,
4651 * then we tolerate the absence of stripoffsets tag,
4652 * because, presumably, all required data is in the
4653 * JpegInterchangeFormat stream.
4654 */
4655 TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
4656 }
4657 else
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07004658#endif
4659 {
kumarashishg826308d2023-06-23 13:21:22 +00004660 MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets");
4661 goto bad;
Haibo Huang49cc9302020-04-27 16:14:24 -07004662 }
kumarashishg826308d2023-06-23 13:21:22 +00004663 }
4664
4665 if (tif->tif_mode == O_RDWR &&
4666 tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
4667 tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
4668 tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
4669 tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
4670 tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
4671 tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
4672 tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
4673 tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
4674 {
4675 /* Directory typically created with TIFFDeferStrileArrayWriting() */
4676 TIFFSetupStrips(tif);
4677 }
4678 else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD))
4679 {
4680 if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07004681 {
kumarashishg826308d2023-06-23 13:21:22 +00004682 if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry),
4683 tif->tif_dir.td_nstrips,
4684 &tif->tif_dir.td_stripoffset_p))
Haibo Huang49cc9302020-04-27 16:14:24 -07004685 {
kumarashishg826308d2023-06-23 13:21:22 +00004686 goto bad;
Haibo Huang49cc9302020-04-27 16:14:24 -07004687 }
4688 }
kumarashishg826308d2023-06-23 13:21:22 +00004689 if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0)
4690 {
4691 if (!TIFFFetchStripThing(
4692 tif, &(tif->tif_dir.td_stripbytecount_entry),
4693 tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p))
4694 {
4695 goto bad;
4696 }
4697 }
4698 }
Haibo Huang49cc9302020-04-27 16:14:24 -07004699
kumarashishg826308d2023-06-23 13:21:22 +00004700 /*
4701 * Make sure all non-color channels are extrasamples.
4702 * If it's not the case, define them as such.
4703 */
4704 color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric);
4705 if (color_channels &&
4706 tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples >
4707 color_channels)
4708 {
4709 uint16_t old_extrasamples;
4710 uint16_t *new_sampleinfo;
Haibo Huang49cc9302020-04-27 16:14:24 -07004711
kumarashishg826308d2023-06-23 13:21:22 +00004712 TIFFWarningExtR(
4713 tif, module,
4714 "Sum of Photometric type-related "
4715 "color channels and ExtraSamples doesn't match SamplesPerPixel. "
4716 "Defining non-color channels as ExtraSamples.");
Haibo Huang49cc9302020-04-27 16:14:24 -07004717
kumarashishg826308d2023-06-23 13:21:22 +00004718 old_extrasamples = tif->tif_dir.td_extrasamples;
4719 tif->tif_dir.td_extrasamples =
4720 (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels);
Haibo Huang49cc9302020-04-27 16:14:24 -07004721
kumarashishg826308d2023-06-23 13:21:22 +00004722 // sampleinfo should contain information relative to these new extra
4723 // samples
4724 new_sampleinfo = (uint16_t *)_TIFFcallocExt(
4725 tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t));
4726 if (!new_sampleinfo)
4727 {
4728 TIFFErrorExtR(tif, module,
4729 "Failed to allocate memory for "
4730 "temporary new sampleinfo array "
4731 "(%" PRIu16 " 16 bit elements)",
4732 tif->tif_dir.td_extrasamples);
4733 goto bad;
Haibo Huang49cc9302020-04-27 16:14:24 -07004734 }
4735
kumarashishg826308d2023-06-23 13:21:22 +00004736 if (old_extrasamples > 0)
4737 memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo,
4738 old_extrasamples * sizeof(uint16_t));
4739 _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo,
4740 tif->tif_dir.td_extrasamples);
4741 _TIFFfreeExt(tif, new_sampleinfo);
4742 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004743
kumarashishg826308d2023-06-23 13:21:22 +00004744 /*
4745 * Verify Palette image has a Colormap.
4746 */
4747 if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
4748 !TIFFFieldSet(tif, FIELD_COLORMAP))
4749 {
4750 if (tif->tif_dir.td_bitspersample >= 8 &&
4751 tif->tif_dir.td_samplesperpixel == 3)
4752 tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
4753 else if (tif->tif_dir.td_bitspersample >= 8)
4754 tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
4755 else
4756 {
4757 MissingRequired(tif, "Colormap");
4758 goto bad;
4759 }
4760 }
4761 /*
4762 * OJPEG hack:
4763 * We do no further messing with strip/tile offsets/bytecounts in OJPEG
4764 * TIFFs
4765 */
4766 if (tif->tif_dir.td_compression != COMPRESSION_OJPEG)
4767 {
4768 /*
4769 * Attempt to deal with a missing StripByteCounts tag.
4770 */
4771 if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
4772 {
4773 /*
4774 * Some manufacturers violate the spec by not giving
4775 * the size of the strips. In this case, assume there
4776 * is one uncompressed strip of data.
4777 */
4778 if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4779 tif->tif_dir.td_nstrips > 1) ||
4780 (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
4781 tif->tif_dir.td_nstrips !=
4782 (uint32_t)tif->tif_dir.td_samplesperpixel))
4783 {
4784 MissingRequired(tif, "StripByteCounts");
4785 goto bad;
4786 }
4787 TIFFWarningExtR(
4788 tif, module,
4789 "TIFF directory is missing required "
4790 "\"StripByteCounts\" field, calculating from imagelength");
4791 if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4792 goto bad;
4793 }
4794 else if (tif->tif_dir.td_nstrips == 1 &&
4795 !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif))
4796 {
4797 /*
4798 * XXX: Plexus (and others) sometimes give a value of
4799 * zero for a tag when they don't know what the
4800 * correct value is! Try and handle the simple case
4801 * of estimating the size of a one strip image.
4802 */
4803 TIFFWarningExtR(tif, module,
4804 "Bogus \"StripByteCounts\" field, ignoring and "
4805 "calculating from imagelength");
4806 if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4807 goto bad;
4808 }
4809 else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
4810 tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4811 tif->tif_dir.td_nstrips > 2 &&
4812 tif->tif_dir.td_compression == COMPRESSION_NONE &&
4813 TIFFGetStrileByteCount(tif, 0) !=
4814 TIFFGetStrileByteCount(tif, 1) &&
4815 TIFFGetStrileByteCount(tif, 0) != 0 &&
4816 TIFFGetStrileByteCount(tif, 1) != 0)
4817 {
4818 /*
4819 * XXX: Some vendors fill StripByteCount array with
4820 * absolutely wrong values (it can be equal to
4821 * StripOffset array, for example). Catch this case
4822 * here.
4823 *
4824 * We avoid this check if deferring strile loading
4825 * as it would always force us to load the strip/tile
4826 * information.
4827 */
4828 TIFFWarningExtR(tif, module,
4829 "Wrong \"StripByteCounts\" field, ignoring and "
4830 "calculating from imagelength");
4831 if (EstimateStripByteCounts(tif, dir, dircount) < 0)
4832 goto bad;
4833 }
4834 }
4835 if (dir)
4836 {
4837 _TIFFfreeExt(tif, dir);
4838 dir = NULL;
4839 }
4840 if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
4841 {
4842 if (tif->tif_dir.td_bitspersample >= 16)
4843 tif->tif_dir.td_maxsamplevalue = 0xFFFF;
4844 else
4845 tif->tif_dir.td_maxsamplevalue =
4846 (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1);
4847 }
Haibo Huang49cc9302020-04-27 16:14:24 -07004848
4849#ifdef STRIPBYTECOUNTSORTED_UNUSED
kumarashishg826308d2023-06-23 13:21:22 +00004850 /*
4851 * XXX: We can optimize checking for the strip bounds using the sorted
4852 * bytecounts array. See also comments for TIFFAppendToStrip()
4853 * function in tif_write.c.
4854 */
4855 if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1)
4856 {
4857 uint32_t strip;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004858
kumarashishg826308d2023-06-23 13:21:22 +00004859 tif->tif_dir.td_stripbytecountsorted = 1;
4860 for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
4861 {
4862 if (TIFFGetStrileOffset(tif, strip - 1) >
4863 TIFFGetStrileOffset(tif, strip))
4864 {
4865 tif->tif_dir.td_stripbytecountsorted = 0;
4866 break;
4867 }
4868 }
4869 }
Haibo Huang49cc9302020-04-27 16:14:24 -07004870#endif
4871
kumarashishg826308d2023-06-23 13:21:22 +00004872 /*
4873 * An opportunity for compression mode dependent tag fixup
4874 */
4875 (*tif->tif_fixuptags)(tif);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004876
kumarashishg826308d2023-06-23 13:21:22 +00004877 /*
4878 * Some manufacturers make life difficult by writing
4879 * large amounts of uncompressed data as a single strip.
4880 * This is contrary to the recommendations of the spec.
4881 * The following makes an attempt at breaking such images
4882 * into strips closer to the recommended 8k bytes. A
4883 * side effect, however, is that the RowsPerStrip tag
4884 * value may be changed.
4885 */
4886 if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
4887 (tif->tif_dir.td_nstrips == 1) &&
4888 (tif->tif_dir.td_compression == COMPRESSION_NONE) &&
4889 ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP))
4890 {
4891 ChopUpSingleUncompressedStrip(tif);
4892 }
4893
4894 /* There are also uncompressed striped files with strips larger than */
4895 /* 2 GB, which make them unfriendly with a lot of code. If possible, */
4896 /* try to expose smaller "virtual" strips. */
4897 if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
4898 tif->tif_dir.td_compression == COMPRESSION_NONE &&
4899 (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP &&
4900 TIFFStripSize64(tif) > 0x7FFFFFFFUL)
4901 {
4902 TryChopUpUncompressedBigTiff(tif);
4903 }
4904
4905 /*
4906 * Clear the dirty directory flag.
4907 */
4908 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
4909 tif->tif_flags &= ~TIFF_DIRTYSTRIP;
4910
4911 /*
4912 * Reinitialize i/o since we are starting on a new directory.
4913 */
4914 tif->tif_row = (uint32_t)-1;
4915 tif->tif_curstrip = (uint32_t)-1;
4916 tif->tif_col = (uint32_t)-1;
4917 tif->tif_curtile = (uint32_t)-1;
4918 tif->tif_tilesize = (tmsize_t)-1;
4919
4920 tif->tif_scanlinesize = TIFFScanlineSize(tif);
4921 if (!tif->tif_scanlinesize)
4922 {
4923 TIFFErrorExtR(tif, module, "Cannot handle zero scanline size");
4924 return (0);
4925 }
4926
4927 if (isTiled(tif))
4928 {
4929 tif->tif_tilesize = TIFFTileSize(tif);
4930 if (!tif->tif_tilesize)
Haibo Huang49cc9302020-04-27 16:14:24 -07004931 {
kumarashishg826308d2023-06-23 13:21:22 +00004932 TIFFErrorExtR(tif, module, "Cannot handle zero tile size");
4933 return (0);
Haibo Huang49cc9302020-04-27 16:14:24 -07004934 }
kumarashishg826308d2023-06-23 13:21:22 +00004935 }
4936 else
4937 {
4938 if (!TIFFStripSize(tif))
Haibo Huang49cc9302020-04-27 16:14:24 -07004939 {
kumarashishg826308d2023-06-23 13:21:22 +00004940 TIFFErrorExtR(tif, module, "Cannot handle zero strip size");
4941 return (0);
Haibo Huang49cc9302020-04-27 16:14:24 -07004942 }
kumarashishg826308d2023-06-23 13:21:22 +00004943 }
4944 return (1);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004945bad:
kumarashishg826308d2023-06-23 13:21:22 +00004946 if (dir)
4947 _TIFFfreeExt(tif, dir);
4948 return (0);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004949}
4950
kumarashishg826308d2023-06-23 13:21:22 +00004951static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
4952 uint16_t dircount)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004953{
kumarashishg826308d2023-06-23 13:21:22 +00004954 static const char module[] = "TIFFReadDirectoryCheckOrder";
4955 uint16_t m;
4956 uint16_t n;
4957 TIFFDirEntry *o;
4958 m = 0;
4959 for (n = 0, o = dir; n < dircount; n++, o++)
4960 {
4961 if (o->tdir_tag < m)
4962 {
4963 TIFFWarningExtR(tif, module,
4964 "Invalid TIFF directory; tags are not sorted in "
4965 "ascending order");
4966 break;
4967 }
4968 m = o->tdir_tag + 1;
4969 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004970}
4971
kumarashishg826308d2023-06-23 13:21:22 +00004972static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
4973 uint16_t dircount,
4974 uint16_t tagid)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004975{
kumarashishg826308d2023-06-23 13:21:22 +00004976 TIFFDirEntry *m;
4977 uint16_t n;
4978 (void)tif;
4979 for (m = dir, n = 0; n < dircount; m++, n++)
4980 {
4981 if (m->tdir_tag == tagid)
4982 return (m);
4983 }
4984 return (0);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004985}
4986
kumarashishg826308d2023-06-23 13:21:22 +00004987static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
4988 uint32_t *fii)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08004989{
kumarashishg826308d2023-06-23 13:21:22 +00004990 int32_t ma, mb, mc;
4991 ma = -1;
4992 mc = (int32_t)tif->tif_nfields;
4993 while (1)
4994 {
4995 if (ma + 1 == mc)
4996 {
4997 *fii = FAILED_FII;
4998 return;
4999 }
5000 mb = (ma + mc) / 2;
5001 if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid)
5002 break;
5003 if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid)
5004 ma = mb;
5005 else
5006 mc = mb;
5007 }
5008 while (1)
5009 {
5010 if (mb == 0)
5011 break;
5012 if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid)
5013 break;
5014 mb--;
5015 }
5016 *fii = mb;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005017}
5018
5019/*
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07005020 * Read custom directory from the arbitrary offset.
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005021 * The code is very similar to TIFFReadDirectory().
5022 */
kumarashishg826308d2023-06-23 13:21:22 +00005023int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
5024 const TIFFFieldArray *infoarray)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005025{
kumarashishg826308d2023-06-23 13:21:22 +00005026 static const char module[] = "TIFFReadCustomDirectory";
5027 TIFFDirEntry *dir;
5028 uint16_t dircount;
5029 TIFFDirEntry *dp;
5030 uint16_t di;
5031 const TIFFField *fip;
5032 uint32_t fii;
5033 (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
5034 _TIFFSetupFields(tif, infoarray);
5035 dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
5036 if (!dircount)
5037 {
5038 TIFFErrorExtR(tif, module,
5039 "Failed to read custom directory at offset %" PRIu64,
5040 diroff);
5041 return 0;
5042 }
5043 TIFFFreeDirectory(tif);
5044 _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
5045 TIFFReadDirectoryCheckOrder(tif, dir, dircount);
5046 for (di = 0, dp = dir; di < dircount; di++, dp++)
5047 {
5048 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
5049 if (fii == FAILED_FII)
5050 {
5051 TIFFWarningExtR(tif, module,
5052 "Unknown field with tag %" PRIu16 " (0x%" PRIx16
5053 ") encountered",
5054 dp->tdir_tag, dp->tdir_tag);
5055 if (!_TIFFMergeFields(
5056 tif,
5057 _TIFFCreateAnonField(tif, dp->tdir_tag,
5058 (TIFFDataType)dp->tdir_type),
5059 1))
5060 {
5061 TIFFWarningExtR(tif, module,
5062 "Registering anonymous field with tag %" PRIu16
5063 " (0x%" PRIx16 ") failed",
5064 dp->tdir_tag, dp->tdir_tag);
5065 dp->tdir_ignore = TRUE;
5066 }
5067 else
5068 {
5069 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
5070 assert(fii != FAILED_FII);
5071 }
5072 }
5073 if (!dp->tdir_ignore)
5074 {
5075 fip = tif->tif_fields[fii];
5076 if (fip->field_bit == FIELD_IGNORE)
5077 dp->tdir_ignore = TRUE;
5078 else
5079 {
5080 /* check data type */
5081 while ((fip->field_type != TIFF_ANY) &&
5082 (fip->field_type != dp->tdir_type))
5083 {
5084 fii++;
5085 if ((fii == tif->tif_nfields) ||
5086 (tif->tif_fields[fii]->field_tag !=
5087 (uint32_t)dp->tdir_tag))
5088 {
5089 fii = 0xFFFF;
5090 break;
5091 }
5092 fip = tif->tif_fields[fii];
5093 }
5094 if (fii == 0xFFFF)
5095 {
5096 TIFFWarningExtR(tif, module,
5097 "Wrong data type %" PRIu16
5098 " for \"%s\"; tag ignored",
5099 dp->tdir_type, fip->field_name);
5100 dp->tdir_ignore = TRUE;
5101 }
5102 else
5103 {
5104 /* check count if known in advance */
5105 if ((fip->field_readcount != TIFF_VARIABLE) &&
5106 (fip->field_readcount != TIFF_VARIABLE2))
5107 {
5108 uint32_t expected;
5109 if (fip->field_readcount == TIFF_SPP)
5110 expected =
5111 (uint32_t)tif->tif_dir.td_samplesperpixel;
5112 else
5113 expected = (uint32_t)fip->field_readcount;
5114 if (!CheckDirCount(tif, dp, expected))
5115 dp->tdir_ignore = TRUE;
5116 }
5117 }
5118 }
5119 if (!dp->tdir_ignore)
5120 {
5121 switch (dp->tdir_tag)
5122 {
5123 case EXIFTAG_SUBJECTDISTANCE:
5124 if (!TIFFFieldIsAnonymous(fip))
5125 {
5126 /* should only be called on a Exif directory */
5127 /* when exifFields[] is active */
5128 (void)TIFFFetchSubjectDistance(tif, dp);
5129 }
5130 else
5131 {
5132 (void)TIFFFetchNormalTag(tif, dp, TRUE);
5133 }
5134 break;
5135 default:
5136 (void)TIFFFetchNormalTag(tif, dp, TRUE);
5137 break;
5138 }
5139 } /*-- if (!dp->tdir_ignore) */
5140 }
5141 }
5142 if (dir)
5143 _TIFFfreeExt(tif, dir);
5144 return 1;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005145}
5146
5147/*
5148 * EXIF is important special case of custom IFD, so we have a special
5149 * function to read it.
5150 */
kumarashishg826308d2023-06-23 13:21:22 +00005151int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005152{
kumarashishg826308d2023-06-23 13:21:22 +00005153 const TIFFFieldArray *exifFieldArray;
5154 exifFieldArray = _TIFFGetExifFields();
5155 return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005156}
5157
5158/*
kumarashishg826308d2023-06-23 13:21:22 +00005159 *--: EXIF-GPS custom directory reading as another special case of custom IFD.
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005160 */
kumarashishg826308d2023-06-23 13:21:22 +00005161int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005162{
kumarashishg826308d2023-06-23 13:21:22 +00005163 const TIFFFieldArray *gpsFieldArray;
5164 gpsFieldArray = _TIFFGetGpsFields();
5165 return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005166}
5167
kumarashishg826308d2023-06-23 13:21:22 +00005168static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
5169 uint16_t dircount)
5170{
5171 static const char module[] = "EstimateStripByteCounts";
5172
5173 TIFFDirEntry *dp;
5174 TIFFDirectory *td = &tif->tif_dir;
5175 uint32_t strip;
5176
5177 /* Do not try to load stripbytecount as we will compute it */
5178 if (!_TIFFFillStrilesInternal(tif, 0))
5179 return -1;
5180
5181 if (td->td_stripbytecount_p)
5182 _TIFFfreeExt(tif, td->td_stripbytecount_p);
5183 td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
5184 tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
5185 if (td->td_stripbytecount_p == NULL)
5186 return -1;
5187
5188 if (td->td_compression != COMPRESSION_NONE)
5189 {
5190 uint64_t space;
5191 uint64_t filesize;
5192 uint16_t n;
5193 filesize = TIFFGetFileSize(tif);
5194 if (!(tif->tif_flags & TIFF_BIGTIFF))
5195 space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4;
5196 else
5197 space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8;
5198 /* calculate amount of space used by indirect values */
5199 for (dp = dir, n = dircount; n > 0; n--, dp++)
5200 {
5201 uint32_t typewidth;
5202 uint64_t datasize;
5203 typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type);
5204 if (typewidth == 0)
5205 {
5206 TIFFErrorExtR(
5207 tif, module,
5208 "Cannot determine size of unknown tag type %" PRIu16,
5209 dp->tdir_type);
5210 return -1;
5211 }
5212 if (dp->tdir_count > UINT64_MAX / typewidth)
5213 return -1;
5214 datasize = (uint64_t)typewidth * dp->tdir_count;
5215 if (!(tif->tif_flags & TIFF_BIGTIFF))
5216 {
5217 if (datasize <= 4)
5218 datasize = 0;
5219 }
5220 else
5221 {
5222 if (datasize <= 8)
5223 datasize = 0;
5224 }
5225 if (space > UINT64_MAX - datasize)
5226 return -1;
5227 space += datasize;
5228 }
5229 if (filesize < space)
5230 /* we should perhaps return in error ? */
5231 space = filesize;
5232 else
5233 space = filesize - space;
5234 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
5235 space /= td->td_samplesperpixel;
5236 for (strip = 0; strip < td->td_nstrips; strip++)
5237 td->td_stripbytecount_p[strip] = space;
5238 /*
5239 * This gross hack handles the case were the offset to
5240 * the last strip is past the place where we think the strip
5241 * should begin. Since a strip of data must be contiguous,
5242 * it's safe to assume that we've overestimated the amount
5243 * of data in the strip and trim this number back accordingly.
5244 */
5245 strip--;
5246 if (td->td_stripoffset_p[strip] >
5247 UINT64_MAX - td->td_stripbytecount_p[strip])
5248 return -1;
5249 if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] >
5250 filesize)
5251 {
5252 if (td->td_stripoffset_p[strip] >= filesize)
5253 {
5254 /* Not sure what we should in that case... */
5255 td->td_stripbytecount_p[strip] = 0;
5256 }
5257 else
5258 {
5259 td->td_stripbytecount_p[strip] =
5260 filesize - td->td_stripoffset_p[strip];
5261 }
5262 }
5263 }
5264 else if (isTiled(tif))
5265 {
5266 uint64_t bytespertile = TIFFTileSize64(tif);
5267
5268 for (strip = 0; strip < td->td_nstrips; strip++)
5269 td->td_stripbytecount_p[strip] = bytespertile;
5270 }
5271 else
5272 {
5273 uint64_t rowbytes = TIFFScanlineSize64(tif);
5274 uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage;
5275 for (strip = 0; strip < td->td_nstrips; strip++)
5276 {
5277 if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes)
5278 return -1;
5279 td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
5280 }
5281 }
5282 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
5283 if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
5284 td->td_rowsperstrip = td->td_imagelength;
5285 return 1;
5286}
5287
5288static void MissingRequired(TIFF *tif, const char *tagname)
5289{
5290 static const char module[] = "MissingRequired";
5291
5292 TIFFErrorExtR(tif, module,
5293 "TIFF directory is missing required \"%s\" field", tagname);
5294}
5295
5296static unsigned long hashFuncOffsetToNumber(const void *elt)
5297{
5298 const TIFFOffsetAndDirNumber *offsetAndDirNumber =
5299 (const TIFFOffsetAndDirNumber *)elt;
5300 const uint32_t hash = (uint32_t)(offsetAndDirNumber->offset >> 32) ^
5301 ((uint32_t)offsetAndDirNumber->offset & 0xFFFFFFFFU);
5302 return hash;
5303}
5304
5305static bool equalFuncOffsetToNumber(const void *elt1, const void *elt2)
5306{
5307 const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
5308 (const TIFFOffsetAndDirNumber *)elt1;
5309 const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
5310 (const TIFFOffsetAndDirNumber *)elt2;
5311 return offsetAndDirNumber1->offset == offsetAndDirNumber2->offset;
5312}
5313
5314static unsigned long hashFuncNumberToOffset(const void *elt)
5315{
5316 const TIFFOffsetAndDirNumber *offsetAndDirNumber =
5317 (const TIFFOffsetAndDirNumber *)elt;
5318 return offsetAndDirNumber->dirNumber;
5319}
5320
5321static bool equalFuncNumberToOffset(const void *elt1, const void *elt2)
5322{
5323 const TIFFOffsetAndDirNumber *offsetAndDirNumber1 =
5324 (const TIFFOffsetAndDirNumber *)elt1;
5325 const TIFFOffsetAndDirNumber *offsetAndDirNumber2 =
5326 (const TIFFOffsetAndDirNumber *)elt2;
5327 return offsetAndDirNumber1->dirNumber == offsetAndDirNumber2->dirNumber;
5328}
5329
5330/*
5331 * Check the directory number and offset against the list of already seen
5332 * directory numbers and offsets. This is a trick to prevent IFD looping.
5333 * The one can create TIFF file with looped directory pointers. We will
5334 * maintain a list of already seen directories and check every IFD offset
5335 * and its IFD number against that list. However, the offset of an IFD number
5336 * can change - e.g. when writing updates to file.
5337 * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered,
5338 * or an error has occurred.
5339 */
5340int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff)
5341{
5342 if (diroff == 0) /* no more directories */
5343 return 0;
5344
5345 if (tif->tif_map_dir_offset_to_number == NULL)
5346 {
5347 tif->tif_map_dir_offset_to_number = TIFFHashSetNew(
5348 hashFuncOffsetToNumber, equalFuncOffsetToNumber, free);
5349 if (tif->tif_map_dir_offset_to_number == NULL)
5350 {
5351 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5352 "Not enough memory");
5353 return 1;
5354 }
5355 }
5356
5357 if (tif->tif_map_dir_number_to_offset == NULL)
5358 {
5359 /* No free callback for this map, as it shares the same items as
5360 * tif->tif_map_dir_offset_to_number. */
5361 tif->tif_map_dir_number_to_offset = TIFFHashSetNew(
5362 hashFuncNumberToOffset, equalFuncNumberToOffset, NULL);
5363 if (tif->tif_map_dir_number_to_offset == NULL)
5364 {
5365 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5366 "Not enough memory");
5367 return 1;
5368 }
5369 }
5370
5371 /* Check if offset is already in the list:
5372 * - yes: check, if offset is at the same IFD number - if not, it is an IFD
5373 * loop
5374 * - no: add to list or update offset at that IFD number
5375 */
5376 TIFFOffsetAndDirNumber entry;
5377 entry.offset = diroff;
5378 entry.dirNumber = dirn;
5379
5380 TIFFOffsetAndDirNumber *foundEntry =
5381 (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5382 tif->tif_map_dir_offset_to_number, &entry);
5383 if (foundEntry)
5384 {
5385 if (foundEntry->dirNumber == dirn)
5386 {
5387 return 1;
5388 }
5389 else
5390 {
5391 TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset",
5392 "TIFF directory %d has IFD looping to directory %u "
5393 "at offset 0x%" PRIx64 " (%" PRIu64 ")",
5394 (int)dirn - 1, foundEntry->dirNumber, diroff,
5395 diroff);
5396 return 0;
5397 }
5398 }
5399
5400 /* Check if offset of an IFD has been changed and update offset of that IFD
5401 * number. */
5402 foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5403 tif->tif_map_dir_number_to_offset, &entry);
5404 if (foundEntry)
5405 {
5406 if (foundEntry->offset != diroff)
5407 {
5408 TIFFOffsetAndDirNumber entryOld;
5409 entryOld.offset = foundEntry->offset;
5410 entryOld.dirNumber = dirn;
5411 /* We must remove first from tif_map_dir_number_to_offset as the */
5412 /* entry is owned (and thus freed) by */
5413 /* tif_map_dir_offset_to_number */
5414 TIFFOffsetAndDirNumber *foundEntryOld =
5415 (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5416 tif->tif_map_dir_number_to_offset, &entryOld);
5417 if (foundEntryOld)
5418 {
5419 TIFFHashSetRemove(tif->tif_map_dir_number_to_offset,
5420 foundEntryOld);
5421 }
5422 foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5423 tif->tif_map_dir_offset_to_number, &entryOld);
5424 if (foundEntryOld)
5425 {
5426 TIFFHashSetRemove(tif->tif_map_dir_offset_to_number,
5427 foundEntryOld);
5428 }
5429
5430 TIFFOffsetAndDirNumber *entryPtr = (TIFFOffsetAndDirNumber *)malloc(
5431 sizeof(TIFFOffsetAndDirNumber));
5432 if (entryPtr == NULL)
5433 {
5434 return 0;
5435 }
5436
5437 /* Add IFD offset and dirn to IFD directory list */
5438 *entryPtr = entry;
5439
5440 if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
5441 {
5442 TIFFErrorExtR(
5443 tif, "_TIFFCheckDirNumberAndOffset",
5444 "Insertion in tif_map_dir_offset_to_number failed");
5445 return 0;
5446 }
5447 if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
5448 {
5449 TIFFErrorExtR(
5450 tif, "_TIFFCheckDirNumberAndOffset",
5451 "Insertion in tif_map_dir_number_to_offset failed");
5452 return 0;
5453 }
5454 }
5455 return 1;
5456 }
5457
5458 /* Arbitrary (hopefully big enough) limit */
5459 if (tif->tif_dirnumber >= TIFF_MAX_DIR_COUNT)
5460 {
5461 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5462 "Cannot handle more than %u TIFF directories",
5463 TIFF_MAX_DIR_COUNT);
5464 return 0;
5465 }
5466
5467 TIFFOffsetAndDirNumber *entryPtr =
5468 (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber));
5469 if (entryPtr == NULL)
5470 {
5471 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5472 "malloc(sizeof(TIFFOffsetAndDirNumber)) failed");
5473 return 0;
5474 }
5475
5476 /* Add IFD offset and dirn to IFD directory list */
5477 *entryPtr = entry;
5478
5479 if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr))
5480 {
5481 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5482 "Insertion in tif_map_dir_offset_to_number failed");
5483 return 0;
5484 }
5485 if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr))
5486 {
5487 TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset",
5488 "Insertion in tif_map_dir_number_to_offset failed");
5489 return 0;
5490 }
5491
5492 tif->tif_dirnumber++;
5493
5494 return 1;
5495} /* --- _TIFFCheckDirNumberAndOffset() ---*/
5496
5497/*
5498 * Retrieve the matching IFD directory number of a given IFD offset
5499 * from the list of directories already seen.
5500 * Returns 1 if the offset was in the list and the directory number
5501 * can be returned.
5502 * Otherwise returns 0 or if an error occurred.
5503 */
5504int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, tdir_t *dirn)
5505{
5506 if (diroff == 0) /* no more directories */
5507 return 0;
5508 if (tif->tif_dirnumber >= TIFF_MAX_DIR_COUNT)
5509 {
5510 TIFFErrorExtR(tif, "_TIFFGetDirNumberFromOffset",
5511 "Cannot handle more than %u TIFF directories",
5512 TIFF_MAX_DIR_COUNT);
5513 return 0;
5514 }
5515
5516 /* Check if offset is already in the list and return matching directory
5517 * number. Otherwise update IFD list using TIFFNumberOfDirectories() and
5518 * search again in IFD list.
5519 */
5520 if (tif->tif_map_dir_offset_to_number == NULL)
5521 return 0;
5522 TIFFOffsetAndDirNumber entry;
5523 entry.offset = diroff;
5524 entry.dirNumber = 0; /* not used */
5525
5526 TIFFOffsetAndDirNumber *foundEntry =
5527 (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5528 tif->tif_map_dir_offset_to_number, &entry);
5529 if (foundEntry)
5530 {
5531 *dirn = foundEntry->dirNumber;
5532 return 1;
5533 }
5534
5535 TIFFNumberOfDirectories(tif);
5536
5537 foundEntry = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup(
5538 tif->tif_map_dir_offset_to_number, &entry);
5539 if (foundEntry)
5540 {
5541 *dirn = foundEntry->dirNumber;
5542 return 1;
5543 }
5544
5545 return 0;
5546} /*--- _TIFFGetDirNumberFromOffset() ---*/
5547
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005548/*
5549 * Check the count field of a directory entry against a known value. The
5550 * caller is expected to skip/ignore the tag if there is a mismatch.
5551 */
kumarashishg826308d2023-06-23 13:21:22 +00005552static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005553{
kumarashishg826308d2023-06-23 13:21:22 +00005554 if ((uint64_t)count > dir->tdir_count)
5555 {
5556 const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
5557 TIFFWarningExtR(tif, tif->tif_name,
5558 "incorrect count for field \"%s\" (%" PRIu64
5559 ", expecting %" PRIu32 "); tag ignored",
5560 fip ? fip->field_name : "unknown tagname",
5561 dir->tdir_count, count);
5562 return (0);
5563 }
5564 else if ((uint64_t)count < dir->tdir_count)
5565 {
5566 const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
5567 TIFFWarningExtR(tif, tif->tif_name,
5568 "incorrect count for field \"%s\" (%" PRIu64
5569 ", expecting %" PRIu32 "); tag trimmed",
5570 fip ? fip->field_name : "unknown tagname",
5571 dir->tdir_count, count);
5572 dir->tdir_count = count;
5573 return (1);
5574 }
5575 return (1);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005576}
5577
5578/*
5579 * Read IFD structure from the specified offset. If the pointer to
5580 * nextdiroff variable has been specified, read it too. Function returns a
5581 * number of fields in the directory or 0 if failed.
5582 */
kumarashishg826308d2023-06-23 13:21:22 +00005583static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
5584 TIFFDirEntry **pdir, uint64_t *nextdiroff)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005585{
kumarashishg826308d2023-06-23 13:21:22 +00005586 static const char module[] = "TIFFFetchDirectory";
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005587
kumarashishg826308d2023-06-23 13:21:22 +00005588 void *origdir;
5589 uint16_t dircount16;
5590 uint32_t dirsize;
5591 TIFFDirEntry *dir;
5592 uint8_t *ma;
5593 TIFFDirEntry *mb;
5594 uint16_t n;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005595
kumarashishg826308d2023-06-23 13:21:22 +00005596 assert(pdir);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005597
kumarashishg826308d2023-06-23 13:21:22 +00005598 tif->tif_diroff = diroff;
5599 if (nextdiroff)
5600 *nextdiroff = 0;
5601 if (!isMapped(tif))
5602 {
5603 if (!SeekOK(tif, tif->tif_diroff))
5604 {
5605 TIFFErrorExtR(tif, module,
5606 "%s: Seek error accessing TIFF directory",
5607 tif->tif_name);
5608 return 0;
5609 }
5610 if (!(tif->tif_flags & TIFF_BIGTIFF))
5611 {
5612 if (!ReadOK(tif, &dircount16, sizeof(uint16_t)))
5613 {
5614 TIFFErrorExtR(tif, module,
5615 "%s: Can not read TIFF directory count",
5616 tif->tif_name);
5617 return 0;
5618 }
5619 if (tif->tif_flags & TIFF_SWAB)
5620 TIFFSwabShort(&dircount16);
5621 if (dircount16 > 4096)
5622 {
5623 TIFFErrorExtR(tif, module,
5624 "Sanity check on directory count failed, this is "
5625 "probably not a valid IFD offset");
5626 return 0;
5627 }
5628 dirsize = 12;
5629 }
5630 else
5631 {
5632 uint64_t dircount64;
5633 if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
5634 {
5635 TIFFErrorExtR(tif, module,
5636 "%s: Can not read TIFF directory count",
5637 tif->tif_name);
5638 return 0;
5639 }
5640 if (tif->tif_flags & TIFF_SWAB)
5641 TIFFSwabLong8(&dircount64);
5642 if (dircount64 > 4096)
5643 {
5644 TIFFErrorExtR(tif, module,
5645 "Sanity check on directory count failed, this is "
5646 "probably not a valid IFD offset");
5647 return 0;
5648 }
5649 dircount16 = (uint16_t)dircount64;
5650 dirsize = 20;
5651 }
5652 origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
5653 "to read TIFF directory");
5654 if (origdir == NULL)
5655 return 0;
5656 if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize)))
5657 {
5658 TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory",
5659 tif->tif_name);
5660 _TIFFfreeExt(tif, origdir);
5661 return 0;
5662 }
5663 /*
5664 * Read offset to next directory for sequential scans if
5665 * needed.
5666 */
5667 if (nextdiroff)
5668 {
5669 if (!(tif->tif_flags & TIFF_BIGTIFF))
5670 {
5671 uint32_t nextdiroff32;
5672 if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t)))
5673 nextdiroff32 = 0;
5674 if (tif->tif_flags & TIFF_SWAB)
5675 TIFFSwabLong(&nextdiroff32);
5676 *nextdiroff = nextdiroff32;
5677 }
5678 else
5679 {
5680 if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
5681 *nextdiroff = 0;
5682 if (tif->tif_flags & TIFF_SWAB)
5683 TIFFSwabLong8(nextdiroff);
5684 }
5685 }
5686 }
5687 else
5688 {
5689 tmsize_t m;
5690 tmsize_t off;
5691 if (tif->tif_diroff > (uint64_t)INT64_MAX)
5692 {
5693 TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5694 return (0);
5695 }
5696 off = (tmsize_t)tif->tif_diroff;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005697
kumarashishg826308d2023-06-23 13:21:22 +00005698 /*
5699 * Check for integer overflow when validating the dir_off,
5700 * otherwise a very high offset may cause an OOB read and
5701 * crash the client. Make two comparisons instead of
5702 *
5703 * off + sizeof(uint16_t) > tif->tif_size
5704 *
5705 * to avoid overflow.
5706 */
5707 if (!(tif->tif_flags & TIFF_BIGTIFF))
5708 {
5709 m = off + sizeof(uint16_t);
5710 if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) ||
5711 (m > tif->tif_size))
5712 {
5713 TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5714 return 0;
5715 }
5716 else
5717 {
5718 _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t));
5719 }
5720 off += sizeof(uint16_t);
5721 if (tif->tif_flags & TIFF_SWAB)
5722 TIFFSwabShort(&dircount16);
5723 if (dircount16 > 4096)
5724 {
5725 TIFFErrorExtR(tif, module,
5726 "Sanity check on directory count failed, this is "
5727 "probably not a valid IFD offset");
5728 return 0;
5729 }
5730 dirsize = 12;
5731 }
5732 else
5733 {
5734 uint64_t dircount64;
5735 m = off + sizeof(uint64_t);
5736 if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
5737 (m > tif->tif_size))
5738 {
5739 TIFFErrorExtR(tif, module, "Can not read TIFF directory count");
5740 return 0;
5741 }
5742 else
5743 {
5744 _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t));
5745 }
5746 off += sizeof(uint64_t);
5747 if (tif->tif_flags & TIFF_SWAB)
5748 TIFFSwabLong8(&dircount64);
5749 if (dircount64 > 4096)
5750 {
5751 TIFFErrorExtR(tif, module,
5752 "Sanity check on directory count failed, this is "
5753 "probably not a valid IFD offset");
5754 return 0;
5755 }
5756 dircount16 = (uint16_t)dircount64;
5757 dirsize = 20;
5758 }
5759 if (dircount16 == 0)
5760 {
5761 TIFFErrorExtR(tif, module,
5762 "Sanity check on directory count failed, zero tag "
5763 "directories not supported");
5764 return 0;
5765 }
5766 origdir = _TIFFCheckMalloc(tif, dircount16, dirsize,
5767 "to read TIFF directory");
5768 if (origdir == NULL)
5769 return 0;
5770 m = off + dircount16 * dirsize;
5771 if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) ||
5772 (m > tif->tif_size))
5773 {
5774 TIFFErrorExtR(tif, module, "Can not read TIFF directory");
5775 _TIFFfreeExt(tif, origdir);
5776 return 0;
5777 }
5778 else
5779 {
5780 _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize);
5781 }
5782 if (nextdiroff)
5783 {
5784 off += dircount16 * dirsize;
5785 if (!(tif->tif_flags & TIFF_BIGTIFF))
5786 {
5787 uint32_t nextdiroff32;
5788 m = off + sizeof(uint32_t);
5789 if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) ||
5790 (m > tif->tif_size))
5791 nextdiroff32 = 0;
5792 else
5793 _TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
5794 sizeof(uint32_t));
5795 if (tif->tif_flags & TIFF_SWAB)
5796 TIFFSwabLong(&nextdiroff32);
5797 *nextdiroff = nextdiroff32;
5798 }
5799 else
5800 {
5801 m = off + sizeof(uint64_t);
5802 if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) ||
5803 (m > tif->tif_size))
5804 *nextdiroff = 0;
5805 else
5806 _TIFFmemcpy(nextdiroff, tif->tif_base + off,
5807 sizeof(uint64_t));
5808 if (tif->tif_flags & TIFF_SWAB)
5809 TIFFSwabLong8(nextdiroff);
5810 }
5811 }
5812 }
5813 dir = (TIFFDirEntry *)_TIFFCheckMalloc(
5814 tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory");
5815 if (dir == 0)
5816 {
5817 _TIFFfreeExt(tif, origdir);
5818 return 0;
5819 }
5820 ma = (uint8_t *)origdir;
5821 mb = dir;
5822 for (n = 0; n < dircount16; n++)
5823 {
5824 mb->tdir_ignore = FALSE;
5825 if (tif->tif_flags & TIFF_SWAB)
5826 TIFFSwabShort((uint16_t *)ma);
5827 mb->tdir_tag = *(uint16_t *)ma;
5828 ma += sizeof(uint16_t);
5829 if (tif->tif_flags & TIFF_SWAB)
5830 TIFFSwabShort((uint16_t *)ma);
5831 mb->tdir_type = *(uint16_t *)ma;
5832 ma += sizeof(uint16_t);
5833 if (!(tif->tif_flags & TIFF_BIGTIFF))
5834 {
5835 if (tif->tif_flags & TIFF_SWAB)
5836 TIFFSwabLong((uint32_t *)ma);
5837 mb->tdir_count = (uint64_t)(*(uint32_t *)ma);
5838 ma += sizeof(uint32_t);
5839 mb->tdir_offset.toff_long8 = 0;
5840 *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma;
5841 ma += sizeof(uint32_t);
5842 }
5843 else
5844 {
5845 if (tif->tif_flags & TIFF_SWAB)
5846 TIFFSwabLong8((uint64_t *)ma);
5847 mb->tdir_count = TIFFReadUInt64(ma);
5848 ma += sizeof(uint64_t);
5849 mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma);
5850 ma += sizeof(uint64_t);
5851 }
5852 mb++;
5853 }
5854 _TIFFfreeExt(tif, origdir);
5855 *pdir = dir;
5856 return dircount16;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005857}
5858
5859/*
5860 * Fetch a tag that is not handled by special case code.
5861 */
kumarashishg826308d2023-06-23 13:21:22 +00005862static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005863{
kumarashishg826308d2023-06-23 13:21:22 +00005864 static const char module[] = "TIFFFetchNormalTag";
5865 enum TIFFReadDirEntryErr err;
5866 uint32_t fii;
5867 const TIFFField *fip = NULL;
5868 TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
5869 if (fii == FAILED_FII)
5870 {
5871 TIFFErrorExtR(tif, "TIFFFetchNormalTag",
5872 "No definition found for tag %" PRIu16, dp->tdir_tag);
5873 return 0;
5874 }
5875 fip = tif->tif_fields[fii];
5876 assert(fip != NULL); /* should not happen */
5877 assert(fip->set_field_type !=
5878 TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with
5879 this in specialized code */
5880 assert(fip->set_field_type !=
5881 TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only
5882 the case for pseudo-tags */
5883 err = TIFFReadDirEntryErrOk;
5884 switch (fip->set_field_type)
5885 {
5886 case TIFF_SETGET_UNDEFINED:
5887 TIFFErrorExtR(
5888 tif, "TIFFFetchNormalTag",
5889 "Defined set_field_type of custom tag %u (%s) is "
5890 "TIFF_SETGET_UNDEFINED and thus tag is not read from file",
5891 fip->field_tag, fip->field_name);
5892 break;
5893 case TIFF_SETGET_ASCII:
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005894 {
kumarashishg826308d2023-06-23 13:21:22 +00005895 uint8_t *data;
5896 assert(fip->field_passcount == 0);
5897 err = TIFFReadDirEntryByteArray(tif, dp, &data);
5898 if (err == TIFFReadDirEntryErrOk)
5899 {
5900 size_t mb = 0;
5901 int n;
5902 if (data != NULL)
5903 {
5904 if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0)
5905 {
5906 /* optimization: if data is known to be 0 terminated, we
5907 * can use strlen() */
5908 mb = strlen((const char *)data);
5909 }
5910 else
5911 {
5912 /* general case. equivalent to non-portable */
5913 /* mb = strnlen((const char*)data,
5914 * (uint32_t)dp->tdir_count); */
5915 uint8_t *ma = data;
5916 while (mb < (uint32_t)dp->tdir_count)
5917 {
5918 if (*ma == 0)
5919 break;
5920 ma++;
5921 mb++;
5922 }
5923 }
5924 }
5925 if (mb + 1 < (uint32_t)dp->tdir_count)
5926 TIFFWarningExtR(
5927 tif, module,
5928 "ASCII value for tag \"%s\" contains null byte in "
5929 "value; value incorrectly truncated during reading due "
5930 "to implementation limitations",
5931 fip->field_name);
5932 else if (mb + 1 > (uint32_t)dp->tdir_count)
5933 {
5934 uint8_t *o;
5935 TIFFWarningExtR(
5936 tif, module,
5937 "ASCII value for tag \"%s\" does not end in null byte",
5938 fip->field_name);
5939 /* TIFFReadDirEntryArrayWithLimit() ensures this can't be
5940 * larger than MAX_SIZE_TAG_DATA */
5941 assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1);
5942 o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1);
5943 if (o == NULL)
5944 {
5945 if (data != NULL)
5946 _TIFFfreeExt(tif, data);
5947 return (0);
5948 }
5949 if (dp->tdir_count > 0)
5950 {
5951 _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count);
5952 }
5953 o[(uint32_t)dp->tdir_count] = 0;
5954 if (data != 0)
5955 _TIFFfreeExt(tif, data);
5956 data = o;
5957 }
5958 n = TIFFSetField(tif, dp->tdir_tag, data);
5959 if (data != 0)
5960 _TIFFfreeExt(tif, data);
5961 if (!n)
5962 return (0);
5963 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08005964 }
kumarashishg826308d2023-06-23 13:21:22 +00005965 break;
5966 case TIFF_SETGET_UINT8:
5967 {
5968 uint8_t data = 0;
5969 assert(fip->field_readcount == 1);
5970 assert(fip->field_passcount == 0);
5971 err = TIFFReadDirEntryByte(tif, dp, &data);
5972 if (err == TIFFReadDirEntryErrOk)
5973 {
5974 if (!TIFFSetField(tif, dp->tdir_tag, data))
5975 return (0);
5976 }
5977 }
5978 break;
5979 case TIFF_SETGET_SINT8:
5980 {
5981 int8_t data = 0;
5982 assert(fip->field_readcount == 1);
5983 assert(fip->field_passcount == 0);
5984 err = TIFFReadDirEntrySbyte(tif, dp, &data);
5985 if (err == TIFFReadDirEntryErrOk)
5986 {
5987 if (!TIFFSetField(tif, dp->tdir_tag, data))
5988 return (0);
5989 }
5990 }
5991 break;
5992 case TIFF_SETGET_UINT16:
5993 {
5994 uint16_t data;
5995 assert(fip->field_readcount == 1);
5996 assert(fip->field_passcount == 0);
5997 err = TIFFReadDirEntryShort(tif, dp, &data);
5998 if (err == TIFFReadDirEntryErrOk)
5999 {
6000 if (!TIFFSetField(tif, dp->tdir_tag, data))
6001 return (0);
6002 }
6003 }
6004 break;
6005 case TIFF_SETGET_SINT16:
6006 {
6007 int16_t data;
6008 assert(fip->field_readcount == 1);
6009 assert(fip->field_passcount == 0);
6010 err = TIFFReadDirEntrySshort(tif, dp, &data);
6011 if (err == TIFFReadDirEntryErrOk)
6012 {
6013 if (!TIFFSetField(tif, dp->tdir_tag, data))
6014 return (0);
6015 }
6016 }
6017 break;
6018 case TIFF_SETGET_UINT32:
6019 {
6020 uint32_t data;
6021 assert(fip->field_readcount == 1);
6022 assert(fip->field_passcount == 0);
6023 err = TIFFReadDirEntryLong(tif, dp, &data);
6024 if (err == TIFFReadDirEntryErrOk)
6025 {
6026 if (!TIFFSetField(tif, dp->tdir_tag, data))
6027 return (0);
6028 }
6029 }
6030 break;
6031 case TIFF_SETGET_SINT32:
6032 {
6033 int32_t data;
6034 assert(fip->field_readcount == 1);
6035 assert(fip->field_passcount == 0);
6036 err = TIFFReadDirEntrySlong(tif, dp, &data);
6037 if (err == TIFFReadDirEntryErrOk)
6038 {
6039 if (!TIFFSetField(tif, dp->tdir_tag, data))
6040 return (0);
6041 }
6042 }
6043 break;
6044 case TIFF_SETGET_UINT64:
6045 {
6046 uint64_t data;
6047 assert(fip->field_readcount == 1);
6048 assert(fip->field_passcount == 0);
6049 err = TIFFReadDirEntryLong8(tif, dp, &data);
6050 if (err == TIFFReadDirEntryErrOk)
6051 {
6052 if (!TIFFSetField(tif, dp->tdir_tag, data))
6053 return (0);
6054 }
6055 }
6056 break;
6057 case TIFF_SETGET_SINT64:
6058 {
6059 int64_t data;
6060 assert(fip->field_readcount == 1);
6061 assert(fip->field_passcount == 0);
6062 err = TIFFReadDirEntrySlong8(tif, dp, &data);
6063 if (err == TIFFReadDirEntryErrOk)
6064 {
6065 if (!TIFFSetField(tif, dp->tdir_tag, data))
6066 return (0);
6067 }
6068 }
6069 break;
6070 case TIFF_SETGET_FLOAT:
6071 {
6072 float data;
6073 assert(fip->field_readcount == 1);
6074 assert(fip->field_passcount == 0);
6075 err = TIFFReadDirEntryFloat(tif, dp, &data);
6076 if (err == TIFFReadDirEntryErrOk)
6077 {
6078 if (!TIFFSetField(tif, dp->tdir_tag, data))
6079 return (0);
6080 }
6081 }
6082 break;
6083 case TIFF_SETGET_DOUBLE:
6084 {
6085 double data;
6086 assert(fip->field_readcount == 1);
6087 assert(fip->field_passcount == 0);
6088 err = TIFFReadDirEntryDouble(tif, dp, &data);
6089 if (err == TIFFReadDirEntryErrOk)
6090 {
6091 if (!TIFFSetField(tif, dp->tdir_tag, data))
6092 return (0);
6093 }
6094 }
6095 break;
6096 case TIFF_SETGET_IFD8:
6097 {
6098 uint64_t data;
6099 assert(fip->field_readcount == 1);
6100 assert(fip->field_passcount == 0);
6101 err = TIFFReadDirEntryIfd8(tif, dp, &data);
6102 if (err == TIFFReadDirEntryErrOk)
6103 {
6104 if (!TIFFSetField(tif, dp->tdir_tag, data))
6105 return (0);
6106 }
6107 }
6108 break;
6109 case TIFF_SETGET_UINT16_PAIR:
6110 {
6111 uint16_t *data;
6112 assert(fip->field_readcount == 2);
6113 assert(fip->field_passcount == 0);
6114 if (dp->tdir_count != 2)
6115 {
6116 TIFFWarningExtR(tif, module,
6117 "incorrect count for field \"%s\", expected 2, "
6118 "got %" PRIu64,
6119 fip->field_name, dp->tdir_count);
6120 return (0);
6121 }
6122 err = TIFFReadDirEntryShortArray(tif, dp, &data);
6123 if (err == TIFFReadDirEntryErrOk)
6124 {
6125 int m;
6126 assert(data); /* avoid CLang static Analyzer false positive */
6127 m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]);
6128 _TIFFfreeExt(tif, data);
6129 if (!m)
6130 return (0);
6131 }
6132 }
6133 break;
6134 case TIFF_SETGET_C0_UINT8:
6135 {
6136 uint8_t *data;
6137 assert(fip->field_readcount >= 1);
6138 assert(fip->field_passcount == 0);
6139 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6140 {
6141 TIFFWarningExtR(tif, module,
6142 "incorrect count for field \"%s\", expected "
6143 "%d, got %" PRIu64,
6144 fip->field_name, (int)fip->field_readcount,
6145 dp->tdir_count);
6146 return (0);
6147 }
6148 else
6149 {
6150 err = TIFFReadDirEntryByteArray(tif, dp, &data);
6151 if (err == TIFFReadDirEntryErrOk)
6152 {
6153 int m;
6154 m = TIFFSetField(tif, dp->tdir_tag, data);
6155 if (data != 0)
6156 _TIFFfreeExt(tif, data);
6157 if (!m)
6158 return (0);
6159 }
6160 }
6161 }
6162 break;
6163 case TIFF_SETGET_C0_SINT8:
6164 {
6165 int8_t *data;
6166 assert(fip->field_readcount >= 1);
6167 assert(fip->field_passcount == 0);
6168 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6169 {
6170 TIFFWarningExtR(tif, module,
6171 "incorrect count for field \"%s\", expected "
6172 "%d, got %" PRIu64,
6173 fip->field_name, (int)fip->field_readcount,
6174 dp->tdir_count);
6175 return (0);
6176 }
6177 else
6178 {
6179 err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6180 if (err == TIFFReadDirEntryErrOk)
6181 {
6182 int m;
6183 m = TIFFSetField(tif, dp->tdir_tag, data);
6184 if (data != 0)
6185 _TIFFfreeExt(tif, data);
6186 if (!m)
6187 return (0);
6188 }
6189 }
6190 }
6191 break;
6192 case TIFF_SETGET_C0_UINT16:
6193 {
6194 uint16_t *data;
6195 assert(fip->field_readcount >= 1);
6196 assert(fip->field_passcount == 0);
6197 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6198 {
6199 TIFFWarningExtR(tif, module,
6200 "incorrect count for field \"%s\", expected "
6201 "%d, got %" PRIu64,
6202 fip->field_name, (int)fip->field_readcount,
6203 dp->tdir_count);
6204 return (0);
6205 }
6206 else
6207 {
6208 err = TIFFReadDirEntryShortArray(tif, dp, &data);
6209 if (err == TIFFReadDirEntryErrOk)
6210 {
6211 int m;
6212 m = TIFFSetField(tif, dp->tdir_tag, data);
6213 if (data != 0)
6214 _TIFFfreeExt(tif, data);
6215 if (!m)
6216 return (0);
6217 }
6218 }
6219 }
6220 break;
6221 case TIFF_SETGET_C0_SINT16:
6222 {
6223 int16_t *data;
6224 assert(fip->field_readcount >= 1);
6225 assert(fip->field_passcount == 0);
6226 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6227 {
6228 TIFFWarningExtR(tif, module,
6229 "incorrect count for field \"%s\", expected "
6230 "%d, got %" PRIu64,
6231 fip->field_name, (int)fip->field_readcount,
6232 dp->tdir_count);
6233 return (0);
6234 }
6235 else
6236 {
6237 err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6238 if (err == TIFFReadDirEntryErrOk)
6239 {
6240 int m;
6241 m = TIFFSetField(tif, dp->tdir_tag, data);
6242 if (data != 0)
6243 _TIFFfreeExt(tif, data);
6244 if (!m)
6245 return (0);
6246 }
6247 }
6248 }
6249 break;
6250 case TIFF_SETGET_C0_UINT32:
6251 {
6252 uint32_t *data;
6253 assert(fip->field_readcount >= 1);
6254 assert(fip->field_passcount == 0);
6255 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6256 {
6257 TIFFWarningExtR(tif, module,
6258 "incorrect count for field \"%s\", expected "
6259 "%d, got %" PRIu64,
6260 fip->field_name, (int)fip->field_readcount,
6261 dp->tdir_count);
6262 return (0);
6263 }
6264 else
6265 {
6266 err = TIFFReadDirEntryLongArray(tif, dp, &data);
6267 if (err == TIFFReadDirEntryErrOk)
6268 {
6269 int m;
6270 m = TIFFSetField(tif, dp->tdir_tag, data);
6271 if (data != 0)
6272 _TIFFfreeExt(tif, data);
6273 if (!m)
6274 return (0);
6275 }
6276 }
6277 }
6278 break;
6279 case TIFF_SETGET_C0_SINT32:
6280 {
6281 int32_t *data;
6282 assert(fip->field_readcount >= 1);
6283 assert(fip->field_passcount == 0);
6284 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6285 {
6286 TIFFWarningExtR(tif, module,
6287 "incorrect count for field \"%s\", expected "
6288 "%d, got %" PRIu64,
6289 fip->field_name, (int)fip->field_readcount,
6290 dp->tdir_count);
6291 return (0);
6292 }
6293 else
6294 {
6295 err = TIFFReadDirEntrySlongArray(tif, dp, &data);
6296 if (err == TIFFReadDirEntryErrOk)
6297 {
6298 int m;
6299 m = TIFFSetField(tif, dp->tdir_tag, data);
6300 if (data != 0)
6301 _TIFFfreeExt(tif, data);
6302 if (!m)
6303 return (0);
6304 }
6305 }
6306 }
6307 break;
6308 case TIFF_SETGET_C0_UINT64:
6309 {
6310 uint64_t *data;
6311 assert(fip->field_readcount >= 1);
6312 assert(fip->field_passcount == 0);
6313 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6314 {
6315 TIFFWarningExtR(tif, module,
6316 "incorrect count for field \"%s\", expected "
6317 "%d, got %" PRIu64,
6318 fip->field_name, (int)fip->field_readcount,
6319 dp->tdir_count);
6320 return (0);
6321 }
6322 else
6323 {
6324 err = TIFFReadDirEntryLong8Array(tif, dp, &data);
6325 if (err == TIFFReadDirEntryErrOk)
6326 {
6327 int m;
6328 m = TIFFSetField(tif, dp->tdir_tag, data);
6329 if (data != 0)
6330 _TIFFfreeExt(tif, data);
6331 if (!m)
6332 return (0);
6333 }
6334 }
6335 }
6336 break;
6337 case TIFF_SETGET_C0_SINT64:
6338 {
6339 int64_t *data;
6340 assert(fip->field_readcount >= 1);
6341 assert(fip->field_passcount == 0);
6342 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6343 {
6344 TIFFWarningExtR(tif, module,
6345 "incorrect count for field \"%s\", expected "
6346 "%d, got %" PRIu64,
6347 fip->field_name, (int)fip->field_readcount,
6348 dp->tdir_count);
6349 return (0);
6350 }
6351 else
6352 {
6353 err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
6354 if (err == TIFFReadDirEntryErrOk)
6355 {
6356 int m;
6357 m = TIFFSetField(tif, dp->tdir_tag, data);
6358 if (data != 0)
6359 _TIFFfreeExt(tif, data);
6360 if (!m)
6361 return (0);
6362 }
6363 }
6364 }
6365 break;
6366 case TIFF_SETGET_C0_FLOAT:
6367 {
6368 float *data;
6369 assert(fip->field_readcount >= 1);
6370 assert(fip->field_passcount == 0);
6371 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6372 {
6373 TIFFWarningExtR(tif, module,
6374 "incorrect count for field \"%s\", expected "
6375 "%d, got %" PRIu64,
6376 fip->field_name, (int)fip->field_readcount,
6377 dp->tdir_count);
6378 return (0);
6379 }
6380 else
6381 {
6382 err = TIFFReadDirEntryFloatArray(tif, dp, &data);
6383 if (err == TIFFReadDirEntryErrOk)
6384 {
6385 int m;
6386 m = TIFFSetField(tif, dp->tdir_tag, data);
6387 if (data != 0)
6388 _TIFFfreeExt(tif, data);
6389 if (!m)
6390 return (0);
6391 }
6392 }
6393 }
6394 break;
6395 /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read
6396 * into Double-Arrays. */
6397 case TIFF_SETGET_C0_DOUBLE:
6398 {
6399 double *data;
6400 assert(fip->field_readcount >= 1);
6401 assert(fip->field_passcount == 0);
6402 if (dp->tdir_count != (uint64_t)fip->field_readcount)
6403 {
6404 TIFFWarningExtR(tif, module,
6405 "incorrect count for field \"%s\", expected "
6406 "%d, got %" PRIu64,
6407 fip->field_name, (int)fip->field_readcount,
6408 dp->tdir_count);
6409 return (0);
6410 }
6411 else
6412 {
6413 err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
6414 if (err == TIFFReadDirEntryErrOk)
6415 {
6416 int m;
6417 m = TIFFSetField(tif, dp->tdir_tag, data);
6418 if (data != 0)
6419 _TIFFfreeExt(tif, data);
6420 if (!m)
6421 return (0);
6422 }
6423 }
6424 }
6425 break;
6426 case TIFF_SETGET_C16_ASCII:
6427 {
6428 uint8_t *data;
6429 assert(fip->field_readcount == TIFF_VARIABLE);
6430 assert(fip->field_passcount == 1);
6431 if (dp->tdir_count > 0xFFFF)
6432 err = TIFFReadDirEntryErrCount;
6433 else
6434 {
6435 err = TIFFReadDirEntryByteArray(tif, dp, &data);
6436 if (err == TIFFReadDirEntryErrOk)
6437 {
6438 int m;
6439 if (data != 0 && dp->tdir_count > 0 &&
6440 data[dp->tdir_count - 1] != '\0')
6441 {
6442 TIFFWarningExtR(
6443 tif, module,
6444 "ASCII value for tag \"%s\" does not end in null "
6445 "byte. Forcing it to be null",
6446 fip->field_name);
6447 data[dp->tdir_count - 1] = '\0';
6448 }
6449 m = TIFFSetField(tif, dp->tdir_tag,
6450 (uint16_t)(dp->tdir_count), data);
6451 if (data != 0)
6452 _TIFFfreeExt(tif, data);
6453 if (!m)
6454 return (0);
6455 }
6456 }
6457 }
6458 break;
6459 case TIFF_SETGET_C16_UINT8:
6460 {
6461 uint8_t *data;
6462 assert(fip->field_readcount == TIFF_VARIABLE);
6463 assert(fip->field_passcount == 1);
6464 if (dp->tdir_count > 0xFFFF)
6465 err = TIFFReadDirEntryErrCount;
6466 else
6467 {
6468 err = TIFFReadDirEntryByteArray(tif, dp, &data);
6469 if (err == TIFFReadDirEntryErrOk)
6470 {
6471 int m;
6472 m = TIFFSetField(tif, dp->tdir_tag,
6473 (uint16_t)(dp->tdir_count), data);
6474 if (data != 0)
6475 _TIFFfreeExt(tif, data);
6476 if (!m)
6477 return (0);
6478 }
6479 }
6480 }
6481 break;
6482 case TIFF_SETGET_C16_SINT8:
6483 {
6484 int8_t *data;
6485 assert(fip->field_readcount == TIFF_VARIABLE);
6486 assert(fip->field_passcount == 1);
6487 if (dp->tdir_count > 0xFFFF)
6488 err = TIFFReadDirEntryErrCount;
6489 else
6490 {
6491 err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6492 if (err == TIFFReadDirEntryErrOk)
6493 {
6494 int m;
6495 m = TIFFSetField(tif, dp->tdir_tag,
6496 (uint16_t)(dp->tdir_count), data);
6497 if (data != 0)
6498 _TIFFfreeExt(tif, data);
6499 if (!m)
6500 return (0);
6501 }
6502 }
6503 }
6504 break;
6505 case TIFF_SETGET_C16_UINT16:
6506 {
6507 uint16_t *data;
6508 assert(fip->field_readcount == TIFF_VARIABLE);
6509 assert(fip->field_passcount == 1);
6510 if (dp->tdir_count > 0xFFFF)
6511 err = TIFFReadDirEntryErrCount;
6512 else
6513 {
6514 err = TIFFReadDirEntryShortArray(tif, dp, &data);
6515 if (err == TIFFReadDirEntryErrOk)
6516 {
6517 int m;
6518 m = TIFFSetField(tif, dp->tdir_tag,
6519 (uint16_t)(dp->tdir_count), data);
6520 if (data != 0)
6521 _TIFFfreeExt(tif, data);
6522 if (!m)
6523 return (0);
6524 }
6525 }
6526 }
6527 break;
6528 case TIFF_SETGET_C16_SINT16:
6529 {
6530 int16_t *data;
6531 assert(fip->field_readcount == TIFF_VARIABLE);
6532 assert(fip->field_passcount == 1);
6533 if (dp->tdir_count > 0xFFFF)
6534 err = TIFFReadDirEntryErrCount;
6535 else
6536 {
6537 err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6538 if (err == TIFFReadDirEntryErrOk)
6539 {
6540 int m;
6541 m = TIFFSetField(tif, dp->tdir_tag,
6542 (uint16_t)(dp->tdir_count), data);
6543 if (data != 0)
6544 _TIFFfreeExt(tif, data);
6545 if (!m)
6546 return (0);
6547 }
6548 }
6549 }
6550 break;
6551 case TIFF_SETGET_C16_UINT32:
6552 {
6553 uint32_t *data;
6554 assert(fip->field_readcount == TIFF_VARIABLE);
6555 assert(fip->field_passcount == 1);
6556 if (dp->tdir_count > 0xFFFF)
6557 err = TIFFReadDirEntryErrCount;
6558 else
6559 {
6560 err = TIFFReadDirEntryLongArray(tif, dp, &data);
6561 if (err == TIFFReadDirEntryErrOk)
6562 {
6563 int m;
6564 m = TIFFSetField(tif, dp->tdir_tag,
6565 (uint16_t)(dp->tdir_count), data);
6566 if (data != 0)
6567 _TIFFfreeExt(tif, data);
6568 if (!m)
6569 return (0);
6570 }
6571 }
6572 }
6573 break;
6574 case TIFF_SETGET_C16_SINT32:
6575 {
6576 int32_t *data;
6577 assert(fip->field_readcount == TIFF_VARIABLE);
6578 assert(fip->field_passcount == 1);
6579 if (dp->tdir_count > 0xFFFF)
6580 err = TIFFReadDirEntryErrCount;
6581 else
6582 {
6583 err = TIFFReadDirEntrySlongArray(tif, dp, &data);
6584 if (err == TIFFReadDirEntryErrOk)
6585 {
6586 int m;
6587 m = TIFFSetField(tif, dp->tdir_tag,
6588 (uint16_t)(dp->tdir_count), data);
6589 if (data != 0)
6590 _TIFFfreeExt(tif, data);
6591 if (!m)
6592 return (0);
6593 }
6594 }
6595 }
6596 break;
6597 case TIFF_SETGET_C16_UINT64:
6598 {
6599 uint64_t *data;
6600 assert(fip->field_readcount == TIFF_VARIABLE);
6601 assert(fip->field_passcount == 1);
6602 if (dp->tdir_count > 0xFFFF)
6603 err = TIFFReadDirEntryErrCount;
6604 else
6605 {
6606 err = TIFFReadDirEntryLong8Array(tif, dp, &data);
6607 if (err == TIFFReadDirEntryErrOk)
6608 {
6609 int m;
6610 m = TIFFSetField(tif, dp->tdir_tag,
6611 (uint16_t)(dp->tdir_count), data);
6612 if (data != 0)
6613 _TIFFfreeExt(tif, data);
6614 if (!m)
6615 return (0);
6616 }
6617 }
6618 }
6619 break;
6620 case TIFF_SETGET_C16_SINT64:
6621 {
6622 int64_t *data;
6623 assert(fip->field_readcount == TIFF_VARIABLE);
6624 assert(fip->field_passcount == 1);
6625 if (dp->tdir_count > 0xFFFF)
6626 err = TIFFReadDirEntryErrCount;
6627 else
6628 {
6629 err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
6630 if (err == TIFFReadDirEntryErrOk)
6631 {
6632 int m;
6633 m = TIFFSetField(tif, dp->tdir_tag,
6634 (uint16_t)(dp->tdir_count), data);
6635 if (data != 0)
6636 _TIFFfreeExt(tif, data);
6637 if (!m)
6638 return (0);
6639 }
6640 }
6641 }
6642 break;
6643 case TIFF_SETGET_C16_FLOAT:
6644 {
6645 float *data;
6646 assert(fip->field_readcount == TIFF_VARIABLE);
6647 assert(fip->field_passcount == 1);
6648 if (dp->tdir_count > 0xFFFF)
6649 err = TIFFReadDirEntryErrCount;
6650 else
6651 {
6652 err = TIFFReadDirEntryFloatArray(tif, dp, &data);
6653 if (err == TIFFReadDirEntryErrOk)
6654 {
6655 int m;
6656 m = TIFFSetField(tif, dp->tdir_tag,
6657 (uint16_t)(dp->tdir_count), data);
6658 if (data != 0)
6659 _TIFFfreeExt(tif, data);
6660 if (!m)
6661 return (0);
6662 }
6663 }
6664 }
6665 break;
6666 case TIFF_SETGET_C16_DOUBLE:
6667 {
6668 double *data;
6669 assert(fip->field_readcount == TIFF_VARIABLE);
6670 assert(fip->field_passcount == 1);
6671 if (dp->tdir_count > 0xFFFF)
6672 err = TIFFReadDirEntryErrCount;
6673 else
6674 {
6675 err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
6676 if (err == TIFFReadDirEntryErrOk)
6677 {
6678 int m;
6679 m = TIFFSetField(tif, dp->tdir_tag,
6680 (uint16_t)(dp->tdir_count), data);
6681 if (data != 0)
6682 _TIFFfreeExt(tif, data);
6683 if (!m)
6684 return (0);
6685 }
6686 }
6687 }
6688 break;
6689 case TIFF_SETGET_C16_IFD8:
6690 {
6691 uint64_t *data;
6692 assert(fip->field_readcount == TIFF_VARIABLE);
6693 assert(fip->field_passcount == 1);
6694 if (dp->tdir_count > 0xFFFF)
6695 err = TIFFReadDirEntryErrCount;
6696 else
6697 {
6698 err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
6699 if (err == TIFFReadDirEntryErrOk)
6700 {
6701 int m;
6702 m = TIFFSetField(tif, dp->tdir_tag,
6703 (uint16_t)(dp->tdir_count), data);
6704 if (data != 0)
6705 _TIFFfreeExt(tif, data);
6706 if (!m)
6707 return (0);
6708 }
6709 }
6710 }
6711 break;
6712 case TIFF_SETGET_C32_ASCII:
6713 {
6714 uint8_t *data;
6715 assert(fip->field_readcount == TIFF_VARIABLE2);
6716 assert(fip->field_passcount == 1);
6717 err = TIFFReadDirEntryByteArray(tif, dp, &data);
6718 if (err == TIFFReadDirEntryErrOk)
6719 {
6720 int m;
6721 if (data != 0 && dp->tdir_count > 0 &&
6722 data[dp->tdir_count - 1] != '\0')
6723 {
6724 TIFFWarningExtR(tif, module,
6725 "ASCII value for tag \"%s\" does not end "
6726 "in null byte. Forcing it to be null",
6727 fip->field_name);
6728 data[dp->tdir_count - 1] = '\0';
6729 }
6730 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6731 data);
6732 if (data != 0)
6733 _TIFFfreeExt(tif, data);
6734 if (!m)
6735 return (0);
6736 }
6737 }
6738 break;
6739 case TIFF_SETGET_C32_UINT8:
6740 {
6741 uint8_t *data;
6742 uint32_t count = 0;
6743 assert(fip->field_readcount == TIFF_VARIABLE2);
6744 assert(fip->field_passcount == 1);
6745 if (fip->field_tag == TIFFTAG_RICHTIFFIPTC &&
6746 dp->tdir_type == TIFF_LONG)
6747 {
6748 /* Adobe's software (wrongly) writes RichTIFFIPTC tag with
6749 * data type LONG instead of UNDEFINED. Work around this
6750 * frequently found issue */
6751 void *origdata;
6752 err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata);
6753 if ((err != TIFFReadDirEntryErrOk) || (origdata == 0))
6754 {
6755 data = NULL;
6756 }
6757 else
6758 {
6759 if (tif->tif_flags & TIFF_SWAB)
6760 TIFFSwabArrayOfLong((uint32_t *)origdata, count);
6761 data = (uint8_t *)origdata;
6762 count = (uint32_t)(count * 4);
6763 }
6764 }
6765 else
6766 {
6767 err = TIFFReadDirEntryByteArray(tif, dp, &data);
6768 count = (uint32_t)(dp->tdir_count);
6769 }
6770 if (err == TIFFReadDirEntryErrOk)
6771 {
6772 int m;
6773 m = TIFFSetField(tif, dp->tdir_tag, count, data);
6774 if (data != 0)
6775 _TIFFfreeExt(tif, data);
6776 if (!m)
6777 return (0);
6778 }
6779 }
6780 break;
6781 case TIFF_SETGET_C32_SINT8:
6782 {
6783 int8_t *data = NULL;
6784 assert(fip->field_readcount == TIFF_VARIABLE2);
6785 assert(fip->field_passcount == 1);
6786 err = TIFFReadDirEntrySbyteArray(tif, dp, &data);
6787 if (err == TIFFReadDirEntryErrOk)
6788 {
6789 int m;
6790 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6791 data);
6792 if (data != 0)
6793 _TIFFfreeExt(tif, data);
6794 if (!m)
6795 return (0);
6796 }
6797 }
6798 break;
6799 case TIFF_SETGET_C32_UINT16:
6800 {
6801 uint16_t *data;
6802 assert(fip->field_readcount == TIFF_VARIABLE2);
6803 assert(fip->field_passcount == 1);
6804 err = TIFFReadDirEntryShortArray(tif, dp, &data);
6805 if (err == TIFFReadDirEntryErrOk)
6806 {
6807 int m;
6808 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6809 data);
6810 if (data != 0)
6811 _TIFFfreeExt(tif, data);
6812 if (!m)
6813 return (0);
6814 }
6815 }
6816 break;
6817 case TIFF_SETGET_C32_SINT16:
6818 {
6819 int16_t *data = NULL;
6820 assert(fip->field_readcount == TIFF_VARIABLE2);
6821 assert(fip->field_passcount == 1);
6822 err = TIFFReadDirEntrySshortArray(tif, dp, &data);
6823 if (err == TIFFReadDirEntryErrOk)
6824 {
6825 int m;
6826 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6827 data);
6828 if (data != 0)
6829 _TIFFfreeExt(tif, data);
6830 if (!m)
6831 return (0);
6832 }
6833 }
6834 break;
6835 case TIFF_SETGET_C32_UINT32:
6836 {
6837 uint32_t *data;
6838 assert(fip->field_readcount == TIFF_VARIABLE2);
6839 assert(fip->field_passcount == 1);
6840 err = TIFFReadDirEntryLongArray(tif, dp, &data);
6841 if (err == TIFFReadDirEntryErrOk)
6842 {
6843 int m;
6844 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6845 data);
6846 if (data != 0)
6847 _TIFFfreeExt(tif, data);
6848 if (!m)
6849 return (0);
6850 }
6851 }
6852 break;
6853 case TIFF_SETGET_C32_SINT32:
6854 {
6855 int32_t *data = NULL;
6856 assert(fip->field_readcount == TIFF_VARIABLE2);
6857 assert(fip->field_passcount == 1);
6858 err = TIFFReadDirEntrySlongArray(tif, dp, &data);
6859 if (err == TIFFReadDirEntryErrOk)
6860 {
6861 int m;
6862 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6863 data);
6864 if (data != 0)
6865 _TIFFfreeExt(tif, data);
6866 if (!m)
6867 return (0);
6868 }
6869 }
6870 break;
6871 case TIFF_SETGET_C32_UINT64:
6872 {
6873 uint64_t *data;
6874 assert(fip->field_readcount == TIFF_VARIABLE2);
6875 assert(fip->field_passcount == 1);
6876 err = TIFFReadDirEntryLong8Array(tif, dp, &data);
6877 if (err == TIFFReadDirEntryErrOk)
6878 {
6879 int m;
6880 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6881 data);
6882 if (data != 0)
6883 _TIFFfreeExt(tif, data);
6884 if (!m)
6885 return (0);
6886 }
6887 }
6888 break;
6889 case TIFF_SETGET_C32_SINT64:
6890 {
6891 int64_t *data = NULL;
6892 assert(fip->field_readcount == TIFF_VARIABLE2);
6893 assert(fip->field_passcount == 1);
6894 err = TIFFReadDirEntrySlong8Array(tif, dp, &data);
6895 if (err == TIFFReadDirEntryErrOk)
6896 {
6897 int m;
6898 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6899 data);
6900 if (data != 0)
6901 _TIFFfreeExt(tif, data);
6902 if (!m)
6903 return (0);
6904 }
6905 }
6906 break;
6907 case TIFF_SETGET_C32_FLOAT:
6908 {
6909 float *data;
6910 assert(fip->field_readcount == TIFF_VARIABLE2);
6911 assert(fip->field_passcount == 1);
6912 err = TIFFReadDirEntryFloatArray(tif, dp, &data);
6913 if (err == TIFFReadDirEntryErrOk)
6914 {
6915 int m;
6916 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6917 data);
6918 if (data != 0)
6919 _TIFFfreeExt(tif, data);
6920 if (!m)
6921 return (0);
6922 }
6923 }
6924 break;
6925 case TIFF_SETGET_C32_DOUBLE:
6926 {
6927 double *data;
6928 assert(fip->field_readcount == TIFF_VARIABLE2);
6929 assert(fip->field_passcount == 1);
6930 err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
6931 if (err == TIFFReadDirEntryErrOk)
6932 {
6933 int m;
6934 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6935 data);
6936 if (data != 0)
6937 _TIFFfreeExt(tif, data);
6938 if (!m)
6939 return (0);
6940 }
6941 }
6942 break;
6943 case TIFF_SETGET_C32_IFD8:
6944 {
6945 uint64_t *data;
6946 assert(fip->field_readcount == TIFF_VARIABLE2);
6947 assert(fip->field_passcount == 1);
6948 err = TIFFReadDirEntryIfd8Array(tif, dp, &data);
6949 if (err == TIFFReadDirEntryErrOk)
6950 {
6951 int m;
6952 m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count),
6953 data);
6954 if (data != 0)
6955 _TIFFfreeExt(tif, data);
6956 if (!m)
6957 return (0);
6958 }
6959 }
6960 break;
6961 default:
6962 assert(0); /* we should never get here */
6963 break;
6964 }
6965 if (err != TIFFReadDirEntryErrOk)
6966 {
6967 TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover);
6968 return (0);
6969 }
6970 return (1);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08006971}
6972
6973/*
6974 * Fetch a set of offsets or lengths.
6975 * While this routine says "strips", in fact it's also used for tiles.
6976 */
kumarashishg826308d2023-06-23 13:21:22 +00006977static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
6978 uint64_t **lpp)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08006979{
kumarashishg826308d2023-06-23 13:21:22 +00006980 static const char module[] = "TIFFFetchStripThing";
6981 enum TIFFReadDirEntryErr err;
6982 uint64_t *data;
6983 err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips);
6984 if (err != TIFFReadDirEntryErrOk)
6985 {
6986 const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
6987 TIFFReadDirEntryOutputErr(tif, err, module,
6988 fip ? fip->field_name : "unknown tagname", 0);
6989 return (0);
6990 }
6991 if (dir->tdir_count < (uint64_t)nstrips)
6992 {
6993 uint64_t *resizeddata;
6994 const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag);
6995 const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
6996 uint32_t max_nstrips = 1000000;
6997 if (pszMax)
6998 max_nstrips = (uint32_t)atoi(pszMax);
6999 TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module,
7000 fip ? fip->field_name : "unknown tagname",
7001 (nstrips <= max_nstrips));
Haibo Huang49cc9302020-04-27 16:14:24 -07007002
kumarashishg826308d2023-06-23 13:21:22 +00007003 if (nstrips > max_nstrips)
7004 {
7005 _TIFFfreeExt(tif, data);
7006 return (0);
7007 }
Haibo Huang49cc9302020-04-27 16:14:24 -07007008
kumarashishg826308d2023-06-23 13:21:22 +00007009 resizeddata = (uint64_t *)_TIFFCheckMalloc(
7010 tif, nstrips, sizeof(uint64_t), "for strip array");
7011 if (resizeddata == 0)
7012 {
7013 _TIFFfreeExt(tif, data);
7014 return (0);
7015 }
7016 if (dir->tdir_count)
7017 _TIFFmemcpy(resizeddata, data,
7018 (uint32_t)dir->tdir_count * sizeof(uint64_t));
7019 _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0,
7020 (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t));
7021 _TIFFfreeExt(tif, data);
7022 data = resizeddata;
7023 }
7024 *lpp = data;
7025 return (1);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007026}
7027
7028/*
7029 * Fetch and set the SubjectDistance EXIF tag.
7030 */
kumarashishg826308d2023-06-23 13:21:22 +00007031static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007032{
kumarashishg826308d2023-06-23 13:21:22 +00007033 static const char module[] = "TIFFFetchSubjectDistance";
7034 enum TIFFReadDirEntryErr err;
7035 UInt64Aligned_t m;
7036 m.l = 0;
7037 assert(sizeof(double) == 8);
7038 assert(sizeof(uint64_t) == 8);
7039 assert(sizeof(uint32_t) == 4);
7040 if (dir->tdir_count != 1)
7041 err = TIFFReadDirEntryErrCount;
7042 else if (dir->tdir_type != TIFF_RATIONAL)
7043 err = TIFFReadDirEntryErrType;
7044 else
7045 {
7046 if (!(tif->tif_flags & TIFF_BIGTIFF))
7047 {
7048 uint32_t offset;
7049 offset = *(uint32_t *)(&dir->tdir_offset);
7050 if (tif->tif_flags & TIFF_SWAB)
7051 TIFFSwabLong(&offset);
7052 err = TIFFReadDirEntryData(tif, offset, 8, m.i);
7053 }
7054 else
7055 {
7056 m.l = dir->tdir_offset.toff_long8;
7057 err = TIFFReadDirEntryErrOk;
7058 }
7059 }
7060 if (err == TIFFReadDirEntryErrOk)
7061 {
7062 double n;
7063 if (tif->tif_flags & TIFF_SWAB)
7064 TIFFSwabArrayOfLong(m.i, 2);
7065 if (m.i[0] == 0)
7066 n = 0.0;
7067 else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0)
7068 /*
7069 * XXX: Numerator 0xFFFFFFFF means that we have infinite
7070 * distance. Indicate that with a negative floating point
7071 * SubjectDistance value.
7072 */
7073 n = -1.0;
7074 else
7075 n = (double)m.i[0] / (double)m.i[1];
7076 return (TIFFSetField(tif, dir->tdir_tag, n));
7077 }
7078 else
7079 {
7080 TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE);
7081 return (0);
7082 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007083}
7084
kumarashishg826308d2023-06-23 13:21:22 +00007085static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
7086 uint64_t stripbytes,
7087 uint32_t rowsperstrip)
Haibo Huang49cc9302020-04-27 16:14:24 -07007088{
7089 TIFFDirectory *td = &tif->tif_dir;
kumarashishg826308d2023-06-23 13:21:22 +00007090 uint64_t bytecount;
7091 uint64_t offset;
7092 uint64_t last_offset;
7093 uint64_t last_bytecount;
7094 uint32_t i;
7095 uint64_t *newcounts;
7096 uint64_t *newoffsets;
Haibo Huang49cc9302020-04-27 16:14:24 -07007097
7098 offset = TIFFGetStrileOffset(tif, 0);
kumarashishg826308d2023-06-23 13:21:22 +00007099 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
7100 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
7101 if (last_offset > UINT64_MAX - last_bytecount ||
7102 last_offset + last_bytecount < offset)
Haibo Huang49cc9302020-04-27 16:14:24 -07007103 {
7104 return;
7105 }
7106 bytecount = last_offset + last_bytecount - offset;
7107
kumarashishg826308d2023-06-23 13:21:22 +00007108 newcounts =
7109 (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t),
7110 "for chopped \"StripByteCounts\" array");
7111 newoffsets = (uint64_t *)_TIFFCheckMalloc(
7112 tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array");
7113 if (newcounts == NULL || newoffsets == NULL)
7114 {
Haibo Huang49cc9302020-04-27 16:14:24 -07007115 /*
kumarashishg826308d2023-06-23 13:21:22 +00007116 * Unable to allocate new strip information, give up and use
7117 * the original one strip information.
7118 */
Haibo Huang49cc9302020-04-27 16:14:24 -07007119 if (newcounts != NULL)
kumarashishg826308d2023-06-23 13:21:22 +00007120 _TIFFfreeExt(tif, newcounts);
Haibo Huang49cc9302020-04-27 16:14:24 -07007121 if (newoffsets != NULL)
kumarashishg826308d2023-06-23 13:21:22 +00007122 _TIFFfreeExt(tif, newoffsets);
Haibo Huang49cc9302020-04-27 16:14:24 -07007123 return;
7124 }
7125
7126 /*
7127 * Fill the strip information arrays with new bytecounts and offsets
7128 * that reflect the broken-up format.
7129 */
7130 for (i = 0; i < nstrips; i++)
7131 {
7132 if (stripbytes > bytecount)
7133 stripbytes = bytecount;
7134 newcounts[i] = stripbytes;
7135 newoffsets[i] = stripbytes ? offset : 0;
7136 offset += stripbytes;
7137 bytecount -= stripbytes;
7138 }
7139
7140 /*
7141 * Replace old single strip info with multi-strip info.
7142 */
7143 td->td_stripsperimage = td->td_nstrips = nstrips;
7144 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
7145
kumarashishg826308d2023-06-23 13:21:22 +00007146 _TIFFfreeExt(tif, td->td_stripbytecount_p);
7147 _TIFFfreeExt(tif, td->td_stripoffset_p);
Haibo Huang49cc9302020-04-27 16:14:24 -07007148 td->td_stripbytecount_p = newcounts;
7149 td->td_stripoffset_p = newoffsets;
7150#ifdef STRIPBYTECOUNTSORTED_UNUSED
7151 td->td_stripbytecountsorted = 1;
7152#endif
7153 tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
7154}
7155
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007156/*
7157 * Replace a single strip (tile) of uncompressed data by multiple strips
7158 * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
7159 * dealing with large images or for dealing with machines with a limited
7160 * amount memory.
7161 */
kumarashishg826308d2023-06-23 13:21:22 +00007162static void ChopUpSingleUncompressedStrip(TIFF *tif)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007163{
kumarashishg826308d2023-06-23 13:21:22 +00007164 register TIFFDirectory *td = &tif->tif_dir;
7165 uint64_t bytecount;
7166 uint64_t offset;
7167 uint32_t rowblock;
7168 uint64_t rowblockbytes;
7169 uint64_t stripbytes;
7170 uint32_t nstrips;
7171 uint32_t rowsperstrip;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007172
kumarashishg826308d2023-06-23 13:21:22 +00007173 bytecount = TIFFGetStrileByteCount(tif, 0);
7174 /* On a newly created file, just re-opened to be filled, we */
7175 /* don't want strip chop to trigger as it is going to cause issues */
7176 /* later ( StripOffsets and StripByteCounts improperly filled) . */
7177 if (bytecount == 0 && tif->tif_mode != O_RDONLY)
7178 return;
7179 offset = TIFFGetStrileByteCount(tif, 0);
7180 assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
7181 if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
7182 rowblock = td->td_ycbcrsubsampling[1];
7183 else
7184 rowblock = 1;
7185 rowblockbytes = TIFFVTileSize64(tif, rowblock);
7186 /*
7187 * Make the rows hold at least one scanline, but fill specified amount
7188 * of data if possible.
7189 */
7190 if (rowblockbytes > STRIP_SIZE_DEFAULT)
7191 {
7192 stripbytes = rowblockbytes;
7193 rowsperstrip = rowblock;
7194 }
7195 else if (rowblockbytes > 0)
7196 {
7197 uint32_t rowblocksperstrip;
7198 rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes);
7199 rowsperstrip = rowblocksperstrip * rowblock;
7200 stripbytes = rowblocksperstrip * rowblockbytes;
7201 }
7202 else
7203 return;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007204
kumarashishg826308d2023-06-23 13:21:22 +00007205 /*
7206 * never increase the number of rows per strip
7207 */
7208 if (rowsperstrip >= td->td_rowsperstrip)
7209 return;
7210 nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
7211 if (nstrips == 0)
7212 return;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007213
kumarashishg826308d2023-06-23 13:21:22 +00007214 /* If we are going to allocate a lot of memory, make sure that the */
7215 /* file is as big as needed */
7216 if (tif->tif_mode == O_RDONLY && nstrips > 1000000 &&
7217 (offset >= TIFFGetFileSize(tif) ||
7218 stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)))
7219 {
7220 return;
7221 }
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007222
kumarashishg826308d2023-06-23 13:21:22 +00007223 allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007224}
7225
Haibo Huang49cc9302020-04-27 16:14:24 -07007226/*
7227 * Replace a file with contiguous strips > 2 GB of uncompressed data by
7228 * multiple smaller strips. This is useful for
7229 * dealing with large images or for dealing with machines with a limited
7230 * amount memory.
7231 */
kumarashishg826308d2023-06-23 13:21:22 +00007232static void TryChopUpUncompressedBigTiff(TIFF *tif)
Haibo Huang49cc9302020-04-27 16:14:24 -07007233{
7234 TIFFDirectory *td = &tif->tif_dir;
kumarashishg826308d2023-06-23 13:21:22 +00007235 uint32_t rowblock;
7236 uint64_t rowblockbytes;
7237 uint32_t i;
7238 uint64_t stripsize;
7239 uint32_t rowblocksperstrip;
7240 uint32_t rowsperstrip;
7241 uint64_t stripbytes;
7242 uint32_t nstrips;
Haibo Huang49cc9302020-04-27 16:14:24 -07007243
7244 stripsize = TIFFStripSize64(tif);
7245
kumarashishg826308d2023-06-23 13:21:22 +00007246 assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG);
7247 assert(tif->tif_dir.td_compression == COMPRESSION_NONE);
7248 assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) ==
7249 TIFF_STRIPCHOP);
7250 assert(stripsize > 0x7FFFFFFFUL);
Haibo Huang49cc9302020-04-27 16:14:24 -07007251
7252 /* On a newly created file, just re-opened to be filled, we */
7253 /* don't want strip chop to trigger as it is going to cause issues */
7254 /* later ( StripOffsets and StripByteCounts improperly filled) . */
kumarashishg826308d2023-06-23 13:21:22 +00007255 if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY)
Haibo Huang49cc9302020-04-27 16:14:24 -07007256 return;
7257
kumarashishg826308d2023-06-23 13:21:22 +00007258 if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
Haibo Huang49cc9302020-04-27 16:14:24 -07007259 rowblock = td->td_ycbcrsubsampling[1];
7260 else
7261 rowblock = 1;
7262 rowblockbytes = TIFFVStripSize64(tif, rowblock);
kumarashishg826308d2023-06-23 13:21:22 +00007263 if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL)
Haibo Huang49cc9302020-04-27 16:14:24 -07007264 {
7265 /* In case of file with gigantic width */
7266 return;
7267 }
7268
7269 /* Check that the strips are contiguous and of the expected size */
kumarashishg826308d2023-06-23 13:21:22 +00007270 for (i = 0; i < td->td_nstrips; i++)
Haibo Huang49cc9302020-04-27 16:14:24 -07007271 {
kumarashishg826308d2023-06-23 13:21:22 +00007272 if (i == td->td_nstrips - 1)
Haibo Huang49cc9302020-04-27 16:14:24 -07007273 {
kumarashishg826308d2023-06-23 13:21:22 +00007274 if (TIFFGetStrileByteCount(tif, i) <
7275 TIFFVStripSize64(tif,
7276 td->td_imagelength - i * td->td_rowsperstrip))
Haibo Huang49cc9302020-04-27 16:14:24 -07007277 {
7278 return;
7279 }
7280 }
7281 else
7282 {
kumarashishg826308d2023-06-23 13:21:22 +00007283 if (TIFFGetStrileByteCount(tif, i) != stripsize)
Haibo Huang49cc9302020-04-27 16:14:24 -07007284 {
7285 return;
7286 }
kumarashishg826308d2023-06-23 13:21:22 +00007287 if (i > 0 && TIFFGetStrileOffset(tif, i) !=
7288 TIFFGetStrileOffset(tif, i - 1) +
7289 TIFFGetStrileByteCount(tif, i - 1))
Haibo Huang49cc9302020-04-27 16:14:24 -07007290 {
7291 return;
7292 }
7293 }
7294 }
7295
7296 /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
kumarashishg826308d2023-06-23 13:21:22 +00007297 rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes);
7298 if (rowblocksperstrip == 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07007299 rowblocksperstrip = 1;
7300 rowsperstrip = rowblocksperstrip * rowblock;
7301 stripbytes = rowblocksperstrip * rowblockbytes;
kumarashishg826308d2023-06-23 13:21:22 +00007302 assert(stripbytes <= 0x7FFFFFFFUL);
Haibo Huang49cc9302020-04-27 16:14:24 -07007303
7304 nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
kumarashishg826308d2023-06-23 13:21:22 +00007305 if (nstrips == 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07007306 return;
7307
7308 /* If we are going to allocate a lot of memory, make sure that the */
7309 /* file is as big as needed */
kumarashishg826308d2023-06-23 13:21:22 +00007310 if (tif->tif_mode == O_RDONLY && nstrips > 1000000)
Haibo Huang49cc9302020-04-27 16:14:24 -07007311 {
kumarashishg826308d2023-06-23 13:21:22 +00007312 uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1);
7313 uint64_t filesize = TIFFGetFileSize(tif);
7314 uint64_t last_bytecount =
7315 TIFFGetStrileByteCount(tif, td->td_nstrips - 1);
7316 if (last_offset > filesize || last_bytecount > filesize - last_offset)
Haibo Huang49cc9302020-04-27 16:14:24 -07007317 {
7318 return;
7319 }
7320 }
7321
7322 allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
7323}
7324
Haibo Huang49cc9302020-04-27 16:14:24 -07007325TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
kumarashishg826308d2023-06-23 13:21:22 +00007326static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
Haibo Huang49cc9302020-04-27 16:14:24 -07007327{
7328 return a + b;
7329}
7330
7331/* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
7332 * strip/tile of number strile. Also fetch the neighbouring values using a
7333 * 4096 byte page size.
7334 */
kumarashishg826308d2023-06-23 13:21:22 +00007335static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
7336 int strile, uint64_t *panVals)
Haibo Huang49cc9302020-04-27 16:14:24 -07007337{
7338 static const char module[] = "_TIFFPartialReadStripArray";
7339#define IO_CACHE_PAGE_SIZE 4096
7340
7341 size_t sizeofval;
7342 const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
7343 int sizeofvalint;
kumarashishg826308d2023-06-23 13:21:22 +00007344 uint64_t nBaseOffset;
7345 uint64_t nOffset;
7346 uint64_t nOffsetStartPage;
7347 uint64_t nOffsetEndPage;
Haibo Huang49cc9302020-04-27 16:14:24 -07007348 tmsize_t nToRead;
7349 tmsize_t nRead;
kumarashishg826308d2023-06-23 13:21:22 +00007350 uint64_t nLastStripOffset;
Haibo Huang49cc9302020-04-27 16:14:24 -07007351 int iStartBefore;
7352 int i;
kumarashishg826308d2023-06-23 13:21:22 +00007353 const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
Haibo Huang49cc9302020-04-27 16:14:24 -07007354 unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
7355
kumarashishg826308d2023-06-23 13:21:22 +00007356 assert(dirent->tdir_count > 4);
Haibo Huang49cc9302020-04-27 16:14:24 -07007357
kumarashishg826308d2023-06-23 13:21:22 +00007358 if (dirent->tdir_type == TIFF_SHORT)
Haibo Huang49cc9302020-04-27 16:14:24 -07007359 {
kumarashishg826308d2023-06-23 13:21:22 +00007360 sizeofval = sizeof(uint16_t);
Haibo Huang49cc9302020-04-27 16:14:24 -07007361 }
kumarashishg826308d2023-06-23 13:21:22 +00007362 else if (dirent->tdir_type == TIFF_LONG)
Haibo Huang49cc9302020-04-27 16:14:24 -07007363 {
kumarashishg826308d2023-06-23 13:21:22 +00007364 sizeofval = sizeof(uint32_t);
Haibo Huang49cc9302020-04-27 16:14:24 -07007365 }
kumarashishg826308d2023-06-23 13:21:22 +00007366 else if (dirent->tdir_type == TIFF_LONG8)
Haibo Huang49cc9302020-04-27 16:14:24 -07007367 {
kumarashishg826308d2023-06-23 13:21:22 +00007368 sizeofval = sizeof(uint64_t);
7369 }
7370 else if (dirent->tdir_type == TIFF_SLONG8)
7371 {
7372 /* Non conformant but used by some images as in */
7373 /* https://github.com/OSGeo/gdal/issues/2165 */
7374 sizeofval = sizeof(int64_t);
Haibo Huang49cc9302020-04-27 16:14:24 -07007375 }
7376 else
7377 {
kumarashishg826308d2023-06-23 13:21:22 +00007378 TIFFErrorExtR(tif, module,
7379 "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
Haibo Huang49cc9302020-04-27 16:14:24 -07007380 panVals[strile] = 0;
7381 return 0;
7382 }
7383 sizeofvalint = (int)(sizeofval);
7384
kumarashishg826308d2023-06-23 13:21:22 +00007385 if (tif->tif_flags & TIFF_BIGTIFF)
Haibo Huang49cc9302020-04-27 16:14:24 -07007386 {
kumarashishg826308d2023-06-23 13:21:22 +00007387 uint64_t offset = dirent->tdir_offset.toff_long8;
7388 if (bSwab)
Haibo Huang49cc9302020-04-27 16:14:24 -07007389 TIFFSwabLong8(&offset);
7390 nBaseOffset = offset;
7391 }
7392 else
7393 {
kumarashishg826308d2023-06-23 13:21:22 +00007394 uint32_t offset = dirent->tdir_offset.toff_long;
7395 if (bSwab)
Haibo Huang49cc9302020-04-27 16:14:24 -07007396 TIFFSwabLong(&offset);
7397 nBaseOffset = offset;
7398 }
7399 /* To avoid later unsigned integer overflows */
kumarashishg826308d2023-06-23 13:21:22 +00007400 if (nBaseOffset > (uint64_t)INT64_MAX)
Haibo Huang49cc9302020-04-27 16:14:24 -07007401 {
kumarashishg826308d2023-06-23 13:21:22 +00007402 TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7403 strile);
Haibo Huang49cc9302020-04-27 16:14:24 -07007404 panVals[strile] = 0;
7405 return 0;
7406 }
7407 nOffset = nBaseOffset + sizeofval * strile;
kumarashishg826308d2023-06-23 13:21:22 +00007408 nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
Haibo Huang49cc9302020-04-27 16:14:24 -07007409 nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
7410
kumarashishg826308d2023-06-23 13:21:22 +00007411 if (nOffset + sizeofval > nOffsetEndPage)
Haibo Huang49cc9302020-04-27 16:14:24 -07007412 nOffsetEndPage += IO_CACHE_PAGE_SIZE;
7413#undef IO_CACHE_PAGE_SIZE
7414
7415 nLastStripOffset = nBaseOffset + arraySize * sizeofval;
kumarashishg826308d2023-06-23 13:21:22 +00007416 if (nLastStripOffset < nOffsetEndPage)
Haibo Huang49cc9302020-04-27 16:14:24 -07007417 nOffsetEndPage = nLastStripOffset;
kumarashishg826308d2023-06-23 13:21:22 +00007418 if (nOffsetStartPage >= nOffsetEndPage)
Haibo Huang49cc9302020-04-27 16:14:24 -07007419 {
kumarashishg826308d2023-06-23 13:21:22 +00007420 TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7421 strile);
Haibo Huang49cc9302020-04-27 16:14:24 -07007422 panVals[strile] = 0;
7423 return 0;
7424 }
kumarashishg826308d2023-06-23 13:21:22 +00007425 if (!SeekOK(tif, nOffsetStartPage))
Haibo Huang49cc9302020-04-27 16:14:24 -07007426 {
7427 panVals[strile] = 0;
7428 return 0;
7429 }
7430
7431 nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
7432 nRead = TIFFReadFile(tif, buffer, nToRead);
kumarashishg826308d2023-06-23 13:21:22 +00007433 if (nRead < nToRead)
Haibo Huang49cc9302020-04-27 16:14:24 -07007434 {
kumarashishg826308d2023-06-23 13:21:22 +00007435 TIFFErrorExtR(tif, module,
7436 "Cannot read offset/size for strile around ~%d", strile);
Haibo Huang49cc9302020-04-27 16:14:24 -07007437 return 0;
7438 }
7439 iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
kumarashishg826308d2023-06-23 13:21:22 +00007440 if (strile + iStartBefore < 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07007441 iStartBefore = -strile;
kumarashishg826308d2023-06-23 13:21:22 +00007442 for (i = iStartBefore;
7443 (uint32_t)(strile + i) < arraySize &&
7444 _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <=
7445 nOffsetEndPage;
7446 ++i)
Haibo Huang49cc9302020-04-27 16:14:24 -07007447 {
kumarashishg826308d2023-06-23 13:21:22 +00007448 if (dirent->tdir_type == TIFF_SHORT)
Haibo Huang49cc9302020-04-27 16:14:24 -07007449 {
kumarashishg826308d2023-06-23 13:21:22 +00007450 uint16_t val;
Haibo Huang49cc9302020-04-27 16:14:24 -07007451 memcpy(&val,
7452 buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7453 sizeof(val));
kumarashishg826308d2023-06-23 13:21:22 +00007454 if (bSwab)
Haibo Huang49cc9302020-04-27 16:14:24 -07007455 TIFFSwabShort(&val);
7456 panVals[strile + i] = val;
7457 }
kumarashishg826308d2023-06-23 13:21:22 +00007458 else if (dirent->tdir_type == TIFF_LONG)
Haibo Huang49cc9302020-04-27 16:14:24 -07007459 {
kumarashishg826308d2023-06-23 13:21:22 +00007460 uint32_t val;
Haibo Huang49cc9302020-04-27 16:14:24 -07007461 memcpy(&val,
7462 buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7463 sizeof(val));
kumarashishg826308d2023-06-23 13:21:22 +00007464 if (bSwab)
Haibo Huang49cc9302020-04-27 16:14:24 -07007465 TIFFSwabLong(&val);
7466 panVals[strile + i] = val;
7467 }
kumarashishg826308d2023-06-23 13:21:22 +00007468 else if (dirent->tdir_type == TIFF_LONG8)
Haibo Huang49cc9302020-04-27 16:14:24 -07007469 {
kumarashishg826308d2023-06-23 13:21:22 +00007470 uint64_t val;
Haibo Huang49cc9302020-04-27 16:14:24 -07007471 memcpy(&val,
7472 buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7473 sizeof(val));
kumarashishg826308d2023-06-23 13:21:22 +00007474 if (bSwab)
Haibo Huang49cc9302020-04-27 16:14:24 -07007475 TIFFSwabLong8(&val);
7476 panVals[strile + i] = val;
7477 }
kumarashishg826308d2023-06-23 13:21:22 +00007478 else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
7479 {
7480 /* Non conformant data type */
7481 int64_t val;
7482 memcpy(&val,
7483 buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7484 sizeof(val));
7485 if (bSwab)
7486 TIFFSwabLong8((uint64_t *)&val);
7487 panVals[strile + i] = (uint64_t)val;
7488 }
Haibo Huang49cc9302020-04-27 16:14:24 -07007489 }
7490 return 1;
7491}
7492
kumarashishg826308d2023-06-23 13:21:22 +00007493static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
7494 TIFFDirEntry *dirent, uint64_t **parray)
Haibo Huang49cc9302020-04-27 16:14:24 -07007495{
7496 static const char module[] = "_TIFFFetchStrileValue";
7497 TIFFDirectory *td = &tif->tif_dir;
kumarashishg826308d2023-06-23 13:21:22 +00007498 if (strile >= dirent->tdir_count)
Haibo Huang49cc9302020-04-27 16:14:24 -07007499 {
7500 return 0;
7501 }
kumarashishg826308d2023-06-23 13:21:22 +00007502 if (strile >= td->td_stripoffsetbyteallocsize)
Haibo Huang49cc9302020-04-27 16:14:24 -07007503 {
kumarashishg826308d2023-06-23 13:21:22 +00007504 uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
7505 uint32_t nStripArrayAllocNew;
7506 uint64_t nArraySize64;
Haibo Huang49cc9302020-04-27 16:14:24 -07007507 size_t nArraySize;
kumarashishg826308d2023-06-23 13:21:22 +00007508 uint64_t *offsetArray;
7509 uint64_t *bytecountArray;
Haibo Huang49cc9302020-04-27 16:14:24 -07007510
kumarashishg826308d2023-06-23 13:21:22 +00007511 if (strile > 1000000)
Haibo Huang49cc9302020-04-27 16:14:24 -07007512 {
kumarashishg826308d2023-06-23 13:21:22 +00007513 uint64_t filesize = TIFFGetFileSize(tif);
Haibo Huang49cc9302020-04-27 16:14:24 -07007514 /* Avoid excessive memory allocation attempt */
7515 /* For such a big blockid we need at least a TIFF_LONG per strile */
7516 /* for the offset array. */
kumarashishg826308d2023-06-23 13:21:22 +00007517 if (strile > filesize / sizeof(uint32_t))
Haibo Huang49cc9302020-04-27 16:14:24 -07007518 {
kumarashishg826308d2023-06-23 13:21:22 +00007519 TIFFErrorExtR(tif, module, "File too short");
Haibo Huang49cc9302020-04-27 16:14:24 -07007520 return 0;
7521 }
7522 }
7523
kumarashishg826308d2023-06-23 13:21:22 +00007524 if (td->td_stripoffsetbyteallocsize == 0 &&
7525 td->td_nstrips < 1024 * 1024)
Haibo Huang49cc9302020-04-27 16:14:24 -07007526 {
7527 nStripArrayAllocNew = td->td_nstrips;
7528 }
7529 else
7530 {
kumarashishg826308d2023-06-23 13:21:22 +00007531#define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b))
7532#define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b))
7533 nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U);
7534 if (nStripArrayAllocNew < 0xFFFFFFFFU / 2)
Haibo Huang49cc9302020-04-27 16:14:24 -07007535 nStripArrayAllocNew *= 2;
7536 nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
7537 }
kumarashishg826308d2023-06-23 13:21:22 +00007538 assert(strile < nStripArrayAllocNew);
7539 nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew;
Haibo Huang49cc9302020-04-27 16:14:24 -07007540 nArraySize = (size_t)(nArraySize64);
7541#if SIZEOF_SIZE_T == 4
kumarashishg826308d2023-06-23 13:21:22 +00007542 if (nArraySize != nArraySize64)
Haibo Huang49cc9302020-04-27 16:14:24 -07007543 {
kumarashishg826308d2023-06-23 13:21:22 +00007544 TIFFErrorExtR(tif, module,
7545 "Cannot allocate strip offset and bytecount arrays");
Haibo Huang49cc9302020-04-27 16:14:24 -07007546 return 0;
7547 }
7548#endif
kumarashishg826308d2023-06-23 13:21:22 +00007549 offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p,
7550 nArraySize));
7551 bytecountArray = (uint64_t *)(_TIFFreallocExt(
7552 tif, td->td_stripbytecount_p, nArraySize));
7553 if (offsetArray)
Haibo Huang49cc9302020-04-27 16:14:24 -07007554 td->td_stripoffset_p = offsetArray;
kumarashishg826308d2023-06-23 13:21:22 +00007555 if (bytecountArray)
Haibo Huang49cc9302020-04-27 16:14:24 -07007556 td->td_stripbytecount_p = bytecountArray;
kumarashishg826308d2023-06-23 13:21:22 +00007557 if (offsetArray && bytecountArray)
Haibo Huang49cc9302020-04-27 16:14:24 -07007558 {
7559 td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
7560 /* Initialize new entries to ~0 / -1 */
kumarashishg826308d2023-06-23 13:21:22 +00007561 /* coverity[overrun-buffer-arg] */
7562 memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF,
7563 (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
7564 sizeof(uint64_t));
7565 /* coverity[overrun-buffer-arg] */
7566 memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF,
7567 (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) *
7568 sizeof(uint64_t));
Haibo Huang49cc9302020-04-27 16:14:24 -07007569 }
7570 else
7571 {
kumarashishg826308d2023-06-23 13:21:22 +00007572 TIFFErrorExtR(tif, module,
7573 "Cannot allocate strip offset and bytecount arrays");
7574 _TIFFfreeExt(tif, td->td_stripoffset_p);
Haibo Huang49cc9302020-04-27 16:14:24 -07007575 td->td_stripoffset_p = NULL;
kumarashishg826308d2023-06-23 13:21:22 +00007576 _TIFFfreeExt(tif, td->td_stripbytecount_p);
Haibo Huang49cc9302020-04-27 16:14:24 -07007577 td->td_stripbytecount_p = NULL;
7578 td->td_stripoffsetbyteallocsize = 0;
7579 }
7580 }
kumarashishg826308d2023-06-23 13:21:22 +00007581 if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize)
Haibo Huang49cc9302020-04-27 16:14:24 -07007582 return 0;
7583
kumarashishg826308d2023-06-23 13:21:22 +00007584 if (~((*parray)[strile]) == 0)
Haibo Huang49cc9302020-04-27 16:14:24 -07007585 {
kumarashishg826308d2023-06-23 13:21:22 +00007586 if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
Haibo Huang49cc9302020-04-27 16:14:24 -07007587 {
7588 (*parray)[strile] = 0;
7589 return 0;
7590 }
7591 }
7592
7593 return 1;
7594}
7595
kumarashishg826308d2023-06-23 13:21:22 +00007596static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
7597 TIFFDirEntry *dirent,
7598 uint64_t **parray,
7599 int *pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007600{
7601 TIFFDirectory *td = &tif->tif_dir;
kumarashishg826308d2023-06-23 13:21:22 +00007602 if (pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007603 *pbErr = 0;
kumarashishg826308d2023-06-23 13:21:22 +00007604 if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
7605 !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
Haibo Huang49cc9302020-04-27 16:14:24 -07007606 {
kumarashishg826308d2023-06-23 13:21:22 +00007607 if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
Haibo Huang49cc9302020-04-27 16:14:24 -07007608 /* If the values may fit in the toff_long/toff_long8 member */
7609 /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
kumarashishg826308d2023-06-23 13:21:22 +00007610 dirent->tdir_count <= 4)
Haibo Huang49cc9302020-04-27 16:14:24 -07007611 {
kumarashishg826308d2023-06-23 13:21:22 +00007612 if (!_TIFFFillStriles(tif))
Haibo Huang49cc9302020-04-27 16:14:24 -07007613 {
kumarashishg826308d2023-06-23 13:21:22 +00007614 if (pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007615 *pbErr = 1;
7616 /* Do not return, as we want this function to always */
7617 /* return the same value if called several times with */
7618 /* the same arguments */
7619 }
7620 }
7621 else
7622 {
kumarashishg826308d2023-06-23 13:21:22 +00007623 if (!_TIFFFetchStrileValue(tif, strile, dirent, parray))
7624 {
7625 if (pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007626 *pbErr = 1;
kumarashishg826308d2023-06-23 13:21:22 +00007627 return 0;
7628 }
Haibo Huang49cc9302020-04-27 16:14:24 -07007629 }
7630 }
kumarashishg826308d2023-06-23 13:21:22 +00007631 if (*parray == NULL || strile >= td->td_nstrips)
Haibo Huang49cc9302020-04-27 16:14:24 -07007632 {
kumarashishg826308d2023-06-23 13:21:22 +00007633 if (pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007634 *pbErr = 1;
7635 return 0;
7636 }
7637 return (*parray)[strile];
7638}
7639
kumarashishg826308d2023-06-23 13:21:22 +00007640/* Return the value of the TileOffsets/StripOffsets array for the specified
7641 * tile/strile */
7642uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile)
Haibo Huang49cc9302020-04-27 16:14:24 -07007643{
7644 return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
7645}
7646
kumarashishg826308d2023-06-23 13:21:22 +00007647/* Return the value of the TileOffsets/StripOffsets array for the specified
7648 * tile/strile */
7649uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007650{
7651 TIFFDirectory *td = &tif->tif_dir;
7652 return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
kumarashishg826308d2023-06-23 13:21:22 +00007653 &(td->td_stripoffset_entry),
7654 &(td->td_stripoffset_p), pbErr);
Haibo Huang49cc9302020-04-27 16:14:24 -07007655}
7656
kumarashishg826308d2023-06-23 13:21:22 +00007657/* Return the value of the TileByteCounts/StripByteCounts array for the
7658 * specified tile/strile */
7659uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile)
Haibo Huang49cc9302020-04-27 16:14:24 -07007660{
7661 return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
7662}
7663
kumarashishg826308d2023-06-23 13:21:22 +00007664/* Return the value of the TileByteCounts/StripByteCounts array for the
7665 * specified tile/strile */
7666uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr)
Haibo Huang49cc9302020-04-27 16:14:24 -07007667{
7668 TIFFDirectory *td = &tif->tif_dir;
kumarashishg826308d2023-06-23 13:21:22 +00007669 return _TIFFGetStrileOffsetOrByteCountValue(
7670 tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p),
7671 pbErr);
Haibo Huang49cc9302020-04-27 16:14:24 -07007672}
7673
kumarashishg826308d2023-06-23 13:21:22 +00007674int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
Haibo Huang49cc9302020-04-27 16:14:24 -07007675
kumarashishg826308d2023-06-23 13:21:22 +00007676static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07007677{
Haibo Huang49cc9302020-04-27 16:14:24 -07007678 register TIFFDirectory *td = &tif->tif_dir;
7679 int return_value = 1;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007680
Haibo Huang49cc9302020-04-27 16:14:24 -07007681 /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
kumarashishg826308d2023-06-23 13:21:22 +00007682 if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) ||
7683 (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007684 return 1;
Haibo Huang49cc9302020-04-27 16:14:24 -07007685
kumarashishg826308d2023-06-23 13:21:22 +00007686 if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
Haibo Huang49cc9302020-04-27 16:14:24 -07007687 {
7688 /* In case of lazy loading, reload completely the arrays */
kumarashishg826308d2023-06-23 13:21:22 +00007689 _TIFFfreeExt(tif, td->td_stripoffset_p);
7690 _TIFFfreeExt(tif, td->td_stripbytecount_p);
Haibo Huang49cc9302020-04-27 16:14:24 -07007691 td->td_stripoffset_p = NULL;
7692 td->td_stripbytecount_p = NULL;
7693 td->td_stripoffsetbyteallocsize = 0;
7694 tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
7695 }
7696
7697 /* If stripoffset array is already loaded, exit with success */
kumarashishg826308d2023-06-23 13:21:22 +00007698 if (td->td_stripoffset_p != NULL)
7699 return 1;
Haibo Huang49cc9302020-04-27 16:14:24 -07007700
kumarashishg826308d2023-06-23 13:21:22 +00007701 /* If tdir_count was canceled, then we already got there, but in error */
7702 if (td->td_stripoffset_entry.tdir_count == 0)
7703 return 0;
Haibo Huang49cc9302020-04-27 16:14:24 -07007704
kumarashishg826308d2023-06-23 13:21:22 +00007705 if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips,
7706 &td->td_stripoffset_p))
Haibo Huang49cc9302020-04-27 16:14:24 -07007707 {
kumarashishg826308d2023-06-23 13:21:22 +00007708 return_value = 0;
Haibo Huang49cc9302020-04-27 16:14:24 -07007709 }
7710
7711 if (loadStripByteCount &&
kumarashishg826308d2023-06-23 13:21:22 +00007712 !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry),
7713 td->td_nstrips, &td->td_stripbytecount_p))
Haibo Huang49cc9302020-04-27 16:14:24 -07007714 {
kumarashishg826308d2023-06-23 13:21:22 +00007715 return_value = 0;
Haibo Huang49cc9302020-04-27 16:14:24 -07007716 }
7717
kumarashishg826308d2023-06-23 13:21:22 +00007718 _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
7719 _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
Haibo Huang49cc9302020-04-27 16:14:24 -07007720
7721#ifdef STRIPBYTECOUNTSORTED_UNUSED
kumarashishg826308d2023-06-23 13:21:22 +00007722 if (tif->tif_dir.td_nstrips > 1 && return_value == 1)
7723 {
7724 uint32_t strip;
Haibo Huang49cc9302020-04-27 16:14:24 -07007725
kumarashishg826308d2023-06-23 13:21:22 +00007726 tif->tif_dir.td_stripbytecountsorted = 1;
7727 for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++)
7728 {
7729 if (tif->tif_dir.td_stripoffset_p[strip - 1] >
7730 tif->tif_dir.td_stripoffset_p[strip])
7731 {
7732 tif->tif_dir.td_stripbytecountsorted = 0;
7733 break;
Haibo Huang49cc9302020-04-27 16:14:24 -07007734 }
kumarashishg826308d2023-06-23 13:21:22 +00007735 }
Haibo Huang49cc9302020-04-27 16:14:24 -07007736 }
7737#endif
7738
7739 return return_value;
Philip P. Moltmannac3d58c2016-03-04 15:19:21 -08007740}