summaryrefslogtreecommitdiff
path: root/third_party/libtiff/0019-oom-TIFFReadDirEntryArray.patch
blob: 1144e06ef4ad7bf928307c62c83b23525c56a175 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
index 7dd944483..d50b39a80 100644
--- a/third_party/libtiff/tif_dirread.c
+++ b/third_party/libtiff/tif_dirread.c
@@ -790,44 +790,43 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
        *count=(uint32)direntry->tdir_count;
        datasize=(*count)*typesize;
        assert((tmsize_t)datasize>0);
-       data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-       if (data==0)
-               return(TIFFReadDirEntryErrAlloc);
+       const uint32 small_alloc_threshold=(tif->tif_flags&TIFF_BIGTIFF)? 8 : 4;
+       if (datasize <= small_alloc_threshold)
+       {
+               data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+               if (data==0)
+                       return(TIFFReadDirEntryErrAlloc);
+               _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+               *value=data;
+               return(TIFFReadDirEntryErrOk);
+       }
+       uint64 offset;
        if (!(tif->tif_flags&TIFF_BIGTIFF))
        {
-               if (datasize<=4)
-                       _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-               else
-               {
-                       enum TIFFReadDirEntryErr err;
-                       uint32 offset = direntry->tdir_offset.toff_long;
-                       if (tif->tif_flags&TIFF_SWAB)
-                               TIFFSwabLong(&offset);
-                       err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
-                       if (err!=TIFFReadDirEntryErrOk)
-                       {
-                               _TIFFfree(data);
-                               return(err);
-                       }
-               }
+               uint32 small_offset=direntry->tdir_offset.toff_long;
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabLong(&small_offset);
+               offset=(uint64)small_offset;
        }
        else
        {
-               if (datasize<=8)
-                       _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
-               else
-               {
-                       enum TIFFReadDirEntryErr err;
-                       uint64 offset = direntry->tdir_offset.toff_long8;
-                       if (tif->tif_flags&TIFF_SWAB)
-                               TIFFSwabLong8(&offset);
-                       err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
-                       if (err!=TIFFReadDirEntryErrOk)
-                       {
-                               _TIFFfree(data);
-                               return(err);
-                       }
-               }
+               offset = direntry->tdir_offset.toff_long8;
+               if (tif->tif_flags&TIFF_SWAB)
+                       TIFFSwabLong8(&offset);
+       }
+       if ((uint64)(-1) - offset < datasize)
+               return(TIFFReadDirEntryErrIo);
+       const uint64 size=isMapped(tif)? (uint64)tif->tif_size : TIFFGetFileSize(tif);
+       if (offset + datasize > size)
+               return(TIFFReadDirEntryErrIo);
+       data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+       if (data==0)
+               return(TIFFReadDirEntryErrAlloc);
+       enum TIFFReadDirEntryErr err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
+       if (err!=TIFFReadDirEntryErrOk)
+       {
+               _TIFFfree(data);
+               return(err);
        }
        *value=data;
        return(TIFFReadDirEntryErrOk);