diff --git a/src/dds.imageio/ddsinput.cpp b/src/dds.imageio/ddsinput.cpp index 2f6248dfdb..88260f2c0b 100644 --- a/src/dds.imageio/ddsinput.cpp +++ b/src/dds.imageio/ddsinput.cpp @@ -1090,8 +1090,8 @@ DDSInput::read_native_scanline(int subimage, int miplevel, int y, int z, // don't proceed if a cube map - use tiles then instead if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) return false; - if (m_buf.empty()) - readimg_scanlines(); + if (m_buf.empty() && !readimg_scanlines()) + return false; size_t size = spec().scanline_bytes(); size_t offset = size_t(z) * m_spec.height * size + size_t(y) * size; @@ -1116,8 +1116,8 @@ DDSInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, if (m_dds.caps.flags2 & DDS_CAPS2_VOLUME) { // This is a 3D volume file. For DDS files, we are emulating tiles, // with each scanline as a tile. - if (m_buf.empty()) - readimg_scanlines(); + if (m_buf.empty() && !readimg_scanlines()) + return false; // We reported scanlines as tiles, so x must be 0. if (x != 0) return false; @@ -1151,8 +1151,8 @@ DDSInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, m_buf.resize(m_spec.tile_bytes()); // resize destination buffer if (!w && !h && !d) // face not present in file, black-pad the image memset(&m_buf[0], 0, m_spec.tile_bytes()); - else - readimg_tiles(); + else if (!readimg_tiles()) + return false; } memcpy(data, &m_buf[0], m_spec.tile_bytes()); diff --git a/testsuite/dds/ref/out.txt b/testsuite/dds/ref/out.txt index 3870f2b9df..0f21c60dfa 100644 --- a/testsuite/dds/ref/out.txt +++ b/testsuite/dds/ref/out.txt @@ -240,8 +240,10 @@ Reading ../oiio-images/dds/dds_dxgi_r16.dds textureformat: "Plain Texture" oiio:BitsPerSample: 16 Reading ../oiio-images/dds/broken/dds_bc3_just_header.dds +oiiotool ERROR: -info : SHA-1: Read error: hit end of file in dds reader +Full command line was: +> oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc3_just_header.dds ../oiio-images/dds/broken/dds_bc3_just_header.dds : 24 x 20, 4 channel, uint8 dds - SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED channel list: R, G, B, A compression: "DXT5" textureformat: "Plain Texture" @@ -249,20 +251,26 @@ oiiotool ERROR: read : "../oiio-images/dds/broken/dds_bc3_no_full_header.dds": R Full command line was: > oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc3_no_full_header.dds Reading ../oiio-images/dds/broken/dds_bc7_just_header.dds +oiiotool ERROR: -info : SHA-1: Read error: hit end of file in dds reader +Full command line was: +> oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc7_just_header.dds ../oiio-images/dds/broken/dds_bc7_just_header.dds : 24 x 20, 4 channel, uint8 dds - SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED channel list: R, G, B, A compression: "BC7" textureformat: "Plain Texture" Reading ../oiio-images/dds/broken/dds_bc7_not_enough_data.dds +oiiotool ERROR: -info : SHA-1: Read error: hit end of file in dds reader +Full command line was: +> oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc7_not_enough_data.dds ../oiio-images/dds/broken/dds_bc7_not_enough_data.dds : 24 x 20, 4 channel, uint8 dds - SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED channel list: R, G, B, A compression: "BC7" textureformat: "Plain Texture" Reading src/crash-1634.dds +oiiotool ERROR: -info : SHA-1: Read error: hit end of file in dds reader +Full command line was: +> oiiotool --info -v -a --hash src/crash-1634.dds src/crash-1634.dds : 16 x 8, 1 channel, uint8 dds - SHA-1: CB82FD0F9EF1B69F3F3FF14077564AC2D6C11540 channel list: Y textureformat: "Plain Texture" oiio:BitsPerSample: 16 @@ -278,3 +286,6 @@ src/crash-3950.dds : 16 x 1, 4 channel, uint8 dds oiiotool ERROR: read : "src/crash-bpp.dds": Invalid DDS bytes-per-pixel (322122548). Possible corrupt input? Full command line was: > oiiotool --info -v -a --hash src/crash-bpp.dds +oiiotool ERROR: read : "src/crash-bomb-32768.dds": dds header claims a 4096 MB image from a 128 byte file; probably a corrupt or malicious header +Full command line was: +> oiiotool --info -v -a --hash src/crash-bomb-32768.dds diff --git a/testsuite/dds/run.py b/testsuite/dds/run.py index 86a56549e9..03d98dcb69 100755 --- a/testsuite/dds/run.py +++ b/testsuite/dds/run.py @@ -65,3 +65,6 @@ # crash-bpp.dds has a corrupt bytes-per-pixel that used to drive a multi-GB # allocation (OOM) before the native bpp was sanity-checked. command += info_command ("src/crash-bpp.dds", hash=True) +# Tiny file declaring a huge DXT5 image (decompression bomb) is rejected +# before the m_buf allocation. +command += info_command ("src/crash-bomb-32768.dds", hash=True) diff --git a/testsuite/dds/src/crash-bomb-32768.dds b/testsuite/dds/src/crash-bomb-32768.dds new file mode 100644 index 0000000000..9fe125b2bb Binary files /dev/null and b/testsuite/dds/src/crash-bomb-32768.dds differ