• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1988-1997 Sam Leffler
3  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that (i) the above copyright notices and this permission notice appear in
8  * all copies of the software and related documentation, and (ii) the names of
9  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10  * publicity relating to the software without the specific, prior written
11  * permission of Sam Leffler and Silicon Graphics.
12  *
13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22  * OF THIS SOFTWARE.
23  */
24 
25 /*
26  * TIFF Library.
27  *
28  * Directory Read Support Routines.
29  */
30 
31 /* Suggested pending improvements:
32  * - 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 
37 #include "tiffconf.h"
38 #include "tiffiop.h"
39 #include <float.h>
40 #include <limits.h>
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #define FAILED_FII ((uint32_t)-1)
45 
46 #ifdef HAVE_IEEEFP
47 #define TIFFCvtIEEEFloatToNative(tif, n, fp)
48 #define TIFFCvtIEEEDoubleToNative(tif, n, dp)
49 #else
50 extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *);
51 extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *);
52 #endif
53 
54 enum 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,
64 };
65 
66 static enum TIFFReadDirEntryErr
67 TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value);
68 static enum TIFFReadDirEntryErr
69 TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value);
70 static enum TIFFReadDirEntryErr
71 TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value);
72 static enum TIFFReadDirEntryErr
73 TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value);
74 static enum TIFFReadDirEntryErr
75 TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value);
76 static enum TIFFReadDirEntryErr
77 TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value);
78 static enum TIFFReadDirEntryErr
79 TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
80 static enum TIFFReadDirEntryErr
81 TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value);
82 static enum TIFFReadDirEntryErr
83 TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value);
84 static enum TIFFReadDirEntryErr
85 TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
86 static enum TIFFReadDirEntryErr
87 TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value);
88 
89 static enum TIFFReadDirEntryErr
90 TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
91                       uint32_t desttypesize, void **value);
92 static enum TIFFReadDirEntryErr
93 TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value);
94 static enum TIFFReadDirEntryErr
95 TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value);
96 static enum TIFFReadDirEntryErr
97 TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value);
98 static enum TIFFReadDirEntryErr
99 TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value);
100 static enum TIFFReadDirEntryErr
101 TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value);
102 static enum TIFFReadDirEntryErr
103 TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value);
104 static enum TIFFReadDirEntryErr
105 TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
106 static enum TIFFReadDirEntryErr
107 TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value);
108 static enum TIFFReadDirEntryErr
109 TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value);
110 static enum TIFFReadDirEntryErr
111 TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value);
112 static enum TIFFReadDirEntryErr
113 TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value);
114 
115 static enum TIFFReadDirEntryErr
116 TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
117                                uint16_t *value);
118 
119 static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
120                                         uint8_t *value);
121 static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
122                                          int8_t *value);
123 static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry,
124                                          uint16_t *value);
125 static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry,
126                                           int16_t *value);
127 static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry,
128                                         uint32_t *value);
129 static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry,
130                                          int32_t *value);
131 static enum TIFFReadDirEntryErr
132 TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry,
133                              uint64_t *value);
134 static enum TIFFReadDirEntryErr
135 TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry,
136                               int64_t *value);
137 static enum TIFFReadDirEntryErr
138 TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry,
139                                 double *value);
140 static enum TIFFReadDirEntryErr
141 TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry,
142                                  double *value);
143 static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry,
144                                          float *value);
145 static enum TIFFReadDirEntryErr
146 TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value);
147 
148 static enum TIFFReadDirEntryErr
149 TIFFReadDirEntryCheckRangeByteSbyte(int8_t value);
150 static enum TIFFReadDirEntryErr
151 TIFFReadDirEntryCheckRangeByteShort(uint16_t value);
152 static enum TIFFReadDirEntryErr
153 TIFFReadDirEntryCheckRangeByteSshort(int16_t value);
154 static enum TIFFReadDirEntryErr
155 TIFFReadDirEntryCheckRangeByteLong(uint32_t value);
156 static enum TIFFReadDirEntryErr
157 TIFFReadDirEntryCheckRangeByteSlong(int32_t value);
158 static enum TIFFReadDirEntryErr
159 TIFFReadDirEntryCheckRangeByteLong8(uint64_t value);
160 static enum TIFFReadDirEntryErr
161 TIFFReadDirEntryCheckRangeByteSlong8(int64_t value);
162 
163 static enum TIFFReadDirEntryErr
164 TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value);
165 static enum TIFFReadDirEntryErr
166 TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value);
167 static enum TIFFReadDirEntryErr
168 TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value);
169 static enum TIFFReadDirEntryErr
170 TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value);
171 static enum TIFFReadDirEntryErr
172 TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value);
173 static enum TIFFReadDirEntryErr
174 TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value);
175 static enum TIFFReadDirEntryErr
176 TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value);
177 
178 static enum TIFFReadDirEntryErr
179 TIFFReadDirEntryCheckRangeShortSbyte(int8_t value);
180 static enum TIFFReadDirEntryErr
181 TIFFReadDirEntryCheckRangeShortSshort(int16_t value);
182 static enum TIFFReadDirEntryErr
183 TIFFReadDirEntryCheckRangeShortLong(uint32_t value);
184 static enum TIFFReadDirEntryErr
185 TIFFReadDirEntryCheckRangeShortSlong(int32_t value);
186 static enum TIFFReadDirEntryErr
187 TIFFReadDirEntryCheckRangeShortLong8(uint64_t value);
188 static enum TIFFReadDirEntryErr
189 TIFFReadDirEntryCheckRangeShortSlong8(int64_t value);
190 
191 static enum TIFFReadDirEntryErr
192 TIFFReadDirEntryCheckRangeSshortShort(uint16_t value);
193 static enum TIFFReadDirEntryErr
194 TIFFReadDirEntryCheckRangeSshortLong(uint32_t value);
195 static enum TIFFReadDirEntryErr
196 TIFFReadDirEntryCheckRangeSshortSlong(int32_t value);
197 static enum TIFFReadDirEntryErr
198 TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value);
199 static enum TIFFReadDirEntryErr
200 TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value);
201 
202 static enum TIFFReadDirEntryErr
203 TIFFReadDirEntryCheckRangeLongSbyte(int8_t value);
204 static enum TIFFReadDirEntryErr
205 TIFFReadDirEntryCheckRangeLongSshort(int16_t value);
206 static enum TIFFReadDirEntryErr
207 TIFFReadDirEntryCheckRangeLongSlong(int32_t value);
208 static enum TIFFReadDirEntryErr
209 TIFFReadDirEntryCheckRangeLongLong8(uint64_t value);
210 static enum TIFFReadDirEntryErr
211 TIFFReadDirEntryCheckRangeLongSlong8(int64_t value);
212 
213 static enum TIFFReadDirEntryErr
214 TIFFReadDirEntryCheckRangeSlongLong(uint32_t value);
215 static enum TIFFReadDirEntryErr
216 TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value);
217 static enum TIFFReadDirEntryErr
218 TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value);
219 
220 static enum TIFFReadDirEntryErr
221 TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value);
222 static enum TIFFReadDirEntryErr
223 TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value);
224 static enum TIFFReadDirEntryErr
225 TIFFReadDirEntryCheckRangeLong8Slong(int32_t value);
226 static enum TIFFReadDirEntryErr
227 TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value);
228 
229 static enum TIFFReadDirEntryErr
230 TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value);
231 
232 static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
233                                                      tmsize_t size, void *dest);
234 static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
235                                       const char *module, const char *tagname,
236                                       int recover);
237 
238 static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
239                                         uint16_t dircount);
240 static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
241                                                 uint16_t dircount,
242                                                 uint16_t tagid);
243 static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
244                                            uint32_t *fii);
245 
246 static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir,
247                                    uint16_t dircount);
248 static void MissingRequired(TIFF *, const char *);
249 static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t);
250 static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
251                                    TIFFDirEntry **pdir, uint64_t *nextdiroff);
252 static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover);
253 static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
254                                uint64_t **lpp);
255 static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *);
256 static void ChopUpSingleUncompressedStrip(TIFF *);
257 static void TryChopUpUncompressedBigTiff(TIFF *);
258 static uint64_t TIFFReadUInt64(const uint8_t *value);
259 static int _TIFFGetMaxColorChannels(uint16_t photometric);
260 
261 static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount);
262 
263 typedef union _UInt64Aligned_t
264 {
265     double d;
266     uint64_t l;
267     uint32_t i[2];
268     uint16_t s[4];
269     uint8_t c[8];
270 } UInt64Aligned_t;
271 
272 /*
273   Unaligned safe copy of a uint64_t value from an octet array.
274 */
TIFFReadUInt64(const uint8_t * value)275 static uint64_t TIFFReadUInt64(const uint8_t *value)
276 {
277     UInt64Aligned_t result;
278 
279     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];
287 
288     return result.l;
289 }
290 
291 static enum TIFFReadDirEntryErr
TIFFReadDirEntryByte(TIFF * tif,TIFFDirEntry * direntry,uint8_t * value)292 TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value)
293 {
294     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     }
381 }
382 
383 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySbyte(TIFF * tif,TIFFDirEntry * direntry,int8_t * value)384 TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value)
385 {
386     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() --*/
476 
477 static enum TIFFReadDirEntryErr
TIFFReadDirEntryShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)478 TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value)
479 {
480     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() --*/
563 
564 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySshort(TIFF * tif,TIFFDirEntry * direntry,int16_t * value)565 TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value)
566 {
567     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() --*/
647 
648 static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong(TIFF * tif,TIFFDirEntry * direntry,uint32_t * value)649 TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value)
650 {
651     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 
732 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong(TIFF * tif,TIFFDirEntry * direntry,int32_t * value)733 TIFFReadDirEntrySlong(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 
810 static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)811 TIFFReadDirEntryLong8(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 
889 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong8(TIFF * tif,TIFFDirEntry * direntry,int64_t * value)890 TIFFReadDirEntrySlong8(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 
959 static enum TIFFReadDirEntryErr
TIFFReadDirEntryFloat(TIFF * tif,TIFFDirEntry * direntry,float * value)960 TIFFReadDirEntryFloat(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);
1015 #if defined(__WIN32__) && (_MSC_VER < 1500)
1016             /*
1017              * XXX: MSVC 6.0 does not support conversion
1018              * of 64-bit integers into floating point
1019              * values.
1020              */
1021             *value = _TIFFUInt64ToFloat(m);
1022 #else
1023             *value = (float)m;
1024 #endif
1025             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     }
1071 }
1072 
1073 static enum TIFFReadDirEntryErr
TIFFReadDirEntryDouble(TIFF * tif,TIFFDirEntry * direntry,double * value)1074 TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value)
1075 {
1076     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);
1129 #if defined(__WIN32__) && (_MSC_VER < 1500)
1130             /*
1131              * XXX: MSVC 6.0 does not support conversion
1132              * of 64-bit integers into floating point
1133              * values.
1134              */
1135             *value = _TIFFUInt64ToDouble(m);
1136 #else
1137             *value = (double)m;
1138 #endif
1139             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     }
1169 }
1170 
1171 static enum TIFFReadDirEntryErr
TIFFReadDirEntryIfd8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)1172 TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
1173 {
1174     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     }
1194 }
1195 
1196 #define INITIAL_THRESHOLD (1024 * 1024)
1197 #define THRESHOLD_MULTIPLIER 10
1198 #define MAX_THRESHOLD                                                          \
1199     (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER *      \
1200      INITIAL_THRESHOLD)
1201 
TIFFReadDirEntryDataAndRealloc(TIFF * tif,uint64_t offset,tmsize_t size,void ** pdest)1202 static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif,
1203                                                                uint64_t offset,
1204                                                                tmsize_t size,
1205                                                                void **pdest)
1206 {
1207 #if SIZEOF_SIZE_T == 8
1208     tmsize_t threshold = INITIAL_THRESHOLD;
1209 #endif
1210     tmsize_t already_read = 0;
1211 
1212     assert(!isMapped(tif));
1213 
1214     if (!SeekOK(tif, offset))
1215         return (TIFFReadDirEntryErrIo);
1216 
1217     /* 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;
1228 #if SIZEOF_SIZE_T == 8
1229         if (to_read >= threshold && threshold < MAX_THRESHOLD)
1230         {
1231             to_read = threshold;
1232             threshold *= THRESHOLD_MULTIPLIER;
1233         }
1234 #endif
1235 
1236         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;
1249 
1250         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 
1264 static enum TIFFReadDirEntryErr
TIFFReadDirEntryArrayWithLimit(TIFF * tif,TIFFDirEntry * direntry,uint32_t * count,uint32_t desttypesize,void ** value,uint64_t maxcount)1265 TIFFReadDirEntryArrayWithLimit(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);
1343             }
1344         }
1345     }
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);
1372 }
1373 
1374 static enum TIFFReadDirEntryErr
TIFFReadDirEntryArray(TIFF * tif,TIFFDirEntry * direntry,uint32_t * count,uint32_t desttypesize,void ** value)1375 TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count,
1376                       uint32_t desttypesize, void **value)
1377 {
1378     return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize,
1379                                           value, ~((uint64_t)0));
1380 }
1381 
1382 static enum TIFFReadDirEntryErr
TIFFReadDirEntryByteArray(TIFF * tif,TIFFDirEntry * direntry,uint8_t ** value)1383 TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value)
1384 {
1385     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);
1562 }
1563 
1564 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySbyteArray(TIFF * tif,TIFFDirEntry * direntry,int8_t ** value)1565 TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value)
1566 {
1567     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);
1742 }
1743 
1744 static enum TIFFReadDirEntryErr
TIFFReadDirEntryShortArray(TIFF * tif,TIFFDirEntry * direntry,uint16_t ** value)1745 TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value)
1746 {
1747     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);
1915 }
1916 
1917 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySshortArray(TIFF * tif,TIFFDirEntry * direntry,int16_t ** value)1918 TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value)
1919 {
1920     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);
2083 }
2084 
2085 static enum TIFFReadDirEntryErr
TIFFReadDirEntryLongArray(TIFF * tif,TIFFDirEntry * direntry,uint32_t ** value)2086 TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value)
2087 {
2088     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);
2253 }
2254 
2255 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlongArray(TIFF * tif,TIFFDirEntry * direntry,int32_t ** value)2256 TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value)
2257 {
2258     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);
2415 }
2416 
2417 static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8ArrayWithLimit(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value,uint64_t maxcount)2418 TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry,
2419                                     uint64_t **value, uint64_t maxcount)
2420 {
2421     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);
2584 }
2585 
2586 static enum TIFFReadDirEntryErr
TIFFReadDirEntryLong8Array(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value)2587 TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
2588 {
2589     return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value,
2590                                                ~((uint64_t)0));
2591 }
2592 
2593 static enum TIFFReadDirEntryErr
TIFFReadDirEntrySlong8Array(TIFF * tif,TIFFDirEntry * direntry,int64_t ** value)2594 TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value)
2595 {
2596     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);
2742 }
2743 
2744 static enum TIFFReadDirEntryErr
TIFFReadDirEntryFloatArray(TIFF * tif,TIFFDirEntry * direntry,float ** value)2745 TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
2746 {
2747     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);
2885 #if defined(__WIN32__) && (_MSC_VER < 1500)
2886                 /*
2887                  * XXX: MSVC 6.0 does not support
2888                  * conversion of 64-bit integers into
2889                  * floating point values.
2890                  */
2891                 *mb++ = _TIFFUInt64ToFloat(*ma++);
2892 #else
2893                 *mb++ = (float)(*ma++);
2894 #endif
2895             }
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);
2987 }
2988 
2989 static enum TIFFReadDirEntryErr
TIFFReadDirEntryDoubleArray(TIFF * tif,TIFFDirEntry * direntry,double ** value)2990 TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value)
2991 {
2992     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);
3130 #if defined(__WIN32__) && (_MSC_VER < 1500)
3131                 /*
3132                  * XXX: MSVC 6.0 does not support
3133                  * conversion of 64-bit integers into
3134                  * floating point values.
3135                  */
3136                 *mb++ = _TIFFUInt64ToDouble(*ma++);
3137 #else
3138                 *mb++ = (double)(*ma++);
3139 #endif
3140             }
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);
3225 }
3226 
3227 static enum TIFFReadDirEntryErr
TIFFReadDirEntryIfd8Array(TIFF * tif,TIFFDirEntry * direntry,uint64_t ** value)3228 TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value)
3229 {
3230     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);
3287 }
3288 
3289 static enum TIFFReadDirEntryErr
TIFFReadDirEntryPersampleShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)3290 TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry,
3291                                uint16_t *value)
3292 {
3293     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 
TIFFReadDirEntryCheckedByte(TIFF * tif,TIFFDirEntry * direntry,uint8_t * value)3319 static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry,
3320                                         uint8_t *value)
3321 {
3322     (void)tif;
3323     *value = *(uint8_t *)(&direntry->tdir_offset);
3324 }
3325 
TIFFReadDirEntryCheckedSbyte(TIFF * tif,TIFFDirEntry * direntry,int8_t * value)3326 static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry,
3327                                          int8_t *value)
3328 {
3329     (void)tif;
3330     *value = *(int8_t *)(&direntry->tdir_offset);
3331 }
3332 
TIFFReadDirEntryCheckedShort(TIFF * tif,TIFFDirEntry * direntry,uint16_t * value)3333 static 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 
TIFFReadDirEntryCheckedSshort(TIFF * tif,TIFFDirEntry * direntry,int16_t * value)3342 static 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 
TIFFReadDirEntryCheckedLong(TIFF * tif,TIFFDirEntry * direntry,uint32_t * value)3350 static 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 
TIFFReadDirEntryCheckedSlong(TIFF * tif,TIFFDirEntry * direntry,int32_t * value)3358 static 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);
3364 }
3365 
3366 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedLong8(TIFF * tif,TIFFDirEntry * direntry,uint64_t * value)3367 TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value)
3368 {
3369     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 
3386 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedSlong8(TIFF * tif,TIFFDirEntry * direntry,int64_t * value)3387 TIFFReadDirEntryCheckedSlong8(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 
3406 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedRational(TIFF * tif,TIFFDirEntry * direntry,double * value)3407 TIFFReadDirEntryCheckedRational(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 
3439 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedSrational(TIFF * tif,TIFFDirEntry * direntry,double * value)3440 TIFFReadDirEntryCheckedSrational(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 
TIFFReadDirEntryCheckedFloat(TIFF * tif,TIFFDirEntry * direntry,float * value)3472 static 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 
3489 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckedDouble(TIFF * tif,TIFFDirEntry * direntry,double * value)3490 TIFFReadDirEntryCheckedDouble(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 
3516 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)3517 TIFFReadDirEntryCheckRangeByteSbyte(int8_t value)
3518 {
3519     if (value < 0)
3520         return (TIFFReadDirEntryErrRange);
3521     else
3522         return (TIFFReadDirEntryErrOk);
3523 }
3524 
3525 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteShort(uint16_t value)3526 TIFFReadDirEntryCheckRangeByteShort(uint16_t value)
3527 {
3528     if (value > 0xFF)
3529         return (TIFFReadDirEntryErrRange);
3530     else
3531         return (TIFFReadDirEntryErrOk);
3532 }
3533 
3534 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSshort(int16_t value)3535 TIFFReadDirEntryCheckRangeByteSshort(int16_t value)
3536 {
3537     if ((value < 0) || (value > 0xFF))
3538         return (TIFFReadDirEntryErrRange);
3539     else
3540         return (TIFFReadDirEntryErrOk);
3541 }
3542 
3543 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteLong(uint32_t value)3544 TIFFReadDirEntryCheckRangeByteLong(uint32_t value)
3545 {
3546     if (value > 0xFF)
3547         return (TIFFReadDirEntryErrRange);
3548     else
3549         return (TIFFReadDirEntryErrOk);
3550 }
3551 
3552 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSlong(int32_t value)3553 TIFFReadDirEntryCheckRangeByteSlong(int32_t value)
3554 {
3555     if ((value < 0) || (value > 0xFF))
3556         return (TIFFReadDirEntryErrRange);
3557     else
3558         return (TIFFReadDirEntryErrOk);
3559 }
3560 
3561 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)3562 TIFFReadDirEntryCheckRangeByteLong8(uint64_t value)
3563 {
3564     if (value > 0xFF)
3565         return (TIFFReadDirEntryErrRange);
3566     else
3567         return (TIFFReadDirEntryErrOk);
3568 }
3569 
3570 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)3571 TIFFReadDirEntryCheckRangeByteSlong8(int64_t value)
3572 {
3573     if ((value < 0) || (value > 0xFF))
3574         return (TIFFReadDirEntryErrRange);
3575     else
3576         return (TIFFReadDirEntryErrOk);
3577 }
3578 
3579 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)3580 TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value)
3581 {
3582     if (value > 0x7F)
3583         return (TIFFReadDirEntryErrRange);
3584     else
3585         return (TIFFReadDirEntryErrOk);
3586 }
3587 
3588 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)3589 TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value)
3590 {
3591     if (value > 0x7F)
3592         return (TIFFReadDirEntryErrRange);
3593     else
3594         return (TIFFReadDirEntryErrOk);
3595 }
3596 
3597 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)3598 TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value)
3599 {
3600     if ((value < -0x80) || (value > 0x7F))
3601         return (TIFFReadDirEntryErrRange);
3602     else
3603         return (TIFFReadDirEntryErrOk);
3604 }
3605 
3606 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)3607 TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value)
3608 {
3609     if (value > 0x7F)
3610         return (TIFFReadDirEntryErrRange);
3611     else
3612         return (TIFFReadDirEntryErrOk);
3613 }
3614 
3615 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)3616 TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value)
3617 {
3618     if ((value < -0x80) || (value > 0x7F))
3619         return (TIFFReadDirEntryErrRange);
3620     else
3621         return (TIFFReadDirEntryErrOk);
3622 }
3623 
3624 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)3625 TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value)
3626 {
3627     if (value > 0x7F)
3628         return (TIFFReadDirEntryErrRange);
3629     else
3630         return (TIFFReadDirEntryErrOk);
3631 }
3632 
3633 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)3634 TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value)
3635 {
3636     if ((value < -0x80) || (value > 0x7F))
3637         return (TIFFReadDirEntryErrRange);
3638     else
3639         return (TIFFReadDirEntryErrOk);
3640 }
3641 
3642 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)3643 TIFFReadDirEntryCheckRangeShortSbyte(int8_t value)
3644 {
3645     if (value < 0)
3646         return (TIFFReadDirEntryErrRange);
3647     else
3648         return (TIFFReadDirEntryErrOk);
3649 }
3650 
3651 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSshort(int16_t value)3652 TIFFReadDirEntryCheckRangeShortSshort(int16_t value)
3653 {
3654     if (value < 0)
3655         return (TIFFReadDirEntryErrRange);
3656     else
3657         return (TIFFReadDirEntryErrOk);
3658 }
3659 
3660 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortLong(uint32_t value)3661 TIFFReadDirEntryCheckRangeShortLong(uint32_t value)
3662 {
3663     if (value > 0xFFFF)
3664         return (TIFFReadDirEntryErrRange);
3665     else
3666         return (TIFFReadDirEntryErrOk);
3667 }
3668 
3669 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSlong(int32_t value)3670 TIFFReadDirEntryCheckRangeShortSlong(int32_t value)
3671 {
3672     if ((value < 0) || (value > 0xFFFF))
3673         return (TIFFReadDirEntryErrRange);
3674     else
3675         return (TIFFReadDirEntryErrOk);
3676 }
3677 
3678 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)3679 TIFFReadDirEntryCheckRangeShortLong8(uint64_t value)
3680 {
3681     if (value > 0xFFFF)
3682         return (TIFFReadDirEntryErrRange);
3683     else
3684         return (TIFFReadDirEntryErrOk);
3685 }
3686 
3687 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)3688 TIFFReadDirEntryCheckRangeShortSlong8(int64_t value)
3689 {
3690     if ((value < 0) || (value > 0xFFFF))
3691         return (TIFFReadDirEntryErrRange);
3692     else
3693         return (TIFFReadDirEntryErrOk);
3694 }
3695 
3696 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)3697 TIFFReadDirEntryCheckRangeSshortShort(uint16_t value)
3698 {
3699     if (value > 0x7FFF)
3700         return (TIFFReadDirEntryErrRange);
3701     else
3702         return (TIFFReadDirEntryErrOk);
3703 }
3704 
3705 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)3706 TIFFReadDirEntryCheckRangeSshortLong(uint32_t value)
3707 {
3708     if (value > 0x7FFF)
3709         return (TIFFReadDirEntryErrRange);
3710     else
3711         return (TIFFReadDirEntryErrOk);
3712 }
3713 
3714 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)3715 TIFFReadDirEntryCheckRangeSshortSlong(int32_t value)
3716 {
3717     if ((value < -0x8000) || (value > 0x7FFF))
3718         return (TIFFReadDirEntryErrRange);
3719     else
3720         return (TIFFReadDirEntryErrOk);
3721 }
3722 
3723 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)3724 TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value)
3725 {
3726     if (value > 0x7FFF)
3727         return (TIFFReadDirEntryErrRange);
3728     else
3729         return (TIFFReadDirEntryErrOk);
3730 }
3731 
3732 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)3733 TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value)
3734 {
3735     if ((value < -0x8000) || (value > 0x7FFF))
3736         return (TIFFReadDirEntryErrRange);
3737     else
3738         return (TIFFReadDirEntryErrOk);
3739 }
3740 
3741 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)3742 TIFFReadDirEntryCheckRangeLongSbyte(int8_t value)
3743 {
3744     if (value < 0)
3745         return (TIFFReadDirEntryErrRange);
3746     else
3747         return (TIFFReadDirEntryErrOk);
3748 }
3749 
3750 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSshort(int16_t value)3751 TIFFReadDirEntryCheckRangeLongSshort(int16_t value)
3752 {
3753     if (value < 0)
3754         return (TIFFReadDirEntryErrRange);
3755     else
3756         return (TIFFReadDirEntryErrOk);
3757 }
3758 
3759 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong(int32_t value)3760 TIFFReadDirEntryCheckRangeLongSlong(int32_t value)
3761 {
3762     if (value < 0)
3763         return (TIFFReadDirEntryErrRange);
3764     else
3765         return (TIFFReadDirEntryErrOk);
3766 }
3767 
3768 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)3769 TIFFReadDirEntryCheckRangeLongLong8(uint64_t value)
3770 {
3771     if (value > UINT32_MAX)
3772         return (TIFFReadDirEntryErrRange);
3773     else
3774         return (TIFFReadDirEntryErrOk);
3775 }
3776 
3777 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)3778 TIFFReadDirEntryCheckRangeLongSlong8(int64_t value)
3779 {
3780     if ((value < 0) || (value > (int64_t)UINT32_MAX))
3781         return (TIFFReadDirEntryErrRange);
3782     else
3783         return (TIFFReadDirEntryErrOk);
3784 }
3785 
3786 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)3787 TIFFReadDirEntryCheckRangeSlongLong(uint32_t value)
3788 {
3789     if (value > 0x7FFFFFFFUL)
3790         return (TIFFReadDirEntryErrRange);
3791     else
3792         return (TIFFReadDirEntryErrOk);
3793 }
3794 
3795 /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
3796 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)3797 TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value)
3798 {
3799     if (value > 0x7FFFFFFF)
3800         return (TIFFReadDirEntryErrRange);
3801     else
3802         return (TIFFReadDirEntryErrOk);
3803 }
3804 
3805 /* Check that the 8-byte signed value can fit in a 4-byte signed range */
3806 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)3807 TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value)
3808 {
3809     if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF))
3810         return (TIFFReadDirEntryErrRange);
3811     else
3812         return (TIFFReadDirEntryErrOk);
3813 }
3814 
3815 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)3816 TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value)
3817 {
3818     if (value < 0)
3819         return (TIFFReadDirEntryErrRange);
3820     else
3821         return (TIFFReadDirEntryErrOk);
3822 }
3823 
3824 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)3825 TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value)
3826 {
3827     if (value < 0)
3828         return (TIFFReadDirEntryErrRange);
3829     else
3830         return (TIFFReadDirEntryErrOk);
3831 }
3832 
3833 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)3834 TIFFReadDirEntryCheckRangeLong8Slong(int32_t value)
3835 {
3836     if (value < 0)
3837         return (TIFFReadDirEntryErrRange);
3838     else
3839         return (TIFFReadDirEntryErrOk);
3840 }
3841 
3842 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)3843 TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value)
3844 {
3845     if (value < 0)
3846         return (TIFFReadDirEntryErrRange);
3847     else
3848         return (TIFFReadDirEntryErrOk);
3849 }
3850 
3851 static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)3852 TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value)
3853 {
3854     if (value > INT64_MAX)
3855         return (TIFFReadDirEntryErrRange);
3856     else
3857         return (TIFFReadDirEntryErrOk);
3858 }
3859 
TIFFReadDirEntryData(TIFF * tif,uint64_t offset,tmsize_t size,void * dest)3860 static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset,
3861                                                      tmsize_t size, void *dest)
3862 {
3863     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);
3885 }
3886 
TIFFReadDirEntryOutputErr(TIFF * tif,enum TIFFReadDirEntryErr err,const char * module,const char * tagname,int recover)3887 static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err,
3888                                       const char *module, const char *tagname,
3889                                       int recover)
3890 {
3891     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     }
3977 }
3978 
3979 /*
3980  * 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  */
_TIFFGetMaxColorChannels(uint16_t photometric)3984 static int _TIFFGetMaxColorChannels(uint16_t photometric)
3985 {
3986     switch (photometric)
3987     {
3988         case PHOTOMETRIC_PALETTE:
3989         case PHOTOMETRIC_MINISWHITE:
3990         case PHOTOMETRIC_MINISBLACK:
3991             return 1;
3992         case PHOTOMETRIC_YCBCR:
3993         case PHOTOMETRIC_RGB:
3994         case PHOTOMETRIC_CIELAB:
3995         case PHOTOMETRIC_LOGLUV:
3996         case PHOTOMETRIC_ITULAB:
3997         case PHOTOMETRIC_ICCLAB:
3998             return 3;
3999         case PHOTOMETRIC_SEPARATED:
4000         case PHOTOMETRIC_MASK:
4001             return 4;
4002         case PHOTOMETRIC_LOGL:
4003         case PHOTOMETRIC_CFA:
4004         default:
4005             return 0;
4006     }
4007 }
4008 
ByteCountLooksBad(TIFF * tif)4009 static int ByteCountLooksBad(TIFF *tif)
4010 {
4011     /*
4012      * 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;
4027 
4028     if (offset == 0)
4029         return 0;
4030     if (bytecount == 0)
4031         return 1;
4032     if (tif->tif_dir.td_compression != COMPRESSION_NONE)
4033         return 0;
4034     filesize = TIFFGetFileSize(tif);
4035     if (offset <= filesize && bytecount > filesize - offset)
4036         return 1;
4037     if (tif->tif_mode == O_RDONLY)
4038     {
4039         uint64_t scanlinesize = TIFFScanlineSize64(tif);
4040         if (tif->tif_dir.td_imagelength > 0 &&
4041             scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength)
4042         {
4043             return 1;
4044         }
4045         if (bytecount < scanlinesize * tif->tif_dir.td_imagelength)
4046             return 1;
4047     }
4048     return 0;
4049 }
4050 
4051 /*
4052  * Read the next TIFF directory from a file and convert it to the internal
4053  * format. We read directories sequentially.
4054  */
TIFFReadDirectory(TIFF * tif)4055 int TIFFReadDirectory(TIFF *tif)
4056 {
4057     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;
4065     int bitspersample_read = FALSE;
4066     int color_channels;
4067 
4068     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     }
4074 
4075     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     {
4173         /*
4174          * 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.
4178          */
4179         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     }
4306 
4307     /*
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     {
4643 #ifdef OJPEG_SUPPORT
4644         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
4658 #endif
4659         {
4660             MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets");
4661             goto bad;
4662         }
4663     }
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)
4681         {
4682             if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry),
4683                                      tif->tif_dir.td_nstrips,
4684                                      &tif->tif_dir.td_stripoffset_p))
4685             {
4686                 goto bad;
4687             }
4688         }
4689         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     }
4699 
4700     /*
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;
4711 
4712         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.");
4717 
4718         old_extrasamples = tif->tif_dir.td_extrasamples;
4719         tif->tif_dir.td_extrasamples =
4720             (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels);
4721 
4722         // 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;
4734         }
4735 
4736         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     }
4743 
4744     /*
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     }
4848 
4849 #ifdef STRIPBYTECOUNTSORTED_UNUSED
4850     /*
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;
4858 
4859         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     }
4870 #endif
4871 
4872     /*
4873      * An opportunity for compression mode dependent tag fixup
4874      */
4875     (*tif->tif_fixuptags)(tif);
4876 
4877     /*
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)
4931         {
4932             TIFFErrorExtR(tif, module, "Cannot handle zero tile size");
4933             return (0);
4934         }
4935     }
4936     else
4937     {
4938         if (!TIFFStripSize(tif))
4939         {
4940             TIFFErrorExtR(tif, module, "Cannot handle zero strip size");
4941             return (0);
4942         }
4943     }
4944     return (1);
4945 bad:
4946     if (dir)
4947         _TIFFfreeExt(tif, dir);
4948     return (0);
4949 }
4950 
TIFFReadDirectoryCheckOrder(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount)4951 static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir,
4952                                         uint16_t dircount)
4953 {
4954     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     }
4970 }
4971 
TIFFReadDirectoryFindEntry(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount,uint16_t tagid)4972 static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir,
4973                                                 uint16_t dircount,
4974                                                 uint16_t tagid)
4975 {
4976     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);
4985 }
4986 
TIFFReadDirectoryFindFieldInfo(TIFF * tif,uint16_t tagid,uint32_t * fii)4987 static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid,
4988                                            uint32_t *fii)
4989 {
4990     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;
5017 }
5018 
5019 /*
5020  * Read custom directory from the arbitrary offset.
5021  * The code is very similar to TIFFReadDirectory().
5022  */
TIFFReadCustomDirectory(TIFF * tif,toff_t diroff,const TIFFFieldArray * infoarray)5023 int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
5024                             const TIFFFieldArray *infoarray)
5025 {
5026     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;
5145 }
5146 
5147 /*
5148  * EXIF is important special case of custom IFD, so we have a special
5149  * function to read it.
5150  */
TIFFReadEXIFDirectory(TIFF * tif,toff_t diroff)5151 int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff)
5152 {
5153     const TIFFFieldArray *exifFieldArray;
5154     exifFieldArray = _TIFFGetExifFields();
5155     return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
5156 }
5157 
5158 /*
5159  *--: EXIF-GPS custom directory reading as another special case of custom IFD.
5160  */
TIFFReadGPSDirectory(TIFF * tif,toff_t diroff)5161 int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff)
5162 {
5163     const TIFFFieldArray *gpsFieldArray;
5164     gpsFieldArray = _TIFFGetGpsFields();
5165     return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
5166 }
5167 
EstimateStripByteCounts(TIFF * tif,TIFFDirEntry * dir,uint16_t dircount)5168 static 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 
MissingRequired(TIFF * tif,const char * tagname)5288 static 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 
hashFuncOffsetToNumber(const void * elt)5296 static 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 
equalFuncOffsetToNumber(const void * elt1,const void * elt2)5305 static 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 
hashFuncNumberToOffset(const void * elt)5314 static unsigned long hashFuncNumberToOffset(const void *elt)
5315 {
5316     const TIFFOffsetAndDirNumber *offsetAndDirNumber =
5317         (const TIFFOffsetAndDirNumber *)elt;
5318     return offsetAndDirNumber->dirNumber;
5319 }
5320 
equalFuncNumberToOffset(const void * elt1,const void * elt2)5321 static 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  */
_TIFFCheckDirNumberAndOffset(TIFF * tif,tdir_t dirn,uint64_t diroff)5340 int _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  */
_TIFFGetDirNumberFromOffset(TIFF * tif,uint64_t diroff,tdir_t * dirn)5504 int _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 
5548 /*
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  */
CheckDirCount(TIFF * tif,TIFFDirEntry * dir,uint32_t count)5552 static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count)
5553 {
5554     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);
5576 }
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  */
TIFFFetchDirectory(TIFF * tif,uint64_t diroff,TIFFDirEntry ** pdir,uint64_t * nextdiroff)5583 static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff,
5584                                    TIFFDirEntry **pdir, uint64_t *nextdiroff)
5585 {
5586     static const char module[] = "TIFFFetchDirectory";
5587 
5588     void *origdir;
5589     uint16_t dircount16;
5590     uint32_t dirsize;
5591     TIFFDirEntry *dir;
5592     uint8_t *ma;
5593     TIFFDirEntry *mb;
5594     uint16_t n;
5595 
5596     assert(pdir);
5597 
5598     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;
5697 
5698         /*
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;
5857 }
5858 
5859 /*
5860  * Fetch a tag that is not handled by special case code.
5861  */
TIFFFetchNormalTag(TIFF * tif,TIFFDirEntry * dp,int recover)5862 static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
5863 {
5864     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:
5894         {
5895             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             }
5964         }
5965         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);
6971 }
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  */
TIFFFetchStripThing(TIFF * tif,TIFFDirEntry * dir,uint32_t nstrips,uint64_t ** lpp)6977 static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips,
6978                                uint64_t **lpp)
6979 {
6980     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));
7002 
7003         if (nstrips > max_nstrips)
7004         {
7005             _TIFFfreeExt(tif, data);
7006             return (0);
7007         }
7008 
7009         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);
7026 }
7027 
7028 /*
7029  * Fetch and set the SubjectDistance EXIF tag.
7030  */
TIFFFetchSubjectDistance(TIFF * tif,TIFFDirEntry * dir)7031 static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir)
7032 {
7033     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     }
7083 }
7084 
allocChoppedUpStripArrays(TIFF * tif,uint32_t nstrips,uint64_t stripbytes,uint32_t rowsperstrip)7085 static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips,
7086                                       uint64_t stripbytes,
7087                                       uint32_t rowsperstrip)
7088 {
7089     TIFFDirectory *td = &tif->tif_dir;
7090     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;
7097 
7098     offset = TIFFGetStrileOffset(tif, 0);
7099     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)
7103     {
7104         return;
7105     }
7106     bytecount = last_offset + last_bytecount - offset;
7107 
7108     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     {
7115         /*
7116          * Unable to allocate new strip information, give up and use
7117          * the original one strip information.
7118          */
7119         if (newcounts != NULL)
7120             _TIFFfreeExt(tif, newcounts);
7121         if (newoffsets != NULL)
7122             _TIFFfreeExt(tif, newoffsets);
7123         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 
7146     _TIFFfreeExt(tif, td->td_stripbytecount_p);
7147     _TIFFfreeExt(tif, td->td_stripoffset_p);
7148     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 
7156 /*
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  */
ChopUpSingleUncompressedStrip(TIFF * tif)7162 static void ChopUpSingleUncompressedStrip(TIFF *tif)
7163 {
7164     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;
7172 
7173     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;
7204 
7205     /*
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;
7213 
7214     /* 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     }
7222 
7223     allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
7224 }
7225 
7226 /*
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  */
TryChopUpUncompressedBigTiff(TIFF * tif)7232 static void TryChopUpUncompressedBigTiff(TIFF *tif)
7233 {
7234     TIFFDirectory *td = &tif->tif_dir;
7235     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;
7243 
7244     stripsize = TIFFStripSize64(tif);
7245 
7246     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);
7251 
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) . */
7255     if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY)
7256         return;
7257 
7258     if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif)))
7259         rowblock = td->td_ycbcrsubsampling[1];
7260     else
7261         rowblock = 1;
7262     rowblockbytes = TIFFVStripSize64(tif, rowblock);
7263     if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL)
7264     {
7265         /* In case of file with gigantic width */
7266         return;
7267     }
7268 
7269     /* Check that the strips are contiguous and of the expected size */
7270     for (i = 0; i < td->td_nstrips; i++)
7271     {
7272         if (i == td->td_nstrips - 1)
7273         {
7274             if (TIFFGetStrileByteCount(tif, i) <
7275                 TIFFVStripSize64(tif,
7276                                  td->td_imagelength - i * td->td_rowsperstrip))
7277             {
7278                 return;
7279             }
7280         }
7281         else
7282         {
7283             if (TIFFGetStrileByteCount(tif, i) != stripsize)
7284             {
7285                 return;
7286             }
7287             if (i > 0 && TIFFGetStrileOffset(tif, i) !=
7288                              TIFFGetStrileOffset(tif, i - 1) +
7289                                  TIFFGetStrileByteCount(tif, i - 1))
7290             {
7291                 return;
7292             }
7293         }
7294     }
7295 
7296     /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
7297     rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes);
7298     if (rowblocksperstrip == 0)
7299         rowblocksperstrip = 1;
7300     rowsperstrip = rowblocksperstrip * rowblock;
7301     stripbytes = rowblocksperstrip * rowblockbytes;
7302     assert(stripbytes <= 0x7FFFFFFFUL);
7303 
7304     nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
7305     if (nstrips == 0)
7306         return;
7307 
7308     /* If we are going to allocate a lot of memory, make sure that the */
7309     /* file is as big as needed */
7310     if (tif->tif_mode == O_RDONLY && nstrips > 1000000)
7311     {
7312         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)
7317         {
7318             return;
7319         }
7320     }
7321 
7322     allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
7323 }
7324 
7325 TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
_TIFFUnsanitizedAddUInt64AndInt(uint64_t a,int b)7326 static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b)
7327 {
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  */
_TIFFPartialReadStripArray(TIFF * tif,TIFFDirEntry * dirent,int strile,uint64_t * panVals)7335 static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent,
7336                                       int strile, uint64_t *panVals)
7337 {
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;
7344     uint64_t nBaseOffset;
7345     uint64_t nOffset;
7346     uint64_t nOffsetStartPage;
7347     uint64_t nOffsetEndPage;
7348     tmsize_t nToRead;
7349     tmsize_t nRead;
7350     uint64_t nLastStripOffset;
7351     int iStartBefore;
7352     int i;
7353     const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
7354     unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
7355 
7356     assert(dirent->tdir_count > 4);
7357 
7358     if (dirent->tdir_type == TIFF_SHORT)
7359     {
7360         sizeofval = sizeof(uint16_t);
7361     }
7362     else if (dirent->tdir_type == TIFF_LONG)
7363     {
7364         sizeofval = sizeof(uint32_t);
7365     }
7366     else if (dirent->tdir_type == TIFF_LONG8)
7367     {
7368         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);
7375     }
7376     else
7377     {
7378         TIFFErrorExtR(tif, module,
7379                       "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
7380         panVals[strile] = 0;
7381         return 0;
7382     }
7383     sizeofvalint = (int)(sizeofval);
7384 
7385     if (tif->tif_flags & TIFF_BIGTIFF)
7386     {
7387         uint64_t offset = dirent->tdir_offset.toff_long8;
7388         if (bSwab)
7389             TIFFSwabLong8(&offset);
7390         nBaseOffset = offset;
7391     }
7392     else
7393     {
7394         uint32_t offset = dirent->tdir_offset.toff_long;
7395         if (bSwab)
7396             TIFFSwabLong(&offset);
7397         nBaseOffset = offset;
7398     }
7399     /* To avoid later unsigned integer overflows */
7400     if (nBaseOffset > (uint64_t)INT64_MAX)
7401     {
7402         TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7403                       strile);
7404         panVals[strile] = 0;
7405         return 0;
7406     }
7407     nOffset = nBaseOffset + sizeofval * strile;
7408     nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
7409     nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
7410 
7411     if (nOffset + sizeofval > nOffsetEndPage)
7412         nOffsetEndPage += IO_CACHE_PAGE_SIZE;
7413 #undef IO_CACHE_PAGE_SIZE
7414 
7415     nLastStripOffset = nBaseOffset + arraySize * sizeofval;
7416     if (nLastStripOffset < nOffsetEndPage)
7417         nOffsetEndPage = nLastStripOffset;
7418     if (nOffsetStartPage >= nOffsetEndPage)
7419     {
7420         TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d",
7421                       strile);
7422         panVals[strile] = 0;
7423         return 0;
7424     }
7425     if (!SeekOK(tif, nOffsetStartPage))
7426     {
7427         panVals[strile] = 0;
7428         return 0;
7429     }
7430 
7431     nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
7432     nRead = TIFFReadFile(tif, buffer, nToRead);
7433     if (nRead < nToRead)
7434     {
7435         TIFFErrorExtR(tif, module,
7436                       "Cannot read offset/size for strile around ~%d", strile);
7437         return 0;
7438     }
7439     iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
7440     if (strile + iStartBefore < 0)
7441         iStartBefore = -strile;
7442     for (i = iStartBefore;
7443          (uint32_t)(strile + i) < arraySize &&
7444          _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <=
7445              nOffsetEndPage;
7446          ++i)
7447     {
7448         if (dirent->tdir_type == TIFF_SHORT)
7449         {
7450             uint16_t val;
7451             memcpy(&val,
7452                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7453                    sizeof(val));
7454             if (bSwab)
7455                 TIFFSwabShort(&val);
7456             panVals[strile + i] = val;
7457         }
7458         else if (dirent->tdir_type == TIFF_LONG)
7459         {
7460             uint32_t val;
7461             memcpy(&val,
7462                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7463                    sizeof(val));
7464             if (bSwab)
7465                 TIFFSwabLong(&val);
7466             panVals[strile + i] = val;
7467         }
7468         else if (dirent->tdir_type == TIFF_LONG8)
7469         {
7470             uint64_t val;
7471             memcpy(&val,
7472                    buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
7473                    sizeof(val));
7474             if (bSwab)
7475                 TIFFSwabLong8(&val);
7476             panVals[strile + i] = val;
7477         }
7478         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         }
7489     }
7490     return 1;
7491 }
7492 
_TIFFFetchStrileValue(TIFF * tif,uint32_t strile,TIFFDirEntry * dirent,uint64_t ** parray)7493 static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile,
7494                                  TIFFDirEntry *dirent, uint64_t **parray)
7495 {
7496     static const char module[] = "_TIFFFetchStrileValue";
7497     TIFFDirectory *td = &tif->tif_dir;
7498     if (strile >= dirent->tdir_count)
7499     {
7500         return 0;
7501     }
7502     if (strile >= td->td_stripoffsetbyteallocsize)
7503     {
7504         uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
7505         uint32_t nStripArrayAllocNew;
7506         uint64_t nArraySize64;
7507         size_t nArraySize;
7508         uint64_t *offsetArray;
7509         uint64_t *bytecountArray;
7510 
7511         if (strile > 1000000)
7512         {
7513             uint64_t filesize = TIFFGetFileSize(tif);
7514             /* 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. */
7517             if (strile > filesize / sizeof(uint32_t))
7518             {
7519                 TIFFErrorExtR(tif, module, "File too short");
7520                 return 0;
7521             }
7522         }
7523 
7524         if (td->td_stripoffsetbyteallocsize == 0 &&
7525             td->td_nstrips < 1024 * 1024)
7526         {
7527             nStripArrayAllocNew = td->td_nstrips;
7528         }
7529         else
7530         {
7531 #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)
7535                 nStripArrayAllocNew *= 2;
7536             nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
7537         }
7538         assert(strile < nStripArrayAllocNew);
7539         nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew;
7540         nArraySize = (size_t)(nArraySize64);
7541 #if SIZEOF_SIZE_T == 4
7542         if (nArraySize != nArraySize64)
7543         {
7544             TIFFErrorExtR(tif, module,
7545                           "Cannot allocate strip offset and bytecount arrays");
7546             return 0;
7547         }
7548 #endif
7549         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)
7554             td->td_stripoffset_p = offsetArray;
7555         if (bytecountArray)
7556             td->td_stripbytecount_p = bytecountArray;
7557         if (offsetArray && bytecountArray)
7558         {
7559             td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
7560             /* Initialize new entries to ~0 / -1 */
7561             /* 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));
7569         }
7570         else
7571         {
7572             TIFFErrorExtR(tif, module,
7573                           "Cannot allocate strip offset and bytecount arrays");
7574             _TIFFfreeExt(tif, td->td_stripoffset_p);
7575             td->td_stripoffset_p = NULL;
7576             _TIFFfreeExt(tif, td->td_stripbytecount_p);
7577             td->td_stripbytecount_p = NULL;
7578             td->td_stripoffsetbyteallocsize = 0;
7579         }
7580     }
7581     if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize)
7582         return 0;
7583 
7584     if (~((*parray)[strile]) == 0)
7585     {
7586         if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray))
7587         {
7588             (*parray)[strile] = 0;
7589             return 0;
7590         }
7591     }
7592 
7593     return 1;
7594 }
7595 
_TIFFGetStrileOffsetOrByteCountValue(TIFF * tif,uint32_t strile,TIFFDirEntry * dirent,uint64_t ** parray,int * pbErr)7596 static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile,
7597                                                      TIFFDirEntry *dirent,
7598                                                      uint64_t **parray,
7599                                                      int *pbErr)
7600 {
7601     TIFFDirectory *td = &tif->tif_dir;
7602     if (pbErr)
7603         *pbErr = 0;
7604     if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) &&
7605         !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS))
7606     {
7607         if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) ||
7608             /* If the values may fit in the toff_long/toff_long8 member */
7609             /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
7610             dirent->tdir_count <= 4)
7611         {
7612             if (!_TIFFFillStriles(tif))
7613             {
7614                 if (pbErr)
7615                     *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         {
7623             if (!_TIFFFetchStrileValue(tif, strile, dirent, parray))
7624             {
7625                 if (pbErr)
7626                     *pbErr = 1;
7627                 return 0;
7628             }
7629         }
7630     }
7631     if (*parray == NULL || strile >= td->td_nstrips)
7632     {
7633         if (pbErr)
7634             *pbErr = 1;
7635         return 0;
7636     }
7637     return (*parray)[strile];
7638 }
7639 
7640 /* Return the value of the TileOffsets/StripOffsets array for the specified
7641  * tile/strile */
TIFFGetStrileOffset(TIFF * tif,uint32_t strile)7642 uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile)
7643 {
7644     return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
7645 }
7646 
7647 /* Return the value of the TileOffsets/StripOffsets array for the specified
7648  * tile/strile */
TIFFGetStrileOffsetWithErr(TIFF * tif,uint32_t strile,int * pbErr)7649 uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr)
7650 {
7651     TIFFDirectory *td = &tif->tif_dir;
7652     return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
7653                                                 &(td->td_stripoffset_entry),
7654                                                 &(td->td_stripoffset_p), pbErr);
7655 }
7656 
7657 /* Return the value of the TileByteCounts/StripByteCounts array for the
7658  * specified tile/strile */
TIFFGetStrileByteCount(TIFF * tif,uint32_t strile)7659 uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile)
7660 {
7661     return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
7662 }
7663 
7664 /* Return the value of the TileByteCounts/StripByteCounts array for the
7665  * specified tile/strile */
TIFFGetStrileByteCountWithErr(TIFF * tif,uint32_t strile,int * pbErr)7666 uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr)
7667 {
7668     TIFFDirectory *td = &tif->tif_dir;
7669     return _TIFFGetStrileOffsetOrByteCountValue(
7670         tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p),
7671         pbErr);
7672 }
7673 
_TIFFFillStriles(TIFF * tif)7674 int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); }
7675 
_TIFFFillStrilesInternal(TIFF * tif,int loadStripByteCount)7676 static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount)
7677 {
7678     register TIFFDirectory *td = &tif->tif_dir;
7679     int return_value = 1;
7680 
7681     /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
7682     if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) ||
7683         (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0)
7684         return 1;
7685 
7686     if (tif->tif_flags & TIFF_LAZYSTRILELOAD)
7687     {
7688         /* In case of lazy loading, reload completely the arrays */
7689         _TIFFfreeExt(tif, td->td_stripoffset_p);
7690         _TIFFfreeExt(tif, td->td_stripbytecount_p);
7691         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 */
7698     if (td->td_stripoffset_p != NULL)
7699         return 1;
7700 
7701     /* 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;
7704 
7705     if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips,
7706                              &td->td_stripoffset_p))
7707     {
7708         return_value = 0;
7709     }
7710 
7711     if (loadStripByteCount &&
7712         !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry),
7713                              td->td_nstrips, &td->td_stripbytecount_p))
7714     {
7715         return_value = 0;
7716     }
7717 
7718     _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
7719     _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
7720 
7721 #ifdef STRIPBYTECOUNTSORTED_UNUSED
7722     if (tif->tif_dir.td_nstrips > 1 && return_value == 1)
7723     {
7724         uint32_t strip;
7725 
7726         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;
7734             }
7735         }
7736     }
7737 #endif
7738 
7739     return return_value;
7740 }
7741