From 93edf1bd552d5cac9d545cc99ee34db55e3a22ef Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 05:49:15 -0700 Subject: [PATCH] fix(wob): per-group count sanity bounds + group name length cap The WoB top-level header sanity bounds catch obviously-bad totals, but each group's vc/ic/tc was still unbounded. A corrupted group could declare 4G vertices and OOM the resize before the next group even started. Now per-group: vc<=1M, ic<=4M, tc<=1K, name<=1KB. --- src/pipeline/wowee_building.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pipeline/wowee_building.cpp b/src/pipeline/wowee_building.cpp index 18d76595..388f38bf 100644 --- a/src/pipeline/wowee_building.cpp +++ b/src/pipeline/wowee_building.cpp @@ -50,6 +50,7 @@ WoweeBuilding WoweeBuildingLoader::load(const std::string& basePath) { WoweeBuilding::Group grp; uint16_t gnLen; f.read(reinterpret_cast(&gnLen), 2); + if (gnLen > 1024) gnLen = 0; grp.name.resize(gnLen); f.read(grp.name.data(), gnLen); @@ -57,6 +58,13 @@ WoweeBuilding WoweeBuildingLoader::load(const std::string& basePath) { f.read(reinterpret_cast(&vc), 4); f.read(reinterpret_cast(&ic), 4); f.read(reinterpret_cast(&tc), 4); + // Per-group sanity. WMO groups cap at 65k vertices in practice + // (uint16 indices). Tex paths per group rarely exceed 16. + if (vc > 1'000'000 || ic > 4'000'000 || tc > 1024) { + LOG_ERROR("WOB group ", gi, " counts rejected (verts=", vc, + " indices=", ic, " textures=", tc, "): ", basePath); + return WoweeBuilding{}; + } uint8_t outdoor; f.read(reinterpret_cast(&outdoor), 1); grp.isOutdoor = (outdoor != 0);