Revert accidentally pushed "LCEMP RCE fixes"

This reverts commit d557ca2dfb.
This commit is contained in:
Loki Rautio
2026-03-09 04:46:56 -05:00
parent d557ca2dfb
commit a358a3caae
27 changed files with 80 additions and 222 deletions

View File

@@ -47,7 +47,7 @@ void AwardStatPacket::read(DataInputStream *dis) //throws IOException
// Read parameter blob. // Read parameter blob.
int length = dis->readInt(); int length = dis->readInt();
if (length > 0 && length <= 65536) if(length > 0)
{ {
m_paramData = byteArray(length); m_paramData = byteArray(length);
dis->readFully(m_paramData); dis->readFully(m_paramData);

View File

@@ -105,12 +105,6 @@ void BlockRegionUpdatePacket::read(DataInputStream *dis) //throws IOException
levelIdx = ( size >> 30 ) & 3; levelIdx = ( size >> 30 ) & 3;
size &= 0x3fffffff; size &= 0x3fffffff;
const int MAX_COMPRESSED_CHUNK_SIZE = 5 * 1024 * 1024;
if (size < 0 || size > MAX_COMPRESSED_CHUNK_SIZE)
{
size = 0;
}
if(size == 0) if(size == 0)
{ {
buffer = byteArray(); buffer = byteArray();

View File

@@ -10,19 +10,8 @@
//offset - the offset in the buffer of the first byte to read. //offset - the offset in the buffer of the first byte to read.
//length - the maximum number of bytes to read from the buffer. //length - the maximum number of bytes to read from the buffer.
ByteArrayInputStream::ByteArrayInputStream(byteArray buf, unsigned int offset, unsigned int length) ByteArrayInputStream::ByteArrayInputStream(byteArray buf, unsigned int offset, unsigned int length)
: pos(offset), mark(offset) : pos( offset ), count( min( offset+length, buf.length ) ), mark( offset )
{ {
if (offset > buf.length)
{
count = buf.length;
}
else if (length > buf.length - offset)
{
count = buf.length;
}
else
{
count = offset + length;
this->buf = buf; this->buf = buf;
} }

View File

@@ -53,25 +53,9 @@ void ByteArrayOutputStream::write(byteArray b, unsigned int offset, unsigned int
{ {
assert( b.length >= offset + length ); assert( b.length >= offset + length );
if (offset > b.length || length > b.length - offset)
{
return;
}
if (length > 0xFFFFFFFF - count)
{
return;
// If we will fill the buffer we need to make it bigger // If we will fill the buffer we need to make it bigger
if( count + length >= buf.length ) if( count + length >= buf.length )
{ buf.resize( max( count + length + 1, buf.length * 2 ) );
unsigned int newSize = (std::max)(count + length + 1, buf.length * 2);
if (newSize <= buf.length)
{
return;
}
buf.resize(newSize);
}
XMemCpy( &buf[count], &b[offset], length ); XMemCpy( &buf[count], &b[offset], length );
//std::copy( b->data+offset, b->data+offset+length, buf->data + count ); // Or this instead? //std::copy( b->data+offset, b->data+offset+length, buf->data + count ); // Or this instead?

View File

@@ -21,7 +21,6 @@ public:
void load(DataInput *dis, int tagDepth) void load(DataInput *dis, int tagDepth)
{ {
int length = dis->readInt(); int length = dis->readInt();
if (length < 0 || length > 2 * 1024 * 1024) length = 0;
if ( data.data ) delete[] data.data; if ( data.data ) delete[] data.data;
data = byteArray(length); data = byteArray(length);

View File

@@ -32,12 +32,7 @@ void ComplexItemDataPacket::read(DataInputStream *dis) //throws IOException
itemType = dis->readShort(); itemType = dis->readShort();
itemId = dis->readShort(); itemId = dis->readShort();
int dataLength = dis->readShort() & 0xffff; data = charArray(dis->readUnsignedShort() & 0xffff);
if (dataLength > 32767)
{
dataLength = 0;
}
data = charArray(dataLength);
dis->readFully(data); dis->readFully(data);
} }

View File

@@ -42,15 +42,9 @@ public:
} }
tags.clear(); tags.clear();
Tag *tag; Tag *tag;
int tagCount = 0;
const int MAX_COMPOUND_TAGS = 10000;
while ((tag = Tag::readNamedTag(dis))->getId() != Tag::TAG_End) while ((tag = Tag::readNamedTag(dis))->getId() != Tag::TAG_End)
{ {
tags[tag->getName()] = tag; tags[tag->getName()] = tag;
if (++tagCount >= MAX_COMPOUND_TAGS)
{
break;
}
} }
delete tag; delete tag;
} }

View File

@@ -108,8 +108,8 @@ Connection::Connection(Socket *socket, const wstring& id, PacketListener *packet
const char *szId = wstringtofilename(id); const char *szId = wstringtofilename(id);
char readThreadName[256]; char readThreadName[256];
char writeThreadName[256]; char writeThreadName[256];
sprintf_s(readThreadName, sizeof(readThreadName), "%.240s read\n", szId); sprintf(readThreadName,"%s read\n",szId);
sprintf_s(writeThreadName, sizeof(writeThreadName), "%.240s write\n", szId); sprintf(writeThreadName,"%s write\n",szId);
readThread = new C4JThread(runRead, static_cast<void *>(this), readThreadName, READ_STACK_SIZE); readThread = new C4JThread(runRead, static_cast<void *>(this), readThreadName, READ_STACK_SIZE);
writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE); writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE);

View File

@@ -32,9 +32,6 @@ void ContainerSetContentPacket::read(DataInputStream *dis) //throws IOException
{ {
containerId = dis->readByte(); containerId = dis->readByte();
int count = dis->readShort(); int count = dis->readShort();
if (count < 0 || count > 256) count = 0;
items = ItemInstanceArray(count); items = ItemInstanceArray(count);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {

View File

@@ -35,7 +35,7 @@ void ContainerSetSlotPacket::read(DataInputStream *dis) //throws IOException
// 4J Stu - TU-1 hotfix // 4J Stu - TU-1 hotfix
// Fix for #13142 - Holding down the A button on the furnace ingredient slot causes the UI to display incorrect item counts // Fix for #13142 - Holding down the A button on the furnace ingredient slot causes the UI to display incorrect item counts
BYTE byteId = dis->readByte(); BYTE byteId = dis->readByte();
containerId = (char)(signed char)byteId; containerId = *(char *)&byteId;
slot = dis->readShort(); slot = dis->readShort();
item = readItem(dis); item = readItem(dis);
} }

View File

@@ -43,7 +43,7 @@ void CustomPayloadPacket::read(DataInputStream *dis)
identifier = readUtf(dis, 20); identifier = readUtf(dis, 20);
length = dis->readShort(); length = dis->readShort();
if (length > 0 && length <= Short::MAX_VALUE) if (length > 0 && length < Short::MAX_VALUE)
{ {
if(data.data != nullptr) if(data.data != nullptr)
{ {

View File

@@ -303,10 +303,6 @@ wstring DataInputStream::readUTF()
int b = stream->read(); int b = stream->read();
unsigned short UTFLength = static_cast<unsigned short>(((a & 0xff) << 8) | (b & 0xff)); unsigned short UTFLength = static_cast<unsigned short>(((a & 0xff) << 8) | (b & 0xff));
const unsigned short MAX_UTF_LENGTH = 32767;
if (UTFLength > MAX_UTF_LENGTH)
return outputString;
//// 4J Stu - I decided while writing DataOutputStream that we didn't need to bother using the UTF8 format //// 4J Stu - I decided while writing DataOutputStream that we didn't need to bother using the UTF8 format
//// used in the java libs, and just write in/out as wchar_t all the time //// used in the java libs, and just write in/out as wchar_t all the time

View File

@@ -52,8 +52,6 @@ void ExplodePacket::read(DataInputStream *dis) //throws IOException
r = dis->readFloat(); r = dis->readFloat();
int count = dis->readInt(); int count = dis->readInt();
if (count < 0 || count > 32768) count = 0;
int xp = static_cast<int>(x); int xp = static_cast<int>(x);
int yp = static_cast<int>(y); int yp = static_cast<int>(y);
int zp = static_cast<int>(z); int zp = static_cast<int>(z);

View File

@@ -40,7 +40,7 @@ void GameCommandPacket::read(DataInputStream *dis)
command = static_cast<EGameCommand>(dis->readInt()); command = static_cast<EGameCommand>(dis->readInt());
length = dis->readShort(); length = dis->readShort();
if (length > 0 && length <= Short::MAX_VALUE) if (length > 0 && length < Short::MAX_VALUE)
{ {
if(data.data != nullptr) if(data.data != nullptr)
{ {

View File

@@ -35,8 +35,6 @@ public:
void load(DataInput *dis, int tagDepth) void load(DataInput *dis, int tagDepth)
{ {
int length = dis->readInt(); int length = dis->readInt();
if (length < 0 || length > 65536)
length = 0;
if ( data.data ) delete[] data.data; if ( data.data ) delete[] data.data;
data = intArray(length); data = intArray(length);

View File

@@ -26,16 +26,21 @@ public:
void load(DataInput *dis, int tagDepth) void load(DataInput *dis, int tagDepth)
{ {
if (tagDepth > MAX_DEPTH)
{
#ifndef _CONTENT_PACKAGE
printf("Tried to read NBT tag with too high complexity, depth > %d", MAX_DEPTH);
__debugbreak();
#endif
return;
}
type = dis->readByte(); type = dis->readByte();
int size = dis->readInt(); int size = dis->readInt();
if (size < 0 || size > MAX_DEPTH)
size = 0;
list.clear(); list.clear();
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
Tag *tag = Tag::newTag(type, L""); Tag *tag = Tag::newTag(type, L"");
if (tag == nullptr) break;
tag->load(dis, tagDepth); tag->load(dis, tagDepth);
list.push_back(tag); list.push_back(tag);
} }

View File

@@ -267,12 +267,8 @@ void Packet::updatePacketStatsPIX()
shared_ptr<Packet> Packet::getPacket(int id) shared_ptr<Packet> Packet::getPacket(int id)
{ {
auto it = idToCreateMap.find(id); // 4J: Removed try/catch
if (it == idToCreateMap.end()) return idToCreateMap[id]();
{
return nullptr;
}
return it->second();
} }
void Packet::writeBytes(DataOutputStream *dataoutputstream, byteArray bytes) void Packet::writeBytes(DataOutputStream *dataoutputstream, byteArray bytes)
@@ -338,11 +334,30 @@ shared_ptr<Packet> Packet::readPacket(DataInputStream *dis, bool isServer) // th
if ((isServer && serverReceivedPackets.find(id) == serverReceivedPackets.end()) || (!isServer && clientReceivedPackets.find(id) == clientReceivedPackets.end())) if ((isServer && serverReceivedPackets.find(id) == serverReceivedPackets.end()) || (!isServer && clientReceivedPackets.find(id) == clientReceivedPackets.end()))
{ {
return nullptr; app.DebugPrintf("*** BAD PACKET ID %d (0x%02X) isServer=%d totalPacketsRead=%d\n", id, id, isServer ? 1 : 0, s_packetCount);
app.DebugPrintf("*** Last %d good packet IDs (oldest first): ", 8);
for (int dbg = 0; dbg < 8; dbg++)
{
int idx = (s_lastIdPos + dbg) % 8;
app.DebugPrintf("%d ", s_lastIds[idx]);
}
app.DebugPrintf("\n");
// Dump the next 32 bytes from the stream to see what follows
app.DebugPrintf("*** Next bytes in stream: ");
for (int dbg = 0; dbg < 32; dbg++)
{
int b = dis->read();
if (b == -1) { app.DebugPrintf("[EOS] "); break; }
app.DebugPrintf("%02X ", b);
}
app.DebugPrintf("\n");
__debugbreak();
assert(false);
// throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id));
} }
packet = getPacket(id); packet = getPacket(id);
if (packet == nullptr) return nullptr;//throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id)); if (packet == nullptr) assert(false);//throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id));
s_lastIds[s_lastIdPos] = id; s_lastIds[s_lastIdPos] = id;
s_lastIdPos = (s_lastIdPos + 1) % 8; s_lastIdPos = (s_lastIdPos + 1) % 8;
@@ -403,9 +418,11 @@ wstring Packet::readUtf(DataInputStream *dis, int maxLength) // throws IOExcepti
{ {
short stringLength = dis->readShort(); short stringLength = dis->readShort();
if (stringLength > maxLength || stringLength <= 0) if (stringLength > maxLength)
{ {
return L""; wstringstream stream;
stream << L"Received string length longer than maximum allowed (" << stringLength << " > " << maxLength << ")";
assert(false);
// throw new IOException( stream.str() ); // throw new IOException( stream.str() );
} }
if (stringLength < 0) if (stringLength < 0)
@@ -514,7 +531,7 @@ shared_ptr<ItemInstance> Packet::readItem(DataInputStream *dis)
{ {
shared_ptr<ItemInstance> item = nullptr; shared_ptr<ItemInstance> item = nullptr;
int id = dis->readShort(); int id = dis->readShort();
if (id >= 0 && id < 32000) // todo: should turn Item::ITEM_NUM_COUNT into a global define if (id >= 0)
{ {
int count = dis->readByte(); int count = dis->readByte();
int damage = dis->readShort(); int damage = dis->readShort();
@@ -552,16 +569,9 @@ void Packet::writeItem(shared_ptr<ItemInstance> item, DataOutputStream *dos)
CompoundTag *Packet::readNbt(DataInputStream *dis) CompoundTag *Packet::readNbt(DataInputStream *dis)
{ {
int size = dis->readShort(); int size = dis->readShort();
if (size <= 0) return nullptr; if (size < 0) return nullptr;
const int MAX_NBT_SIZE = 32767;
if (size > MAX_NBT_SIZE) return nullptr;
byteArray buff(size); byteArray buff(size);
if (!dis->readFully(buff)) dis->readFully(buff);
{
delete [] buff.data;
return nullptr;
}
CompoundTag *result = (CompoundTag *) NbtIo::decompress(buff); CompoundTag *result = (CompoundTag *) NbtIo::decompress(buff);
delete [] buff.data; delete [] buff.data;
return result; return result;

View File

@@ -62,7 +62,6 @@ void PreLoginPacket::read(DataInputStream *dis) //throws IOException
m_friendsOnlyBits = dis->readByte(); m_friendsOnlyBits = dis->readByte();
m_ugcPlayersVersion = dis->readInt(); m_ugcPlayersVersion = dis->readInt();
m_dwPlayerCount = dis->readByte(); m_dwPlayerCount = dis->readByte();
if( m_dwPlayerCount > MINECRAFT_NET_MAX_PLAYERS ) m_dwPlayerCount = MINECRAFT_NET_MAX_PLAYERS;
if( m_dwPlayerCount > 0 ) if( m_dwPlayerCount > 0 )
{ {
m_playerXuids = new PlayerUID[m_dwPlayerCount]; m_playerXuids = new PlayerUID[m_dwPlayerCount];

View File

@@ -21,9 +21,7 @@ RemoveEntitiesPacket::~RemoveEntitiesPacket()
void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException
{ {
int count = dis->readByte(); ids = intArray(dis->readByte());
if(count < 0) count = 0;
ids = intArray(count);
for(unsigned int i = 0; i < ids.length; ++i) for(unsigned int i = 0; i < ids.length; ++i)
{ {
ids[i] = dis->readInt(); ids[i] = dis->readInt();

View File

@@ -141,11 +141,6 @@ void Socket::pushDataToQueue(const BYTE * pbData, DWORD dwDataSize, bool fromHos
// dwDataSize, queueIdx, dwDataSize > 0 ? pbData[0] : 0, networkPlayerSmallId); // dwDataSize, queueIdx, dwDataSize > 0 ? pbData[0] : 0, networkPlayerSmallId);
EnterCriticalSection(&m_queueLockNetwork[queueIdx]); EnterCriticalSection(&m_queueLockNetwork[queueIdx]);
if (m_queueNetwork[queueIdx].size() + dwDataSize > 2 * 1024 * 1024)
{
LeaveCriticalSection(&m_queueLockNetwork[queueIdx]);
return;
}
for( unsigned int i = 0; i < dwDataSize; i++ ) for( unsigned int i = 0; i < dwDataSize; i++ )
{ {
m_queueNetwork[queueIdx].push(*pbData++); m_queueNetwork[queueIdx].push(*pbData++);

View File

@@ -342,10 +342,7 @@ vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(Data
int currentHeader = input->readByte(); int currentHeader = input->readByte();
int itemCount = 0; while (currentHeader != EOF_MARKER)
const int MAX_ENTITY_DATA_ITEMS = 256;
while (currentHeader != EOF_MARKER && itemCount < MAX_ENTITY_DATA_ITEMS)
{ {
if (result == nullptr) if (result == nullptr)
@@ -400,7 +397,6 @@ vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(Data
break; break;
} }
result->push_back(item); result->push_back(item);
itemCount++;
currentHeader = input->readByte(); currentHeader = input->readByte();
} }

View File

@@ -84,56 +84,27 @@ Tag *Tag::readNamedTag(DataInput *dis)
Tag *Tag::readNamedTag(DataInput *dis, int tagDepth) Tag *Tag::readNamedTag(DataInput *dis, int tagDepth)
{ {
static __declspec(thread) int depth = 0;
static __declspec(thread) int totalTagCount = 0;
if (depth == 0)
{
totalTagCount = 0;
}
depth++;
if (depth > 256)
{
depth--;
return new EndTag();
}
totalTagCount++;
const int MAX_TOTAL_TAGS = 32768;
if (totalTagCount > MAX_TOTAL_TAGS)
{
depth--;
return new EndTag();
}
byte type = dis->readByte(); byte type = dis->readByte();
if (type == 0) { if (type == 0) return new EndTag();
depth--;
return new EndTag();
}
// 4J Stu - readByte can return -1, so if it's that then also mark as the end tag // 4J Stu - readByte can return -1, so if it's that then also mark as the end tag
if(type == 255) if(type == 255)
{ {
depth--; app.DebugPrintf("readNamedTag read a type of 255\n");
#ifndef _CONTENT_PACKAGE
__debugbreak();
#endif
return new EndTag(); return new EndTag();
} }
wstring name = dis->readUTF();//new String(bytes, "UTF-8"); wstring name = dis->readUTF();//new String(bytes, "UTF-8");
Tag *tag = newTag(type, name); Tag *tag = newTag(type, name);
if (tag == nullptr) {
depth--;
return new EndTag();
}
// short length = dis.readShort(); // short length = dis.readShort();
// byte[] bytes = new byte[length]; // byte[] bytes = new byte[length];
// dis.readFully(bytes); // dis.readFully(bytes);
tag->load(dis, tagDepth); tag->load(dis, tagDepth);
depth--;
return tag; return tag;
} }

View File

@@ -121,20 +121,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
{ {
textureName = dis->readUTF(); textureName = dis->readUTF();
dwSkinID = static_cast<DWORD>(dis->readInt()); dwSkinID = static_cast<DWORD>(dis->readInt());
dwTextureBytes = static_cast<DWORD>(dis->readShort());
short rawTextureBytes = dis->readShort();
if (rawTextureBytes <= 0)
{
dwTextureBytes = 0;
}
else
{
dwTextureBytes = (DWORD)(unsigned short)rawTextureBytes;
if (dwTextureBytes > 65536)
{
dwTextureBytes = 0;
}
}
if(dwTextureBytes>0) if(dwTextureBytes>0)
{ {
@@ -147,19 +134,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
} }
uiAnimOverrideBitmask = dis->readInt(); uiAnimOverrideBitmask = dis->readInt();
short rawBoxC = dis->readShort(); dwBoxC = static_cast<DWORD>(dis->readShort());
if (rawBoxC <= 0)
{
dwBoxC = 0;
}
else
{
dwBoxC = (DWORD)(unsigned short)rawBoxC;
if (dwBoxC > 256)
{
dwBoxC = 0; // sane limit for skin boxes
}
}
if(dwBoxC>0) if(dwBoxC>0)
{ {

View File

@@ -37,26 +37,17 @@ void TexturePacket::handle(PacketListener *listener)
void TexturePacket::read(DataInputStream *dis) //throws IOException void TexturePacket::read(DataInputStream *dis) //throws IOException
{ {
textureName = dis->readUTF(); textureName = dis->readUTF();
short rawBytes = dis->readShort(); dwBytes = static_cast<DWORD>(dis->readShort());
if (rawBytes <= 0)
{
dwBytes = 0;
return;
}
dwBytes = (DWORD)(unsigned short)rawBytes;
if (dwBytes > 65536)
{
dwBytes = 0;
return;
}
if(dwBytes>0)
{
this->pbData= new BYTE [dwBytes]; this->pbData= new BYTE [dwBytes];
for(DWORD i=0;i<dwBytes;i++) for(DWORD i=0;i<dwBytes;i++)
{ {
this->pbData[i] = dis->readByte(); this->pbData[i] = dis->readByte();
} }
}
} }
void TexturePacket::write(DataOutputStream *dos) //throws IOException void TexturePacket::write(DataOutputStream *dos) //throws IOException

View File

@@ -22,9 +22,9 @@ void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
#if ( defined _WINDOWS64 | defined _DURANGO ) #if ( defined _WINDOWS64 | defined _DURANGO )
__try __try
{ {
RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR *)&info); RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR *)&info );
} }
__except (EXCEPTION_EXECUTE_HANDLER) __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
{ {
} }
#endif #endif

View File

@@ -18,7 +18,7 @@ UpdateGameRuleProgressPacket::UpdateGameRuleProgressPacket(ConsoleGameRules::EGa
m_auxValue = auxValue; m_auxValue = auxValue;
m_dataTag = dataTag; m_dataTag = dataTag;
if (dataLength > 0 && dataLength <= 65536) if(dataLength > 0)
{ {
m_data = byteArray(dataLength); m_data = byteArray(dataLength);
memcpy(m_data.data,data,dataLength); memcpy(m_data.data,data,dataLength);

View File

@@ -237,19 +237,9 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
unsigned char *dynamicRleBuf = nullptr; unsigned char *dynamicRleBuf = nullptr;
HRESULT decompressResult; HRESULT decompressResult;
unsigned int safeRleSize = max(rleSize, *pDestSize); if(*pDestSize > rleSize)
const unsigned int MAX_RLE_ALLOC = 16 * 1024 * 1024; // 16 MB
if (safeRleSize > MAX_RLE_ALLOC)
{ {
LeaveCriticalSection(&rleDecompressLock); rleSize = *pDestSize;
*pDestSize = 0;
return E_FAIL;
}
if (safeRleSize > staticRleSize)
{
rleSize = safeRleSize;
dynamicRleBuf = new unsigned char[rleSize]; dynamicRleBuf = new unsigned char[rleSize];
decompressResult = Decompress(dynamicRleBuf, &rleSize, pSource, SrcSize); decompressResult = Decompress(dynamicRleBuf, &rleSize, pSource, SrcSize);
pucIn = (unsigned char *)dynamicRleBuf; pucIn = (unsigned char *)dynamicRleBuf;
@@ -273,7 +263,7 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
//unsigned char *pucIn = (unsigned char *)rleDecompressBuf; //unsigned char *pucIn = (unsigned char *)rleDecompressBuf;
const unsigned char *pucEnd = pucIn + rleSize; const unsigned char *pucEnd = pucIn + rleSize;
unsigned char *pucOut = static_cast<unsigned char*>(pDestination); unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
unsigned char *pucOutEnd = pucOut + *pDestSize; const unsigned char *pucOutEnd = pucOut + *pDestSize;
while( pucIn != pucEnd ) while( pucIn != pucEnd )
{ {
@@ -285,11 +275,7 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
if( count < 3 ) if( count < 3 )
{ {
count++; count++;
if (pucOut + count > pucOutEnd) if( pucOut + count > pucOutEnd ) break;
{
pucOut = pucOutEnd;
break;
}
for( unsigned int i = 0; i < count; i++ ) for( unsigned int i = 0; i < count; i++ )
{ {
*pucOut++ = 255; *pucOut++ = 255;
@@ -300,11 +286,7 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
count++; count++;
if( pucIn >= pucEnd ) break; if( pucIn >= pucEnd ) break;
const unsigned char data = *pucIn++; const unsigned char data = *pucIn++;
if (pucOut + count > pucOutEnd) if( pucOut + count > pucOutEnd ) break;
{
pucOut = pucOutEnd;
break;
}
for( unsigned int i = 0; i < count; i++ ) for( unsigned int i = 0; i < count; i++ )
{ {
*pucOut++ = data; *pucOut++ = data;
@@ -335,7 +317,7 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
unsigned char *pucIn = static_cast<unsigned char *>(pSource); unsigned char *pucIn = static_cast<unsigned char *>(pSource);
const unsigned char *pucEnd = pucIn + SrcSize; const unsigned char *pucEnd = pucIn + SrcSize;
unsigned char *pucOut = static_cast<unsigned char*>(pDestination); unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
unsigned char *pucOutEnd = pucOut + *pDestSize; const unsigned char *pucOutEnd = pucOut + *pDestSize;
while( pucIn != pucEnd ) while( pucIn != pucEnd )
{ {
@@ -347,11 +329,7 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
if( count < 3 ) if( count < 3 )
{ {
count++; count++;
if (pucOut + count > pucOutEnd) if( pucOut + count > pucOutEnd ) break;
{
pucOut = pucOutEnd;
break;
}
for( unsigned int i = 0; i < count; i++ ) for( unsigned int i = 0; i < count; i++ )
{ {
*pucOut++ = 255; *pucOut++ = 255;
@@ -362,11 +340,7 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
count++; count++;
if( pucIn >= pucEnd ) break; if( pucIn >= pucEnd ) break;
const unsigned char data = *pucIn++; const unsigned char data = *pucIn++;
if (pucOut + count > pucOutEnd) if( pucOut + count > pucOutEnd ) break;
{
pucOut = pucOutEnd;
break;
}
for( unsigned int i = 0; i < count; i++ ) for( unsigned int i = 0; i < count; i++ )
{ {
*pucOut++ = data; *pucOut++ = data;