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

Address issues reported by Undefined Behavior Sanitizer running IlmImfTest #828

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
12 changes: 12 additions & 0 deletions IlmBase/IlmThread/IlmThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ Thread::~Thread ()
_thread.join ();
}

void
Thread::join()
{
if ( _thread.joinable () )
_thread.join ();
}

void
Thread::start ()
Expand Down Expand Up @@ -108,6 +114,12 @@ Thread::start ()
{
throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
}

void
Thread::join ()
{
throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
}
# endif
#endif

Expand Down
5 changes: 5 additions & 0 deletions IlmBase/IlmThread/IlmThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ class Thread
ILMTHREAD_EXPORT void start ();
ILMTHREAD_EXPORT virtual void run () = 0;

//
// wait for thread to exit - must be called before deleting thread
//
void join();

private:

#ifdef ILMBASE_FORCE_CXX03
Expand Down
4 changes: 3 additions & 1 deletion IlmBase/IlmThread/IlmThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,10 @@ DefaultThreadPoolProvider::finish ()
// Join all the threads
//
for (size_t i = 0; i != curT; ++i)
{
_data.threads[i]->join();
delete _data.threads[i];

}
Lock lock1 (_data.taskMutex);
#ifdef ILMBASE_FORCE_CXX03
Lock lock2 (_data.stopMutex);
Expand Down
7 changes: 7 additions & 0 deletions IlmBase/IlmThread/IlmThreadPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ Thread::~Thread ()
assert (error == 0);
}

void
Thread::join ()
{
int error = ::pthread_join (_thread, 0);
assert (error == 0);
}


void
Thread::start ()
Expand Down
8 changes: 8 additions & 0 deletions IlmBase/IlmThread/IlmThreadWin32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ Thread::~Thread ()
assert (ok);
}

void
Thread::join ()
{
DWORD status = ::WaitForSingleObject (_thread, INFINITE);
assert (status == WAIT_OBJECT_0);
bool ok = ::CloseHandle (_thread) != FALSE;
assert (ok);
}

void
Thread::start ()
Expand Down
8 changes: 4 additions & 4 deletions OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ class LineCompositeTask : public Task

};


void
composite_line(int y,
int start,
Expand Down Expand Up @@ -386,16 +385,17 @@ composite_line(int y,
{

float value = output_pixel[ _Data->_bufferMap[channel_number] ]; // value to write

intptr_t base = reinterpret_cast<intptr_t>(it.slice().base);

// cast to half float if necessary
if(it.slice().type==OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
{
* (float *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = value;

* reinterpret_cast<float*>(base + y*it.slice().yStride + x*it.slice().xStride) = value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These statements sure would be easier to read split in two, with a pointer variable assignment followed by the *ptr = value:

float* ptr = reinterpret_cast<float*>(base + y*it.slice().yStride + x*it.slice().xStride);
*ptr = value;

}
else if(it.slice().type==HALF)
{
* (half *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = half(value);
* reinterpret_cast<half*>(base + y*it.slice().yStride + x*it.slice().xStride) = half(value);
}

channel_number++;
Expand Down
28 changes: 23 additions & 5 deletions OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,20 @@ DeepScanLineInputFile::readPixels (int scanLine)
}


namespace
{
struct I64Bytes
{
uint8_t b[8];
};


union bytesOrInt64
{
I64Bytes b;
Int64 i;
};
}
void
DeepScanLineInputFile::rawPixelData (int firstScanLine,
char *pixelData,
Expand Down Expand Up @@ -1507,12 +1521,16 @@ DeepScanLineInputFile::rawPixelData (int firstScanLine,

// copy the values we have read into the output block
*(int *) pixelData = yInFile;
*(Int64 *) (pixelData+4) =sampleCountTableSize;
*(Int64 *) (pixelData+12) = packedDataSize;

bytesOrInt64 tmp;
tmp.i=sampleCountTableSize;
memcpy(pixelData+4,&tmp.b,8);
tmp.i = packedDataSize;
memcpy(pixelData+12,&tmp.b,8);

// didn't read the unpackedsize - do that now
Xdr::read<StreamIO> (*_data->_streamData->is, *(Int64 *) (pixelData+20));

Xdr::read<StreamIO> (*_data->_streamData->is,tmp.i);
memcpy(pixelData+20,&tmp.b,8);

// read the actual data
_data->_streamData->is->read(pixelData+28, sampleCountTableSize+packedDataSize);

Expand Down
30 changes: 27 additions & 3 deletions OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,23 @@ DeepScanLineOutputFile::copyPixels (DeepScanLineInputPart &in)
copyPixels(*in.file);
}


// helper structure to read Int64 from non 8 byte aligned addresses
namespace
{
struct I64Bytes
{
uint8_t b[8];
};


union bytesOrInt64
{
I64Bytes b;
Int64 i;
};
}

void
DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in)
{
Expand Down Expand Up @@ -1487,9 +1504,16 @@ DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in)

// extract header from block to pass to writePixelData

Int64 packedSampleCountSize = *(Int64 *) (&data[4]);
Int64 packedDataSize = *(Int64 *) (&data[12]);
Int64 unpackedDataSize = *(Int64 *) (&data[20]);
bytesOrInt64 tmp;
memcpy(&tmp.b,&data[4],8);
Int64 packedSampleCountSize = tmp.i;

memcpy(&tmp.b,&data[12],8);
Int64 packedDataSize = tmp.i;

memcpy(&tmp.b,&data[20],8);
Int64 unpackedDataSize = tmp.i;

const char * sampleCountTable = &data[0]+28;
const char * pixelData = sampleCountTable + packedSampleCountSize;

Expand Down
4 changes: 2 additions & 2 deletions OpenEXR/IlmImf/ImfFrameBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Slice::Make (
bool xTileCoords,
bool yTileCoords)
{
char* base = reinterpret_cast<char*> (const_cast<void *> (ptr));
intptr_t base = reinterpret_cast<intptr_t> (const_cast<void *> (ptr));
if (xStride == 0)
{
switch (type)
Expand Down Expand Up @@ -117,7 +117,7 @@ Slice::Make (

return Slice (
type,
base - offx - offy,
reinterpret_cast<char*>(base - offx - offy),
xStride,
yStride,
xSampling,
Expand Down
13 changes: 8 additions & 5 deletions OpenEXR/IlmImf/ImfInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
while (modp (yStart, toSlice.ySampling) != 0)
++yStart;


intptr_t fromBase = reinterpret_cast<intptr_t>(fromSlice.base);
intptr_t toBase = reinterpret_cast<intptr_t>(toSlice.base);

for (int y = yStart;
y <= maxYThisRow;
y += toSlice.ySampling)
Expand All @@ -316,14 +320,13 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
// Set the pointers to the start of the y scanline in
// this row of tiles
//

fromPtr = fromSlice.base +
fromPtr = reinterpret_cast<char*> (fromBase +
(y - tileRange.min.y) * fromSlice.yStride +
xStart * fromSlice.xStride;
xStart * fromSlice.xStride);

toPtr = toSlice.base +
toPtr = reinterpret_cast<char*> (toBase +
divp (y, toSlice.ySampling) * toSlice.yStride +
divp (xStart, toSlice.xSampling) * toSlice.xStride;
divp (xStart, toSlice.xSampling) * toSlice.xStride);

//
// Copy all pixels for the scanline in this row of tiles
Expand Down
9 changes: 6 additions & 3 deletions OpenEXR/IlmImf/ImfMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1390,9 +1390,10 @@ namespace
//

struct FBytes { uint8_t b[4]; };
union bytesOrFloat {
union bytesUintOrFloat {
FBytes b;
float f;
unsigned int u;
} ;
}

Expand All @@ -1408,7 +1409,9 @@ convertInPlace (char *& writePtr,

for (size_t j = 0; j < numPixels; ++j)
{
Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
union bytesUintOrFloat tmp;
tmp.b = * reinterpret_cast<const FBytes *>( readPtr );
Xdr::write <CharPtrIO> (writePtr, tmp.u);
readPtr += sizeof(unsigned int);
}
break;
Expand All @@ -1426,7 +1429,7 @@ convertInPlace (char *& writePtr,

for (size_t j = 0; j < numPixels; ++j)
{
union bytesOrFloat tmp;
union bytesUintOrFloat tmp;
tmp.b = * reinterpret_cast<const FBytes *>( readPtr );
Xdr::write <CharPtrIO> (writePtr, tmp.f);
readPtr += sizeof(float);
Expand Down
15 changes: 10 additions & 5 deletions OpenEXR/IlmImf/ImfOutputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,13 +558,18 @@ LineBufferTask::execute ()
// If necessary, convert the pixel data to Xdr format.
// Then store the pixel data in _ofd->lineBuffer.
//

const char *linePtr = slice.base +
divp (y, slice.ySampling) *
// slice.base may be 'negative' but
// pointer arithmetic is not allowed to overflow, so
// perform computation with the non-pointer 'intptr_t' instead
//
intptr_t base = reinterpret_cast<intptr_t>(slice.base);
intptr_t linePtr = base + divp (y, slice.ySampling) *
slice.yStride;

const char *readPtr = linePtr + dMinX * slice.xStride;
const char *endPtr = linePtr + dMaxX * slice.xStride;
const char *readPtr = reinterpret_cast<const char*>(linePtr +
dMinX * slice.xStride);
const char *endPtr = reinterpret_cast<const char*>(linePtr +
dMaxX * slice.xStride);

copyFromFrameBuffer (writePtr, readPtr, endPtr,
slice.xStride, _ofd->format,
Expand Down
20 changes: 14 additions & 6 deletions OpenEXR/IlmImf/ImfRgbaFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines)
"\"" << _outputFile.fileName() << "\".");
}

intptr_t base = reinterpret_cast<intptr_t>(_fbBase);
if (_writeY && !_writeC)
{
//
Expand All @@ -385,8 +386,9 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines)

for (int j = 0; j < _width; ++j)
{
_tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine +
_fbXStride * (j + _xMin)];
_tmpBuf[j] = *reinterpret_cast<Rgba*>(base + sizeof(Rgba)*
(_fbYStride * _currentScanLine +
_fbXStride * (j + _xMin)));
}

//
Expand Down Expand Up @@ -418,10 +420,12 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines)
// frame buffer into _tmpBuf.
//

intptr_t base = reinterpret_cast<intptr_t>(_fbBase);

for (int j = 0; j < _width; ++j)
{
_tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine +
_fbXStride * (j + _xMin)];
_tmpBuf[j + N2] = *reinterpret_cast<const Rgba*>(base+sizeof(Rgba)*
(_fbYStride * _currentScanLine + _fbXStride * (j + _xMin)) );
}

//
Expand Down Expand Up @@ -1081,9 +1085,13 @@ RgbaInputFile::FromYca::readPixels (int scanLine)

fixSaturation (_yw, _width, _buf2, _tmpBuf);

for (int i = 0; i < _width; ++i)
_fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];

intptr_t base = reinterpret_cast<intptr_t>(_fbBase);
for (int i = 0; i < _width; ++i)
{
*reinterpret_cast<Rgba*>(base + sizeof(Rgba)*
(_fbYStride * scanLine + _fbXStride * (i + _xMin))) = _tmpBuf[i];
}
_currentScanLine = scanLine;
}

Expand Down
19 changes: 11 additions & 8 deletions OpenEXR/IlmImf/ImfScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,12 +636,14 @@ LineBufferTask::execute ()
// The frame buffer contains a slice for this channel.
//

char *linePtr = slice.base +
intptr_t base = reinterpret_cast<intptr_t>(slice.base);

intptr_t linePtr = base +
intptr_t( divp (y, slice.ySampling) ) *
intptr_t( slice.yStride );

char *writePtr = linePtr + intptr_t( dMinX ) * intptr_t( slice.xStride );
char *endPtr = linePtr + intptr_t( dMaxX ) * intptr_t( slice.xStride );
char *writePtr = reinterpret_cast<char*> (linePtr + intptr_t( dMinX ) * intptr_t( slice.xStride ));
char *endPtr = reinterpret_cast<char*> (linePtr + intptr_t( dMaxX ) * intptr_t( slice.xStride ));

copyIntoFrameBuffer (readPtr, writePtr, endPtr,
slice.xStride, slice.fill,
Expand Down Expand Up @@ -794,20 +796,21 @@ void LineBufferTaskIIF::getWritePointer
outWritePointerRight = 0;
}

const char* linePtr1 = firstSlice.base +
intptr_t base = reinterpret_cast<intptr_t>(firstSlice.base);

intptr_t linePtr1 = (base +
divp (y, firstSlice.ySampling) *
firstSlice.yStride;
firstSlice.yStride);

int dMinX1 = divp (_ifd->minX, firstSlice.xSampling);
int dMaxX1 = divp (_ifd->maxX, firstSlice.xSampling);

// Construct the writePtr so that we start writing at
// linePtr + Min offset in the line.
outWritePointerRight = (unsigned short*)(linePtr1 +
outWritePointerRight = reinterpret_cast<unsigned short*>(linePtr1 +
dMinX1 * firstSlice.xStride );

size_t bytesToCopy = ((linePtr1 + dMaxX1 * firstSlice.xStride ) -
(linePtr1 + dMinX1 * firstSlice.xStride )) + 2;
size_t bytesToCopy = ((dMaxX1 * firstSlice.xStride ) - (dMinX1 * firstSlice.xStride )) + 2;
size_t shortsToCopy = bytesToCopy / sizeOfSingleValue;
size_t pixelsToCopy = (shortsToCopy / nbSlicesInBank ) + 1;

Expand Down
Loading