Skip to content
Permalink
Browse files

IOFile: did not properly set m_mode upon open failure. (#2187)

One consequence is that format readers or writers that relied on
IOFile (such as PNG and JPEG) would not properly notice certain I/O
errors.

This failure of JPEG masked a minor bug in the JPEG reader where we
could destroy the compressor that had never been created (crashing
inside jpeg library).
  • Loading branch information...
lgritz committed Mar 8, 2019
1 parent b5b7df4 commit 47404a0b1ec1ad5afdd3857ed0c0a769d1e40475
@@ -102,10 +102,11 @@ class JpgInput final : public ImageInput {
private:
FILE* m_fd;
std::string m_filename;
int m_next_scanline; // Which scanline is the next to read?
bool m_raw; // Read raw coefficients, not scanlines
bool m_cmyk; // The input file is cmyk
bool m_fatalerr; // JPEG reader hit a fatal error
int m_next_scanline; // Which scanline is the next to read?
bool m_raw; // Read raw coefficients, not scanlines
bool m_cmyk; // The input file is cmyk
bool m_fatalerr; // JPEG reader hit a fatal error
bool m_decomp_create; // Have we created the decompressor?
struct jpeg_decompress_struct m_cinfo;
my_error_mgr m_jerr;
jvirt_barray_ptr* m_coeffs;
@@ -119,6 +120,7 @@ class JpgInput final : public ImageInput {
m_raw = false;
m_cmyk = false;
m_fatalerr = false;
m_decomp_create = false;
m_coeffs = NULL;
m_jerr.jpginput = this;
m_io = nullptr;
@@ -255,6 +255,7 @@ JpgInput::open(const std::string& name, ImageSpec& newspec)

// initialize decompressor
jpeg_create_decompress(&m_cinfo);
m_decomp_create = true;
// specify the data source
if (!strcmp(m_io->proxytype(), "file")) {
auto fd = ((Filesystem::IOFile*)m_io)->handle();
@@ -511,7 +512,9 @@ JpgInput::close()
{
if (m_io) {
// unnecessary? jpeg_abort_decompress (&m_cinfo);
jpeg_destroy_decompress(&m_cinfo);
if (m_decomp_create)
jpeg_destroy_decompress(&m_cinfo);
m_decomp_create = false;
close_file();
}
init(); // Reset to initial state
@@ -922,19 +922,20 @@ Filesystem::IOFile::IOFile(string_view filename, Mode mode)
{
// Call Filesystem::fopen since it handles UTF-8 file paths on Windows,
// which std fopen does not.
m_file = Filesystem::fopen(m_filename.c_str(), mode == Write ? "wb" : "rb");
m_file = Filesystem::fopen(m_filename.c_str(),
m_mode == Write ? "wb" : "rb");
if (!m_file)
mode = Closed;
m_mode = Closed;
m_auto_close = true;
if (mode == Read)
if (m_mode == Read)
m_size = Filesystem::file_size(filename);
}

Filesystem::IOFile::IOFile(FILE* file, Mode mode)
: IOProxy("", mode)
, m_file(file)
{
if (mode == Read) {
if (m_mode == Read) {
m_pos = ftell(m_file); // save old position
fseek(m_file, 0, SEEK_END); // seek to end
m_size = size_t(ftell(m_file)); // size is end position
@@ -4,7 +4,8 @@
import OpenImageIO as oiio
import os

OIIO_TESTSUITE_IMAGEDIR = os.environ['OIIO_TESTSUITE_IMAGEDIR']
OIIO_TESTSUITE_IMAGEDIR = os.environ.get('OIIO_TESTSUITE_IMAGEDIR',
'../../../../../oiio-images')

# Print the contents of an ImageSpec
def print_imagespec (spec, subimage=0, mip=0, msg="") :

0 comments on commit 47404a0

Please sign in to comment.
You can’t perform that action at this time.