1
0

netcode crash fix

This commit is contained in:
Emagi 2025-03-04 21:42:35 -05:00
parent 63062737ac
commit 89acf4da25
2 changed files with 52 additions and 29 deletions

View File

@ -218,25 +218,34 @@ void EQPacket::DumpRaw(FILE *to) const
EQProtocolPacket::EQProtocolPacket(const unsigned char *buf, uint32 len, int in_opcode) EQProtocolPacket::EQProtocolPacket(const unsigned char *buf, uint32 len, int in_opcode)
{ {
uint32 offset = 0; uint32 offset = 0;
if(in_opcode>=0) if(in_opcode>=0) {
opcode = in_opcode; opcode = in_opcode;
}
else { else {
// Ensure there are at least 2 bytes for the opcode
if (len < 2 || buf == nullptr) {
// Not enough data to read opcode; set defaults or handle error appropriately
opcode = 0; // or set to a designated invalid opcode
offset = len; // no payload available
} else {
offset = 2; offset = 2;
opcode = ntohs(*(const uint16 *)buf); opcode = ntohs(*(const uint16 *)buf);
} }
}
if (len-offset) { // Check that there is payload data after the header
pBuffer= new unsigned char[len-offset]; if (len > offset) {
size = len - offset; size = len - offset;
pBuffer = new unsigned char[size];
if(buf) if(buf)
memcpy(pBuffer,buf+offset,len-offset); memcpy(pBuffer, buf + offset, size);
else else
memset(pBuffer, 0, size); memset(pBuffer, 0, size);
} else { } else {
pBuffer=NULL; pBuffer = nullptr;
size = 0; size = 0;
} }
version = 0; version = 0;
eq2_compressed = false; eq2_compressed = false;
packet_prepared = false; packet_prepared = false;

View File

@ -224,16 +224,29 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset, int16 len
if(p->size >= ((uint32)(offset+2))){ if(p->size >= ((uint32)(offset+2))){
if(p->pBuffer[offset] == 0 && p->pBuffer[offset+1] == 0x19){ if(p->pBuffer[offset] == 0 && p->pBuffer[offset+1] == 0x19){
if(length == 0) uint32 data_length = 0;
length = p->size-2-offset; if(length == 0) {
else // Ensure there are at least 2 bytes after offset.
length-=2; if(p->size < offset + 2) {
return false; // Not enough data.
}
data_length = p->size - offset - 2;
} else {
// Ensure provided length is at least 2.
if(length < 2) {
return false; // Provided length too short.
}
data_length = length - 2;
}
#ifdef DEBUG_EMBEDDED_PACKETS #ifdef DEBUG_EMBEDDED_PACKETS
printf( "Creating OP_AppCombined Packet with offset %u, length %u, p->size %u\n", offset, length, p->size); printf( "Creating OP_AppCombined Packet with offset %u, length %u, p->size %u\n", offset, length, p->size);
DumpPacket(p->pBuffer, p->size); DumpPacket(p->pBuffer, p->size);
#endif #endif
// Verify that offset + 2 + data_length does not exceed p->size.
EQProtocolPacket *subp=new EQProtocolPacket(OP_AppCombined, p->pBuffer+2+offset, length); if(offset + 2 + data_length > p->size) {
return false; // Out-of-bounds.
}
EQProtocolPacket *subp = new EQProtocolPacket(OP_AppCombined, p->pBuffer + offset + 2, data_length);
subp->copyInfo(p); subp->copyInfo(p);
ProcessPacket(subp, p); ProcessPacket(subp, p);
safe_delete(subp); safe_delete(subp);
@ -279,13 +292,14 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset, int16 len
if(valid) if(valid)
return true; return true;
} }
else if(p->pBuffer[offset] != 0xff && p->pBuffer[offset+1] == 0xff && p->size > (1+offset)) { else if(p->pBuffer[offset] != 0xff && p->pBuffer[offset+1] == 0xff && p->size >= offset + 3) {
uint8 new_length = 0; // Read the first byte into a wider type to avoid underflow.
uint16 total_length = p->pBuffer[offset]; // promote to uint16
memcpy(&new_length, p->pBuffer+offset, sizeof(int8)); // Check that there is enough data: we expect offset+2+total_length == p->size.
if((new_length+offset+2) == p->size) { if(total_length + offset + 2 == p->size && total_length >= 2) {
new_length -= 2; uint32 data_length = total_length - 2;
EQProtocolPacket *subp=new EQProtocolPacket(p->pBuffer+offset+2, new_length, OP_Packet); // No additional bounds check needed because equality condition ensures it.
EQProtocolPacket *subp = new EQProtocolPacket(p->pBuffer + offset + 2, data_length, OP_Packet);
subp->copyInfo(p); subp->copyInfo(p);
ProcessPacket(subp, p); ProcessPacket(subp, p);
delete subp; delete subp;