mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 15:50:20 +00:00
Harden NameQueryResponseParser against malformed packets
Add upfront and in-loop validation for the WotLK variant of name query responses: - Validate packed GUID and found flag reads (minimum 2 bytes) - Validate strings can be read before attempting parse - Validate 3 final uint8 fields (race/gender/class) exist before reading - Graceful truncation handling with field initialization Prevents undefined behavior from servers sending truncated/malformed packets.
This commit is contained in:
parent
2f1b142e14
commit
98739c1610
1 changed files with 27 additions and 0 deletions
|
|
@ -2267,7 +2267,17 @@ network::Packet NameQueryPacket::build(uint64_t playerGuid) {
|
|||
bool NameQueryResponseParser::parse(network::Packet& packet, NameQueryResponseData& data) {
|
||||
// 3.3.5a: packedGuid, uint8 found
|
||||
// If found==0: CString name, CString realmName, uint8 race, uint8 gender, uint8 classId
|
||||
// Validation: packed GUID (1-8 bytes) + found flag (1 byte minimum)
|
||||
if (packet.getSize() - packet.getReadPos() < 2) return false; // At least 1 for packed GUID + 1 for found
|
||||
|
||||
size_t startPos = packet.getReadPos();
|
||||
data.guid = UpdateObjectParser::readPackedGuid(packet);
|
||||
|
||||
// Validate found flag read
|
||||
if (packet.getSize() - packet.getReadPos() < 1) {
|
||||
packet.setReadPos(startPos);
|
||||
return false;
|
||||
}
|
||||
data.found = packet.readUInt8();
|
||||
|
||||
if (data.found != 0) {
|
||||
|
|
@ -2275,8 +2285,25 @@ bool NameQueryResponseParser::parse(network::Packet& packet, NameQueryResponseDa
|
|||
return true; // Valid response, just not found
|
||||
}
|
||||
|
||||
// Validate strings: need at least 2 null terminators for empty strings
|
||||
if (packet.getSize() - packet.getReadPos() < 2) {
|
||||
data.name.clear();
|
||||
data.realmName.clear();
|
||||
return !data.name.empty(); // Fail if name was required
|
||||
}
|
||||
|
||||
data.name = packet.readString();
|
||||
data.realmName = packet.readString();
|
||||
|
||||
// Validate final 3 uint8 fields (race, gender, classId)
|
||||
if (packet.getSize() - packet.getReadPos() < 3) {
|
||||
LOG_WARNING("Name query: truncated fields after realmName, expected 3 uint8s");
|
||||
data.race = 0;
|
||||
data.gender = 0;
|
||||
data.classId = 0;
|
||||
return !data.name.empty();
|
||||
}
|
||||
|
||||
data.race = packet.readUInt8();
|
||||
data.gender = packet.readUInt8();
|
||||
data.classId = packet.readUInt8();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue