Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/dpx.imageio/dpxinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class DPXInput final : public ImageInput {
dpx::Reader m_dpx;
default_init_vector<unsigned char> m_userBuf;
default_init_vector<unsigned char> m_decodebuf; // temporary decode buffer
size_t m_filesize = 0;
bool m_rawcolor;

/// Reset everything to initial state
Expand Down Expand Up @@ -137,7 +138,8 @@ DPXInput::open(const std::string& name, ImageSpec& newspec)
if (!ioproxy_use_or_open(name))
return false;

m_stream = new InStream(ioproxy());
m_filesize = ioproxy()->size();
m_stream = new InStream(ioproxy());
if (!m_stream) {
errorfmt("Could not open file \"{}\"", name);
return false;
Expand Down Expand Up @@ -547,6 +549,11 @@ DPXInput::seek_subimage(int subimage, int miplevel)
// data is per-file, not per-element)
if (m_userBuf.empty() && m_dpx.header.UserSize() != 0
&& m_dpx.header.UserSize() != 0xFFFFFFFF) {
if (m_dpx.header.UserSize() > m_filesize) {
errorfmt("Corrupt userbuf: size claims {} but whole file size is {}",
m_dpx.header.UserSize(), m_filesize);
return false;
}
m_userBuf.resize(m_dpx.header.UserSize());
m_dpx.ReadUserData(&m_userBuf[0]);
}
Expand Down
52 changes: 28 additions & 24 deletions src/dpx.imageio/libdpx/ReaderInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@


#include <algorithm>
#include <cstdint>

#include "BaseTypeConverter.h"


Expand Down Expand Up @@ -143,13 +145,13 @@ namespace dpx
int actline = line + block.y1;

// first get line offset
long offset = actline * lineLength;
int64_t offset = int64_t(actline) * lineLength;

// add in eoln padding
offset += line * eolnPad;
offset += int64_t(line) * eolnPad;

// add in offset within the current line, rounding down so to catch any components within the word
offset += block.x1 * numberOfComponents / 3 * 4;
offset += int64_t(block.x1) * numberOfComponents / 3 * 4;


// get the read count in bytes, round to the 32-bit boundary
Expand Down Expand Up @@ -231,10 +233,12 @@ namespace dpx
// the pattern repeats every 96 bits

// first determine the word that the data element completely resides in
U16 *d1 = reinterpret_cast<U16 *>(reinterpret_cast<U8 *>(readBuf)+((i * bitDepth) / 8 /*bits*/));

// place the component in the MSB and mask it for both 10-bit and 12-bit
U16 d2 = (*d1 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK;
U8 *d1 = reinterpret_cast<U8 *>(readBuf)+((i * bitDepth) / 8 /*bits*/);
U16 d2;
memcpy(&d2, d1, sizeof(U16)); // Use memcpy to launder any misalignment

// place the component in the MSB and mask it for both 10-bit and 12-bit.
d2 = (d2 << (REVERSE - ((i % REMAIN) * MULTIPLIER))) & MASK;

// For the 10/12 bit cases, specialize the 16-bit conversion by
// repacking into the LSB and using a specialized conversion
Expand Down Expand Up @@ -276,8 +280,8 @@ namespace dpx
for (int line = 0; line < height; line++)
{
// determine offset into image element
long offset = (line + block.y1) * (lineSize * sizeof(U32)) +
(block.x1 * numberOfComponents * dataSize / 32 * sizeof(U32)) + (line * eolnPad);
int64_t offset = int64_t(line + block.y1) * (lineSize * sizeof(U32)) +
(int64_t(block.x1) * numberOfComponents * dataSize / 32 * sizeof(U32)) + int64_t(line) * eolnPad;

// calculate read size
int readSize = ((block.x2 - block.x1 + 1) * numberOfComponents * dataSize);
Expand Down Expand Up @@ -338,20 +342,20 @@ namespace dpx
{

// determine offset into image element
long offset = (line + block.y1) * imageWidth * numberOfComponents * bytes +
block.x1 * numberOfComponents * bytes + (line * eolnPad);
int64_t offset = int64_t(line + block.y1) * imageWidth * numberOfComponents * bytes +
int64_t(block.x1) * numberOfComponents * bytes + int64_t(line) * eolnPad;

if (BUFTYPE == SRCTYPE)
{
fd->ReadDirect(dpxHeader, element, offset, reinterpret_cast<unsigned char *>(data + (width*line)), width*bytes);
fd->ReadDirect(dpxHeader, element, offset, reinterpret_cast<unsigned char *>(data + int64_t(width)*line), int64_t(width)*bytes);
}
else
{
fd->Read(dpxHeader, element, offset, readBuf, width*bytes);
// convert data
fd->Read(dpxHeader, element, offset, readBuf, int64_t(width)*bytes);

// convert data
for (int i = 0; i < width; i++)
BaseTypeConverter(readBuf[i], data[width*line+i]);
BaseTypeConverter(readBuf[i], data[int64_t(width)*line+i]);
}

}
Expand Down Expand Up @@ -382,17 +386,17 @@ namespace dpx
for (int line = 0; line < height; line++)
{
// determine offset into image element
long offset = (line + block.y1) * imageWidth * numberOfComponents * 2 +
block.x1 * numberOfComponents * 2 + (line * eolnPad);
int64_t offset = int64_t(line + block.y1) * imageWidth * numberOfComponents * 2 +
int64_t(block.x1) * numberOfComponents * 2 + int64_t(line) * eolnPad;

fd->Read(dpxHeader, element, offset, readBuf, width*2);
// convert data
fd->Read(dpxHeader, element, offset, readBuf, int64_t(width)*2);

// convert data
for (int i = 0; i < width; i++)
{
U16 d1 = readBuf[i];
BaseTypeConvertU12ToU16(d1, d1);
BaseTypeConverter(d1, data[width*line+i]);
BaseTypeConverter(d1, data[int64_t(width)*line+i]);
}
}

Expand Down Expand Up @@ -528,7 +532,7 @@ namespace dpx
{
for (nc = 0; nc < numberOfComponents; nc++)
{
SRC d1 = src[(y * width * numberOfComponents) + (x * numberOfComponents) + nc];
SRC d1 = src[int64_t(y) * width * numberOfComponents + int64_t(x) * numberOfComponents + nc];
BaseTypeConverter(d1, dst[dstoff+((x-block.x1)*numberOfComponents) + nc]);
}
}
Expand Down
3 changes: 3 additions & 0 deletions testsuite/dpx/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,6 @@ grey.dpx : 512 x 512, 1 channel, uint10 dpx
oiio:subimages: 1
Comparing "grey.dpx" and "ref/grey.tif"
PASS
oiiotool ERROR: read : "src/crash-badusersize.dpx": Corrupt userbuf: size claims 4160749568 but whole file size is 2054
Full command line was:
> oiiotool src/crash-badusersize.dpx -o test.tif
6 changes: 6 additions & 0 deletions testsuite/dpx/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# SPDX-License-Identifier: Apache-2.0
# https://github.com/AcademySoftwareFoundation/OpenImageIO

redirect = " >> out.txt 2>&1 "

files = [ "dpx_nuke_10bits_rgb.dpx", "dpx_nuke_16bits_rgba.dpx" ]
for f in files:
command += rw_command (OIIO_TESTSUITE_IMAGEDIR, f)
Expand Down Expand Up @@ -31,3 +33,7 @@
" -chsum:weight=0.333,0.333,0.333 -chnames Y -ch Y -o grey.dpx")
command += info_command("grey.dpx", safematch=True)
command += diff_command("grey.dpx", "ref/grey.tif")


# Regression tests
command += oiiotool("src/crash-badusersize.dpx -o test.tif", failureok=True)
Binary file added testsuite/dpx/src/crash-badusersize.dpx
Binary file not shown.
Loading