mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 00:03:50 +00:00
fix(parsing): validate spline endPoint coords to reject false-positive format matches
The WotLK spline parser tries 6 format variants and accepts the first that passes minimal validation (pointCount<=256, splineMode<=3). A wrong format can pass by coincidence, consuming incorrect bytes and corrupting all subsequent UPDATE_OBJECT blocks (e.g. maskBlockCount=219 garbage). Add endPoint coordinate validation: reject spline parses where the endpoint is non-finite or outside world bounds (65k). Also harden the Turtle parser to keep successfully-parsed blocks on mid-packet failure instead of discarding the entire packet.
This commit is contained in:
parent
40e72d535e
commit
def821055b
2 changed files with 29 additions and 10 deletions
|
|
@ -2140,6 +2140,8 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec
|
|||
out.blocks.reserve(out.blockCount);
|
||||
for (uint32_t i = 0; i < out.blockCount; ++i) {
|
||||
if (!packet.hasData()) {
|
||||
// If we already parsed some blocks, keep them (layout is confirmed valid).
|
||||
if (!out.blocks.empty()) break;
|
||||
packet.setReadPos(start);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2147,6 +2149,7 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec
|
|||
const size_t blockStart = packet.getReadPos();
|
||||
uint8_t updateTypeVal = packet.readUInt8();
|
||||
if (updateTypeVal > static_cast<uint8_t>(UpdateType::NEAR_OBJECTS)) {
|
||||
if (!out.blocks.empty()) break;
|
||||
packet.setReadPos(start);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2220,14 +2223,19 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec
|
|||
}
|
||||
|
||||
if (!ok) {
|
||||
LOG_WARNING("[Turtle] SMSG_UPDATE_OBJECT block parse failed",
|
||||
" blockIndex=", i,
|
||||
" updateType=", updateTypeName(updateType),
|
||||
" readPos=", packet.getReadPos(),
|
||||
" blockStart=", blockStart,
|
||||
" packetSize=", packet.getSize());
|
||||
packet.setReadPos(start);
|
||||
return false;
|
||||
static int turtleBlockErrors = 0;
|
||||
if (++turtleBlockErrors <= 5) {
|
||||
LOG_WARNING("[Turtle] SMSG_UPDATE_OBJECT block parse failed",
|
||||
" blockIndex=", i, " of ", out.blockCount,
|
||||
" updateType=", updateTypeName(updateType),
|
||||
" readPos=", packet.getReadPos(),
|
||||
" blockStart=", blockStart,
|
||||
" packetSize=", packet.getSize(),
|
||||
" (", out.blocks.size(), " blocks kept)");
|
||||
}
|
||||
// Keep successfully parsed blocks instead of discarding all.
|
||||
// Cannot re-sync within the packet, so stop parsing here.
|
||||
break;
|
||||
}
|
||||
|
||||
out.blocks.push_back(std::move(block));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
|
@ -1010,8 +1011,18 @@ bool UpdateObjectParser::parseMovementBlock(network::Packet& packet, UpdateBlock
|
|||
packet.setReadPos(prePointCount);
|
||||
return false;
|
||||
}
|
||||
packet.readFloat(); packet.readFloat(); packet.readFloat(); // endPoint
|
||||
LOG_DEBUG(" Spline pointCount=", pc, " compressed=", compressed, " (", tag, ")");
|
||||
float epX = packet.readFloat();
|
||||
float epY = packet.readFloat();
|
||||
float epZ = packet.readFloat();
|
||||
// Validate endPoint: garbage bytes rarely produce finite world coords
|
||||
if (!std::isfinite(epX) || !std::isfinite(epY) || !std::isfinite(epZ) ||
|
||||
std::fabs(epX) > 65000.0f || std::fabs(epY) > 65000.0f ||
|
||||
std::fabs(epZ) > 65000.0f) {
|
||||
packet.setReadPos(prePointCount);
|
||||
return false;
|
||||
}
|
||||
LOG_DEBUG(" Spline pointCount=", pc, " compressed=", compressed,
|
||||
" endPt=(", epX, ",", epY, ",", epZ, ") (", tag, ")");
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue