Skip to content
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
8 changes: 8 additions & 0 deletions src/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2832,6 +2832,14 @@ uint32_t CProtocol::GetValFromStream ( const CVector<uint8_t>& vecIn, int& iPos,
Q_ASSERT ( ( iNumOfBytes > 0 ) && ( iNumOfBytes <= 4 ) );
Q_ASSERT ( vecIn.Size() >= iPos + iNumOfBytes );

// The asserts above are compiled out in release builds, so also guard at
// runtime: CVector uses unchecked operator[], and reading past the end of a

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might be removed...

// truncated/malformed network message would be an out-of-bounds access.
if ( ( iNumOfBytes < 1 ) || ( iNumOfBytes > 4 ) || ( vecIn.Size() < iPos + iNumOfBytes ) )
{
return 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's the question what it should actually return...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is conflating an error indication with a fetched value. In my view, the correct fix would be for the GetValFromStream() and GetCountryFromStream() functions to follow the format of GetStringFromStream(), where the output variable is passed by reference as a parameter, and the return value is a bool indicating error status (true) or success (false). Every fetch would then be validated and could abort the Evaluate function as soon as a malformation, bounds overflow or bad value was detected.

This would require all calls within protocol.cpp to be reworked, but I think it's worth doing, and shouldn't take too long. I'm happy to take that on if agreed,

Also, the runtime checks on iNumBytes are only checking against programmer error, not input data error, since every call to GetValFromStream() passes a constant 1, 2 or 4 as iNumBytes.

@ann0see ann0see Jul 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The data from the wire is definitely unchecked at the moment then?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like some values are checked, and others are just used without checking.

}

uint32_t iRet = 0;

for ( int i = 0; i < iNumOfBytes; i++ )
Expand Down
Loading