aboutsummaryrefslogtreecommitdiff
path: root/graphics/openexr/files/patch-IlmImf_ImfHeader.cpp
blob: f93473fc7ae4b7da1b0dd235903626788b01eac6 (plain) (blame)
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
--- IlmImf/ImfHeader.cpp.orig	2018-08-10 01:34:58 UTC
+++ IlmImf/ImfHeader.cpp
@@ -785,30 +785,46 @@ Header::sanityCheck (bool isTiled, bool isMultipartFil
 	throw IEX_NAMESPACE::ArgExc ("Invalid data window in image header.");
     }
 
-    if (maxImageWidth > 0 &&
-        maxImageWidth < (dataWindow.max.x - dataWindow.min.x + 1))
+    int w = (dataWindow.max.x - dataWindow.min.x + 1);
+    if (maxImageWidth > 0 && maxImageWidth < w)
     {
 	THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
 			    "maximum width of " << maxImageWidth << "pixels.");
     }
 
-    if (maxImageHeight > 0 &&
-	maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1)
+    int h = (dataWindow.max.y - dataWindow.min.y + 1);
+    if (maxImageHeight > 0 && maxImageHeight < h)
     {
-	THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
-			    "maximum width of " << maxImageHeight << "pixels.");
+	THROW (IEX_NAMESPACE::ArgExc, "The height of the data window exceeds the "
+			    "maximum height of " << maxImageHeight << "pixels.");
     }
 
-   // chunk table must be smaller than the maximum image area
-   // (only reachable for unknown types or damaged files: will have thrown earlier
-   //  for regular image types)
-   if( maxImageHeight>0 && maxImageWidth>0 && 
-       hasChunkCount() && chunkCount()>Int64(maxImageWidth)*Int64(maxImageHeight))
-   {
-       THROW (IEX_NAMESPACE::ArgExc, "chunkCount exceeds maximum area of "
-       << Int64(maxImageWidth)*Int64(maxImageHeight) << " pixels." );
+    // make sure to avoid simple math overflow for large offsets
+    // we know we're at a positive width because of checks above
+    long long bigW = static_cast<long long>( w );
+    long long absOffY = std::abs ( dataWindow.min.y );
+    long long absOffX = std::abs ( dataWindow.min.x );
+    long long offX = static_cast<long long>( INT_MAX ) - absOffX;
+    long long offsetCount = absOffY * bigW;
+    long long bytesLeftPerLine = static_cast<long long>( INT_MAX ) / bigW;
+    if (bytesLeftPerLine < absOffY || offX < offsetCount)
+    {
+	THROW (IEX_NAMESPACE::ArgExc, "Data window [ (" << dataWindow.min.x
+	       << ", " << dataWindow.min.x << ") - (" << dataWindow.max.x
+	       << ", " << dataWindow.max.x
+	       << ") ] offset / size will overflow pointer calculations");
+    }
+
+    // chunk table must be smaller than the maximum image area
+    // (only reachable for unknown types or damaged files: will have thrown earlier
+    //  for regular image types)
+    if( maxImageHeight>0 && maxImageWidth>0 && 
+	hasChunkCount() && chunkCount()>Int64(maxImageWidth)*Int64(maxImageHeight))
+    {
+	THROW (IEX_NAMESPACE::ArgExc, "chunkCount exceeds maximum area of "
+	       << Int64(maxImageWidth)*Int64(maxImageHeight) << " pixels." );
        
-   }
+    }
 
 
     //