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