Skip to content

Commit e16a738

Browse files
committed
Add reference to setMaxImageSize to ReadingAndWritingImageFiles.rst
And website/src/exrreader/exrreader_max.cpp illustrates setting max image size. Signed-off-by: Cary Phillips <cary@ilm.com>
1 parent f457bf0 commit e16a738

4 files changed

Lines changed: 148 additions & 11 deletions

File tree

website/ReadingAndWritingImageFiles.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,41 @@ are currently in use.
15351535
Miscellaneous
15361536
=============
15371537

1538+
Image Size Limits and Out-of-Memory Failures
1539+
--------------------------------------------
1540+
1541+
The OpenEXR file format places no fixed limit on image size, except
1542+
that image width and height are represented by signed 32-bit integers
1543+
and therefore technically limited to a maximum of 2,147,483,647.
1544+
1545+
Attempting to read a very large image may result in an "out-of-memory
1546+
failure. This is not considered a security vulnerability. The memory
1547+
required to decode such an image is inherently proportional to its
1548+
pixel count, even if compression reduces the image to a small file
1549+
size on disk. Exhausting available memory on a given machine is a
1550+
system resource constraint, not a library defect — the same file that
1551+
triggers an out-of-memory error on one machine may load successfully
1552+
on another with more memory.
1553+
1554+
The OpenEXR library provides
1555+
``Imf::Header::setMaxImageSize(int maxWidth,int maxHeight)`` and
1556+
``Imf::Header:"setMaxTileSize(int maxWidth,int maxHeight)`` (and
1557+
``exr_set_default_maximum_image_size()`` and
1558+
``exr_set_default_maximum_tile_size()`` in OpenEXRCore) to allow
1559+
applications to reject files with dimensions exceeding a configurable
1560+
limit before any large allocation occurs. Applications processing
1561+
untrusted EXR files should set these limits to values appropriate for
1562+
their deployment environment.
1563+
1564+
Beware of setting this limit too low. Images of resolution greater
1565+
than 10k are not uncommon in VFX workflows. Unless your application
1566+
must process untrusted EXR files in an environment where failure is
1567+
catastrophic, it may be best to provide a limit but allow it to be
1568+
configured by the user:
1569+
1570+
.. literalinclude:: src/exrreader/exrreader_max.cpp
1571+
:lines: 5-
1572+
15381573
Is this an OpenEXR File?
15391574
------------------------
15401575

website/TechnicalIntroduction.rst

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,20 @@ The OpenEXR file format places no fixed limit on image size, except
146146
that image width and height are represented by signed 32-bit integers
147147
and therefore technically limited to a maximum of 2,147,483,647.
148148

149-
Memory allocation failures caused by large image dimensions declared
150-
in file headers are not considered security vulnerabilities when the
151-
allocation size is proportional to the declared image dimensions. EXR
152-
files can legitimately describe very large images, and the memory
153-
required to decode them is inherently proportional to their pixel
154-
count. Exhausting available memory on a given machine is a system
155-
resource constraint, not a library defect — the same file that
149+
Attempting to read a very large image may result in an "out-of-memory
150+
failure. This is not considered a security vulnerability. The memory
151+
required to decode such an image is inherently proportional to its
152+
pixel count, even if compression reduces the image to a small file
153+
size on disk. Exhausting available memory on a given machine is a
154+
system resource constraint, not a library defect — the same file that
156155
triggers an out-of-memory error on one machine may load successfully
157156
on another with more memory.
158157

159158
The OpenEXR library provides
160-
`Imf::Header::setMaxImageSize(int maxWidth,int maxHeight)` and
161-
`Imf::Header:"setMaxTileSize(int maxWidth,int maxHeight)` (and
162-
`exr_set_default_maximum_image_size()` and
163-
`exr_set_default_maximum_tile_size()` in OpenEXRCore) to allow
159+
``Imf::Header::setMaxImageSize(int maxWidth,int maxHeight)`` and
160+
``Imf::Header:"setMaxTileSize(int maxWidth,int maxHeight)`` (and
161+
``exr_set_default_maximum_image_size()`` and
162+
``exr_set_default_maximum_tile_size()`` in OpenEXRCore) to allow
164163
applications to reject files with dimensions exceeding a configurable
165164
limit before any large allocation occurs. Applications processing
166165
untrusted EXR files should set these limits to values appropriate for

website/src/exrreader/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ find_package(OpenEXR REQUIRED)
1010
add_executable(${PROJECT_NAME} exrreader.cpp)
1111
target_link_libraries(${PROJECT_NAME} OpenEXR::OpenEXR)
1212

13+
add_executable(${PROJECT_NAME}_max exrreader_max.cpp)
14+
target_link_libraries(${PROJECT_NAME}_max OpenEXR::OpenEXR)
15+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
// Copyright (c) Contributors to the OpenEXR Project.
4+
//
5+
6+
#include <ImfRgbaFile.h>
7+
#include <ImfArray.h>
8+
#include <cstring>
9+
#include <iostream>
10+
#include <stdexcept>
11+
#include <string>
12+
13+
static void
14+
usage(const char *prog)
15+
{
16+
std::cerr << "usage: " << prog
17+
<< " [--maxImageSize <width> <height>] <image.exr>\n";
18+
}
19+
20+
int
21+
main(int argc, char *argv[])
22+
{
23+
int maxW = 10000;
24+
int maxH = 10000;
25+
std::string path;
26+
27+
for (int i = 1; i < argc; ++i)
28+
{
29+
if (std::strcmp(argv[i], "--maxImageSize") == 0)
30+
{
31+
if (i + 2 >= argc)
32+
{
33+
usage(argv[0]);
34+
return 1;
35+
}
36+
try
37+
{
38+
maxW = std::stoi(argv[i + 1]);
39+
maxH = std::stoi(argv[i + 2]);
40+
}
41+
catch (const std::exception &)
42+
{
43+
std::cerr << "invalid width or height for --maxImageSize\n";
44+
return 1;
45+
}
46+
if (maxW <= 0 || maxH <= 0)
47+
{
48+
std::cerr << "--maxImageSize width and height must be positive\n";
49+
return 1;
50+
}
51+
i += 2;
52+
}
53+
else if (argv[i][0] == '-')
54+
{
55+
std::cerr << "unknown option: " << argv[i] << std::endl;
56+
usage(argv[0]);
57+
return 1;
58+
}
59+
else
60+
{
61+
if (!path.empty())
62+
{
63+
std::cerr << "unexpected extra argument: " << argv[i]
64+
<< std::endl;
65+
usage(argv[0]);
66+
return 1;
67+
}
68+
path = argv[i];
69+
}
70+
}
71+
72+
if (path.empty())
73+
{
74+
usage(argv[0]);
75+
return 1;
76+
}
77+
78+
Imf::Header::setMaxImageSize(maxW, maxH);
79+
80+
try
81+
{
82+
Imf::RgbaInputFile file(path.c_str());
83+
Imath::Box2i dw = file.dataWindow();
84+
int width = dw.max.x - dw.min.x + 1;
85+
int height = dw.max.y - dw.min.y + 1;
86+
87+
Imf::Array2D<Imf::Rgba> pixels(width, height);
88+
89+
file.setFrameBuffer(&pixels[0][0], 1, width);
90+
file.readPixels(dw.min.y, dw.max.y);
91+
}
92+
catch (const std::exception &e)
93+
{
94+
std::cerr << "error reading image file " << path << ": " << e.what()
95+
<< std::endl;
96+
return 1;
97+
}
98+
99+
return 0;
100+
}

0 commit comments

Comments
 (0)