aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/authserver/Server/BattlenetBitStream.h42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h
index a59150f5327..8d4b36db8c5 100644
--- a/src/server/authserver/Server/BattlenetBitStream.h
+++ b/src/server/authserver/Server/BattlenetBitStream.h
@@ -30,15 +30,38 @@ namespace Battlenet
{
class BitStreamPositionException : public std::exception
{
+ static uint32 const MessageSize = ACE_Stack_Trace::SYMBUFSIZ + 128;
+
public:
- BitStreamPositionException() : st(1) { }
+ BitStreamPositionException(bool read, uint32 operationSize, uint32 position, uint32 streamSize)
+ {
+ memset(_message, 0, MessageSize);
+#ifndef TRINITY_DEBUG
+ snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\nStack trace:\n",
+ (read ? "read" : "write"),
+ operationSize + position,
+ (read ? "from" : "to"),
+ (read ? "exist" : "allowed"),
+ streamSize);
+#else
+ ACE_Stack_Trace st(1);
+ snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\nStack trace:\n%s",
+ (read ? "read" : "write"),
+ operationSize + position,
+ (read ? "from" : "to"),
+ (read ? "exist" : "allowed"),
+ streamSize,
+ st.c_str());
+#endif
+ }
- char const* what() const
+ char const* what() const throw()
{
- return st.c_str();
+ return _message;
}
- ACE_Stack_Trace st;
+ private:
+ char _message[MessageSize];
};
class BitStream
@@ -76,7 +99,7 @@ namespace Battlenet
{
AlignToNextByte();
if (_readPos + count * 8 > _numBits)
- throw BitStreamPositionException();
+ throw BitStreamPositionException(true, count * 8, _readPos, _numBits);
ACE_Auto_Array_Ptr<uint8> buf(new uint8[count]);
memcpy(buf.get(), &_buffer[_readPos >> 3], count);
@@ -109,6 +132,9 @@ namespace Battlenet
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type");
+ if (_readPos + bitCount >= _numBits)
+ throw BitStreamPositionException(true, bitCount, _readPos, _numBits);
+
uint64 ret = 0;
while (bitCount != 0)
{
@@ -139,7 +165,7 @@ namespace Battlenet
return;
if ((_writePos >> 3) + count > MaxSize)
- throw BitStreamPositionException();
+ throw BitStreamPositionException(false, count * 8, _writePos, MaxSize * 8);
_buffer.resize(_buffer.size() + count);
memcpy(&_buffer[_writePos >> 3], data, count);
@@ -170,7 +196,7 @@ namespace Battlenet
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type");
if (_writePos + bitCount >= 8 * MaxSize)
- throw BitStreamPositionException();
+ throw BitStreamPositionException(false, bitCount, _writePos, MaxSize * 8);
while (bitCount != 0)
{
@@ -196,7 +222,7 @@ namespace Battlenet
void SetReadPos(uint32 bits)
{
if (bits >= _numBits)
- throw BitStreamPositionException();
+ throw BitStreamPositionException(true, bits, 0, _numBits);
_readPos = bits;
}