netcode crash fix
This commit is contained in:
parent
63062737ac
commit
89acf4da25
@ -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{
|
}
|
||||||
offset=2;
|
else {
|
||||||
opcode=ntohs(*(const uint16 *)buf);
|
// 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;
|
||||||
|
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;
|
||||||
|
@ -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,17 +292,18 @@ 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.
|
||||||
subp->copyInfo(p);
|
EQProtocolPacket *subp = new EQProtocolPacket(p->pBuffer + offset + 2, data_length, OP_Packet);
|
||||||
ProcessPacket(subp, p);
|
subp->copyInfo(p);
|
||||||
delete subp;
|
ProcessPacket(subp, p);
|
||||||
return true;
|
delete subp;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user