diff --git a/Source/BitStream.cpp b/Source/BitStream.cpp index d184c1735..8a8f2520f 100644 --- a/Source/BitStream.cpp +++ b/Source/BitStream.cpp @@ -192,6 +192,9 @@ void BitStream::Write( BitStream *bitStream) } void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits ) { + if (numberOfBits > bitStream->GetNumberOfUnreadBits()) + return; + AddBitsAndReallocate( numberOfBits ); BitSize_t numberOfBitsMod8; @@ -205,7 +208,7 @@ void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits ) numberOfBitsUsed+=BYTES_TO_BITS(numBytes); } - while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed) + while (numberOfBits-->0) { numberOfBitsMod8 = numberOfBitsUsed & 7; if ( numberOfBitsMod8 == 0 ) @@ -274,7 +277,7 @@ bool BitStream::Read( char* outByteArray, const unsigned int numberOfBytes ) // Optimization: if ((readOffset & 7) == 0) { - if ( readOffset + ( numberOfBytes << 3 ) > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < (numberOfBytes << 3)) return false; // Write the data @@ -331,6 +334,10 @@ void BitStream::Write1( void ) // Returns true if the next data read is a 1, false if it is a 0 bool BitStream::ReadBit( void ) { + if (GetNumberOfUnreadBits() == 0) { + return false; + } + bool result = ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) !=0; readOffset++; return result; @@ -378,7 +385,7 @@ bool BitStream::ReadAlignedBytes( unsigned char* inOutByteArray, const unsigned // Byte align AlignReadToByteBoundary(); - if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < (numberOfBytesToRead << 3)) return false; // Write the data @@ -556,7 +563,7 @@ bool BitStream::ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsT if (numberOfBitsToRead<=0) return false; - if ( readOffset + numberOfBitsToRead > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < numberOfBitsToRead) return false; @@ -1038,7 +1045,7 @@ void BitStream::WriteAlignedVar8(const char *inByteArray) bool BitStream::ReadAlignedVar8(char *inOutByteArray) { RakAssert((readOffset&7)==0); - if ( readOffset + 1*8 > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < 1 * 8) return false; inOutByteArray[0] = data[( readOffset >> 3 ) + 0]; @@ -1067,7 +1074,7 @@ void BitStream::WriteAlignedVar16(const char *inByteArray) bool BitStream::ReadAlignedVar16(char *inOutByteArray) { RakAssert((readOffset&7)==0); - if ( readOffset + 2*8 > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < 2 * 8) return false; #ifndef __BITSTREAM_NATIVE_END if (DoEndianSwap()) @@ -1111,7 +1118,7 @@ void BitStream::WriteAlignedVar32(const char *inByteArray) bool BitStream::ReadAlignedVar32(char *inOutByteArray) { RakAssert((readOffset&7)==0); - if ( readOffset + 4*8 > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < 4 * 8) return false; #ifndef __BITSTREAM_NATIVE_END if (DoEndianSwap()) diff --git a/Source/BitStream.h b/Source/BitStream.h index ccb2e5d0c..9ba30c204 100644 --- a/Source/BitStream.h +++ b/Source/BitStream.h @@ -511,7 +511,7 @@ namespace RakNet void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;} /// \brief Returns the number of bits left in the stream that haven't been read - inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;} + inline BitSize_t GetNumberOfUnreadBits( void ) const { return readOffset > numberOfBitsUsed ? 0 : numberOfBitsUsed - readOffset; } /// \brief Makes a copy of the internal data for you \a _data will point to /// the stream. Partial bytes are left aligned. @@ -1474,7 +1474,7 @@ namespace RakNet template <> inline bool BitStream::Read(bool &outTemplateVar) { - if ( readOffset + 1 > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() == 0) return false; if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here? @@ -1524,7 +1524,7 @@ namespace RakNet inline bool BitStream::Read(uint24_t &outTemplateVar) { AlignReadToByteBoundary(); - if ( readOffset + 3*8 > numberOfBitsUsed ) + if (GetNumberOfUnreadBits() < 3 * 8) return false; if (IsBigEndian()==false)