diff --git a/source/common/EQPacket.cpp b/source/common/EQPacket.cpp index 499ac90..c2f9e1f 100644 --- a/source/common/EQPacket.cpp +++ b/source/common/EQPacket.cpp @@ -218,25 +218,34 @@ void EQPacket::DumpRaw(FILE *to) const EQProtocolPacket::EQProtocolPacket(const unsigned char *buf, uint32 len, int in_opcode) { uint32 offset = 0; - if(in_opcode>=0) + if(in_opcode>=0) { opcode = in_opcode; - else{ - offset=2; - opcode=ntohs(*(const uint16 *)buf); + } + 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; + opcode = ntohs(*(const uint16 *)buf); + } } - if (len-offset) { - pBuffer= new unsigned char[len-offset]; - size=len-offset; + // Check that there is payload data after the header + if (len > offset) { + size = len - offset; + pBuffer = new unsigned char[size]; if(buf) - memcpy(pBuffer,buf+offset,len-offset); + memcpy(pBuffer, buf + offset, size); else - memset(pBuffer,0,size); - + memset(pBuffer, 0, size); } else { - pBuffer=NULL; - size=0; + pBuffer = nullptr; + size = 0; } + version = 0; eq2_compressed = false; packet_prepared = false; diff --git a/source/common/EQStream.cpp b/source/common/EQStream.cpp index 6544496..bbaf3a9 100644 --- a/source/common/EQStream.cpp +++ b/source/common/EQStream.cpp @@ -224,16 +224,29 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset, int16 len if(p->size >= ((uint32)(offset+2))){ if(p->pBuffer[offset] == 0 && p->pBuffer[offset+1] == 0x19){ - if(length == 0) - length = p->size-2-offset; - else - length-=2; + uint32 data_length = 0; + if(length == 0) { + // Ensure there are at least 2 bytes after offset. + 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 printf( "Creating OP_AppCombined Packet with offset %u, length %u, p->size %u\n", offset, length, p->size); DumpPacket(p->pBuffer, p->size); #endif - - EQProtocolPacket *subp=new EQProtocolPacket(OP_AppCombined, p->pBuffer+2+offset, length); + // Verify that offset + 2 + data_length does not exceed p->size. + 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); ProcessPacket(subp, p); safe_delete(subp); @@ -279,17 +292,18 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset, int16 len if(valid) return true; } - else if(p->pBuffer[offset] != 0xff && p->pBuffer[offset+1] == 0xff && p->size > (1+offset)) { - uint8 new_length = 0; - - memcpy(&new_length, p->pBuffer+offset, sizeof(int8)); - if((new_length+offset+2) == p->size) { - new_length -= 2; - EQProtocolPacket *subp=new EQProtocolPacket(p->pBuffer+offset+2, new_length, OP_Packet); - subp->copyInfo(p); - ProcessPacket(subp, p); - delete subp; - return true; + else if(p->pBuffer[offset] != 0xff && p->pBuffer[offset+1] == 0xff && p->size >= offset + 3) { + // Read the first byte into a wider type to avoid underflow. + uint16 total_length = p->pBuffer[offset]; // promote to uint16 + // Check that there is enough data: we expect offset+2+total_length == p->size. + if(total_length + offset + 2 == p->size && total_length >= 2) { + uint32 data_length = total_length - 2; + // 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); + ProcessPacket(subp, p); + delete subp; + return true; } } }