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

Fix out-of-bounds writesin BitView::_Read64<true> #355

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
36 changes: 16 additions & 20 deletions src/util/BitView.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,32 +131,31 @@ class CPBitReader
const uint32 fieldBitIdx = (uint32)( position - fieldIndex * 64 ); // Value start bit position from the left (MSb) in the field itself
const uint32 bitsAvailable = 64 - fieldBitIdx;

uint32 shift = 64 - std::min( fieldBitIdx + bitCount, 64u );

const byte* pField = fields + fieldIndex * 8;
const size_t totalBytes = CDiv( sizeBits, 8 );
const byte* pField = fields + fieldIndex * 8;

uint32 shift = 64 - std::min( fieldBitIdx + bitCount, 64u );

const byte* pEnd;
uint64 field;
uint64 value;

// Check for aligned pointer
bool isPtrAligned;
bool isLastField;

if constexpr ( CheckAlignment )
{
isPtrAligned = ((uintptr_t)pField & 7) == 0; // % 8
isLastField = fieldIndex == ( sizeBits >> 6 ) - 1;

if( isPtrAligned && !isLastField )
pEnd = fields + totalBytes;
ASSERT(pField < pEnd);

isPtrAligned = ((uintptr_t)pField & 7) == 0;
const size_t remainderBytes = pEnd - pField;

if ( remainderBytes >= 8 )
field = *((uint64*)pField);
else if( !isLastField )
memcpy( &field, pField, sizeof( uint64 ) );
else
{
// No guarantee that the last field is complete, so copy only the bytes we know we have
const size_t totalBytes = CDiv( sizeBits, 8 );
const int32 remainderBytes = (int32)( totalBytes - fieldIndex * 8 );

field = 0;
byte* fieldBytes = (byte*)&field;
for( int32 i = 0; i < remainderBytes; i++ )
Expand All @@ -176,16 +175,13 @@ class CPBitReader
if constexpr ( CheckAlignment )
{
pField += 8;

if( isPtrAligned && !isLastField )
ASSERT(pField < pEnd);
const size_t remainderBytes = pEnd - pField;

if( remainderBytes >= 8 )
field = *((uint64*)pField);
else if( !isLastField )
memcpy( &field, pField, sizeof( uint64 ) );
else
{
const size_t totalBytes = CDiv( sizeBits, 8 );
const int32 remainderBytes = (int32)( totalBytes - fieldIndex * 8 );

field = 0;
byte* fieldBytes = (byte*)&field;
for( int32 i = 0; i < remainderBytes; i++ )
Expand Down