diff --git a/src/cineon.imageio/cineoninput.cpp b/src/cineon.imageio/cineoninput.cpp index d64ac4ab3d..330ba34c27 100644 --- a/src/cineon.imageio/cineoninput.cpp +++ b/src/cineon.imageio/cineoninput.cpp @@ -41,6 +41,7 @@ class CineonInput final : public ImageInput { m_stream = nullptr; } m_userBuf.clear(); + m_cin.SetInStream(nullptr); } /// Helper function - retrieve string for libcineon descriptor @@ -89,12 +90,23 @@ CineonInput::open(const std::string& name, ImageSpec& newspec) return false; } + int nchannels = m_cin.header.NumberOfElements(); + if (nchannels < 1 || nchannels > 8) { + errorfmt("Invalid number of channels {} (must be 1-8)", nchannels); + close(); + return false; + } + // create imagespec TypeDesc typedesc; int maxbits = 0; - for (int i = 0; i < m_cin.header.NumberOfElements(); i++) { - if (maxbits < m_cin.header.BitDepth(i)) - maxbits = m_cin.header.BitDepth(i); + for (int i = 0; i < nchannels; i++) { + int b(m_cin.header.BitDepth(i)); + if (b < 1 || b > 32) { + errorfmt("Invalid bitdepth in channel {}: {} bits", i, b); + return false; + } + maxbits = std::max(maxbits, b); } switch ((maxbits + 7) / 8) { case 1: typedesc = TypeDesc::UINT8; break; @@ -103,8 +115,13 @@ CineonInput::open(const std::string& name, ImageSpec& newspec) case 4: typedesc = TypeDesc::UINT32; break; default: errorfmt("Unsupported bit depth {}", maxbits); return false; } - m_spec = ImageSpec(m_cin.header.Width(), m_cin.header.Height(), - m_cin.header.NumberOfElements(), typedesc); + m_spec = ImageSpec(m_cin.header.Width(), m_cin.header.Height(), nchannels, + typedesc); + + if (!check_open(m_spec, { 0, 1 << 20, 0, 1 << 20, 0, 1, 0, 8 })) { + return false; + } + // fill channel names m_spec.channelnames.clear(); int gscount = 0, rcount = 0, gcount = 0, bcount = 0; @@ -119,7 +136,7 @@ CineonInput::open(const std::string& name, ImageSpec& newspec) break; case cineon::kPrintingDensityRed: case cineon::kRec709Red: - if (++gscount > 1) { + if (++rcount > 1) { std::string ch = Strutil::fmt::format("R{}", rcount); m_spec.channelnames.push_back(ch); } else diff --git a/testsuite/cineon/ref/out.txt b/testsuite/cineon/ref/out.txt index efe69e19aa..74ad31e404 100644 --- a/testsuite/cineon/ref/out.txt +++ b/testsuite/cineon/ref/out.txt @@ -33,3 +33,6 @@ Reading ../oiio-images/cineon/checker.cin cineon:YOffset: 0 oiio:BitsPerSample: 10 oiio:ColorSpace: "KodakLog" +oiiotool ERROR: read : "src/broken_bitdepth.cin": Invalid number of channels 255 (must be 1-8) +Full command line was: +> oiiotool --info --hash src/broken_bitdepth.cin diff --git a/testsuite/cineon/run.py b/testsuite/cineon/run.py index 9637ef88a9..e73803c963 100755 --- a/testsuite/cineon/run.py +++ b/testsuite/cineon/run.py @@ -4,7 +4,15 @@ # SPDX-License-Identifier: Apache-2.0 # https://github.com/AcademySoftwareFoundation/OpenImageIO +# save the error output +redirect = " >> out.txt 2>&1 " files = [ "checker.cin" ] for f in files: command += info_command ("../oiio-images/cineon/" + f) + + +# Regression tests for broken files +command += info_command ("src/broken_bitdepth.cin", verbose=False, failureok=True) + +outputs = [ "out.txt" ] diff --git a/testsuite/cineon/src/broken_bitdepth.cin b/testsuite/cineon/src/broken_bitdepth.cin new file mode 100644 index 0000000000..f239e66fe3 Binary files /dev/null and b/testsuite/cineon/src/broken_bitdepth.cin differ