Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add exrcheck utility and hooks for fuzz testing #842

Merged
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
1 change: 1 addition & 0 deletions OpenEXR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ if(OPENEXR_BUILD_UTILS)
add_subdirectory( exrenvmap )
add_subdirectory( exrmultiview )
add_subdirectory( exrmultipart )
add_subdirectory( exrcheck )
endif()

option(INSTALL_OPENEXR_DOCS "Install OpenEXR documentation" ON)
Expand Down
81 changes: 78 additions & 3 deletions OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,10 +721,12 @@ LineBufferTask::execute ()

int width = (_ifd->maxX - _ifd->minX + 1);

ptrdiff_t base = reinterpret_cast<ptrdiff_t>(&_ifd->sampleCount[0][0]);
base -= sizeof(unsigned int)*_ifd->minX;
base -= sizeof(unsigned int)*static_cast<ptrdiff_t>(_ifd->minY) * static_cast<ptrdiff_t>(width);

copyIntoDeepFrameBuffer (readPtr, slice.base,
(char*) (&_ifd->sampleCount[0][0]
- _ifd->minX
- _ifd->minY * width),
reinterpret_cast<char*>(base),
sizeof(unsigned int) * 1,
sizeof(unsigned int) * width,
y, _ifd->minX, _ifd->maxX,
Expand Down Expand Up @@ -1026,6 +1028,79 @@ DeepScanLineInputFile::DeepScanLineInputFile
}



DeepScanLineInputFile::DeepScanLineInputFile
(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads)
:
_data (new Data (numThreads))
{
_data->_deleteStream = false;
_data->_streamData = nullptr;

try
{
readMagicNumberAndVersionField(is, _data->version);
//
// Backward compatibility to read multpart file.
// multiPartInitialize will create _streamData
if (isMultiPart(_data->version))
{
compatibilityInitialize(is);
return;
}
}
catch (IEX_NAMESPACE::BaseExc &e)
{
if (_data) delete _data;

REPLACE_EXC (e, "Cannot read image file "
"\"" << is.fileName() << "\". " << e.what());
throw;
}

//
// not multiPart - allocate stream data and intialise as normal
//
try
{
_data->_streamData = new InputStreamMutex();
_data->_streamData->is = &is;
_data->memoryMapped = is.isMemoryMapped();
_data->header.readFrom (*_data->_streamData->is, _data->version);
_data->header.sanityCheck (isTiled (_data->version));

initialize(_data->header);

readLineOffsets (*_data->_streamData->is,
_data->lineOrder,
_data->lineOffsets,
_data->fileIsComplete);
}
catch (IEX_NAMESPACE::BaseExc &e)
{
if (_data && _data->_streamData)
{
delete _data->_streamData;
}
if (_data) delete _data;

REPLACE_EXC (e, "Cannot read image file "
"\"" << is.fileName() << "\". " << e.what());
throw;
}
catch (...)
{
if (_data && _data->_streamData)
{
delete _data->_streamData;
}
if (_data) delete _data;

throw;
}
}


DeepScanLineInputFile::DeepScanLineInputFile
(const Header &header,
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
Expand Down
5 changes: 5 additions & 0 deletions OpenEXR/IlmImf/ImfDeepScanLineInputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ class DeepScanLineInputFile : public GenericInputFile
DeepScanLineInputFile (const char fileName[],
int numThreads = globalThreadCount());

IMF_EXPORT
DeepScanLineInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
int numThreads = globalThreadCount());


IMF_EXPORT
DeepScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
int version, /*version field from file*/
Expand Down
2 changes: 1 addition & 1 deletion OpenEXR/IlmImf/ImfInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
// if no channels are being read that are present in file, cachedBuffer will be empty
//

if (ifd->cachedBuffer->begin() != ifd->cachedBuffer->end())
if (ifd->cachedBuffer && ifd->cachedBuffer->begin() != ifd->cachedBuffer->end())
{
ifd->tFile->readTiles (0, ifd->tFile->numXTiles (0) - 1, j, j);
}
Expand Down
12 changes: 12 additions & 0 deletions OpenEXR/IlmImf/ImfMultiPartInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,18 @@ MultiPartInputFile::getInputPart(int partNumber)
else return (T*) _data->_inputFiles[partNumber];
}

void
MultiPartInputFile::flushPartCache()
{
Lock lock(*_data);
while ( _data->_inputFiles.begin() != _data->_inputFiles.end())
{
delete _data->_inputFiles.begin()->second;
_data->_inputFiles.erase(_data->_inputFiles.begin());
}

}


template InputFile* MultiPartInputFile::getInputPart<InputFile>(int);
template TiledInputFile* MultiPartInputFile::getInputPart<TiledInputFile>(int);
Expand Down
12 changes: 12 additions & 0 deletions OpenEXR/IlmImf/ImfMultiPartInputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ class MultiPartInputFile : public GenericInputFile
bool partComplete(int part) const;


// ----------------------------------------
// Flush internal part cache
// Invalidates all 'Part' types previously
// constructed from this file
// Intended for test purposes, but can be
// used to temporarily reduce memory overhead,
// or to switch between types (e.g. TiledInputPart
// or DeepScanLineInputPart to InputPart)
// ----------------------------------------

IMF_EXPORT
void flushPartCache();
struct Data;


Expand Down
5 changes: 4 additions & 1 deletion OpenEXR/IlmImf/ImfTiledInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,10 @@ TiledInputFile::initialize ()
{
if (!isTiled (_data->version))
throw IEX_NAMESPACE::ArgExc ("Expected a tiled file but the file is not tiled.");


if (isNonImage (_data->version))
throw IEX_NAMESPACE::ArgExc ("File is not a regular tiled image.");

}
else
{
Expand Down
20 changes: 20 additions & 0 deletions OpenEXR/IlmImfFuzzTest/oss-fuzz/openexr_exrcheck_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenEXR Project.
//
// this file is found by the oss-fuzz project to generate a fuzzer. It is not part of
// OpenEXR's internal IlmImfFuzzTest suite
//

#include <ImfNamespace.h>
#include <ImfCheckFile.h>
#include <stdint.h>

using OPENEXR_IMF_NAMESPACE::checkOpenEXRFile;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
checkOpenEXRFile( (const char*) data , size , true , true );
return 0;
}

2 changes: 2 additions & 0 deletions OpenEXR/IlmImfUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ openexr_define_library(IlmImfUtil
ImfFlatImageIO.cpp
ImfDeepImageIO.cpp
ImfImageDataWindow.cpp
ImfCheckFile.cpp
HEADERS
ImfImageChannel.h
ImfFlatImageChannel.h
Expand All @@ -36,6 +37,7 @@ openexr_define_library(IlmImfUtil
ImfImageDataWindow.h
ImfImageChannelRenaming.h
ImfUtilExport.h
ImfCheckFile.h
DEPENDENCIES
OpenEXR::IlmImf
)
Loading