Skip to content

Commit 4b56b81

Browse files
committed
fix(exr): Avoid integer overflow for large deep exr slice strides (AcademySoftwareFoundation#4542)
Fixes AcademySoftwareFoundation#4540 --------- Signed-off-by: Larry Gritz <[email protected]>
1 parent 6b55821 commit 4b56b81

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed

src/openexr.imageio/exrinput.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ OpenEXRInput::read_native_deep_scanlines(int subimage, int miplevel, int ybegin,
14451445
try {
14461446
size_t npixels = (yend - ybegin) * m_spec.width;
14471447
chend = clamp(chend, chbegin + 1, m_spec.nchannels);
1448-
int nchans = chend - chbegin;
1448+
size_t nchans = chend - chbegin;
14491449

14501450
// Set up the count and pointers arrays and the Imf framebuffer
14511451
std::vector<TypeDesc> channeltypes;
@@ -1462,16 +1462,17 @@ OpenEXRInput::read_native_deep_scanlines(int subimage, int miplevel, int ybegin,
14621462
sizeof(unsigned int),
14631463
sizeof(unsigned int) * m_spec.width);
14641464
frameBuffer.insertSampleCountSlice(countslice);
1465+
size_t slchans = m_spec.width * nchans;
1466+
size_t xstride = sizeof(void*) * nchans;
1467+
size_t ystride = sizeof(void*) * slchans;
1468+
size_t samplestride = deepdata.samplesize();
14651469

14661470
for (int c = chbegin; c < chend; ++c) {
1467-
Imf::DeepSlice slice(
1468-
part.pixeltype[c],
1469-
(char*)(&pointerbuf[0] + (c - chbegin) - m_spec.x * nchans
1470-
- ybegin * m_spec.width * nchans),
1471-
sizeof(void*) * nchans, // xstride of pointer array
1472-
sizeof(void*) * nchans
1473-
* m_spec.width, // ystride of pointer array
1474-
deepdata.samplesize()); // stride of data sample
1471+
Imf::DeepSlice slice(part.pixeltype[c],
1472+
(char*)(&pointerbuf[0] + (c - chbegin)
1473+
- m_spec.x * nchans
1474+
- ybegin * slchans),
1475+
xstride, ystride, samplestride);
14751476
frameBuffer.insert(m_spec.channelnames[c].c_str(), slice);
14761477
}
14771478
m_deep_scanline_input_part->setFrameBuffer(frameBuffer);
@@ -1524,7 +1525,7 @@ OpenEXRInput::read_native_deep_tiles(int subimage, int miplevel, int xbegin,
15241525
size_t height = yend - ybegin;
15251526
size_t npixels = width * height;
15261527
chend = clamp(chend, chbegin + 1, m_spec.nchannels);
1527-
int nchans = chend - chbegin;
1528+
size_t nchans = chend - chbegin;
15281529

15291530
// Set up the count and pointers arrays and the Imf framebuffer
15301531
std::vector<TypeDesc> channeltypes;
@@ -1539,14 +1540,15 @@ OpenEXRInput::read_native_deep_tiles(int subimage, int miplevel, int xbegin,
15391540
Imf::UINT, (char*)(&all_samples[0] - xbegin - ybegin * width),
15401541
sizeof(unsigned int), sizeof(unsigned int) * width);
15411542
frameBuffer.insertSampleCountSlice(countslice);
1543+
size_t slchans = width * nchans;
1544+
size_t xstride = sizeof(void*) * nchans;
1545+
size_t ystride = sizeof(void*) * slchans;
1546+
size_t samplestride = deepdata.samplesize();
15421547
for (int c = chbegin; c < chend; ++c) {
1543-
Imf::DeepSlice slice(
1544-
part.pixeltype[c],
1545-
(char*)(&pointerbuf[0] + (c - chbegin) - xbegin * nchans
1546-
- ybegin * width * nchans),
1547-
sizeof(void*) * nchans, // xstride of pointer array
1548-
sizeof(void*) * nchans * width, // ystride of pointer array
1549-
deepdata.samplesize()); // stride of data sample
1548+
Imf::DeepSlice slice(part.pixeltype[c],
1549+
(char*)(&pointerbuf[0] + (c - chbegin)
1550+
- xbegin * nchans - ybegin * slchans),
1551+
xstride, ystride, samplestride);
15501552
frameBuffer.insert(m_spec.channelnames[c].c_str(), slice);
15511553
}
15521554
m_deep_tiled_input_part->setFrameBuffer(frameBuffer);

src/openexr.imageio/exroutput.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,17 +1693,17 @@ OpenEXROutput::write_deep_scanlines(int ybegin, int yend, int /*z*/,
16931693
return false;
16941694
}
16951695

1696-
int nchans = m_spec.nchannels;
1696+
size_t nchans(m_spec.nchannels);
16971697
const DeepData* dd = &deepdata;
16981698
std::unique_ptr<DeepData> dd_local; // In case we need a copy
16991699
bool same_chantypes = true;
1700-
for (int c = 0; c < nchans; ++c)
1700+
for (size_t c = 0; c < nchans; ++c)
17011701
same_chantypes &= (m_spec.channelformat(c) == deepdata.channeltype(c));
17021702
if (!same_chantypes) {
17031703
// If the channel types don't match, we need to make a copy of the
17041704
// DeepData and convert the channels to the spec's channel types.
17051705
std::vector<TypeDesc> chantypes;
1706-
if (m_spec.channelformats.size() == size_t(nchans))
1706+
if (m_spec.channelformats.size() == nchans)
17071707
chantypes = m_spec.channelformats;
17081708
else
17091709
chantypes.resize(nchans, m_spec.format);
@@ -1722,15 +1722,15 @@ OpenEXROutput::write_deep_scanlines(int ybegin, int yend, int /*z*/,
17221722
frameBuffer.insertSampleCountSlice(countslice);
17231723
std::vector<void*> pointerbuf;
17241724
dd->get_pointers(pointerbuf);
1725-
for (int c = 0; c < nchans; ++c) {
1725+
size_t slchans = size_t(m_spec.width) * nchans;
1726+
size_t xstride = sizeof(void*) * nchans;
1727+
size_t ystride = sizeof(void*) * slchans;
1728+
size_t samplestride = dd->samplesize();
1729+
for (size_t c = 0; c < nchans; ++c) {
17261730
Imf::DeepSlice slice(m_pixeltype[c],
17271731
(char*)(&pointerbuf[c] - m_spec.x * nchans
1728-
- ybegin * m_spec.width * nchans),
1729-
sizeof(void*)
1730-
* nchans, // xstride of pointer array
1731-
sizeof(void*) * nchans
1732-
* m_spec.width, // ystride of pointer array
1733-
dd->samplesize()); // stride of data sample
1732+
- ybegin * slchans),
1733+
xstride, ystride, samplestride);
17341734
frameBuffer.insert(m_spec.channelnames[c].c_str(), slice);
17351735
}
17361736
m_deep_scanline_output_part->setFrameBuffer(frameBuffer);
@@ -1765,17 +1765,17 @@ OpenEXROutput::write_deep_tiles(int xbegin, int xend, int ybegin, int yend,
17651765
return false;
17661766
}
17671767

1768-
int nchans = m_spec.nchannels;
1768+
size_t nchans = size_t(m_spec.nchannels);
17691769
const DeepData* dd = &deepdata;
17701770
std::unique_ptr<DeepData> dd_local; // In case we need a copy
17711771
bool same_chantypes = true;
1772-
for (int c = 0; c < nchans; ++c)
1772+
for (size_t c = 0; c < nchans; ++c)
17731773
same_chantypes &= (m_spec.channelformat(c) == deepdata.channeltype(c));
17741774
if (!same_chantypes) {
17751775
// If the channel types don't match, we need to make a copy of the
17761776
// DeepData and convert the channels to the spec's channel types.
17771777
std::vector<TypeDesc> chantypes;
1778-
if (m_spec.channelformats.size() == size_t(nchans))
1778+
if (m_spec.channelformats.size() == nchans)
17791779
chantypes = m_spec.channelformats;
17801780
else
17811781
chantypes.resize(nchans, m_spec.format);
@@ -1796,15 +1796,15 @@ OpenEXROutput::write_deep_tiles(int xbegin, int xend, int ybegin, int yend,
17961796
frameBuffer.insertSampleCountSlice(countslice);
17971797
std::vector<void*> pointerbuf;
17981798
dd->get_pointers(pointerbuf);
1799-
for (int c = 0; c < nchans; ++c) {
1799+
size_t slchans = width * nchans;
1800+
size_t xstride = sizeof(void*) * nchans;
1801+
size_t ystride = sizeof(void*) * slchans;
1802+
size_t samplestride = dd->samplesize();
1803+
for (size_t c = 0; c < nchans; ++c) {
18001804
Imf::DeepSlice slice(m_pixeltype[c],
18011805
(char*)(&pointerbuf[c] - xbegin * nchans
1802-
- ybegin * width * nchans),
1803-
sizeof(void*)
1804-
* nchans, // xstride of pointer array
1805-
sizeof(void*) * nchans
1806-
* width, // ystride of pointer array
1807-
dd->samplesize()); // stride of data sample
1806+
- ybegin * slchans),
1807+
xstride, ystride, samplestride);
18081808
frameBuffer.insert(m_spec.channelnames[c].c_str(), slice);
18091809
}
18101810
m_deep_tiled_output_part->setFrameBuffer(frameBuffer);

0 commit comments

Comments
 (0)