From f0abd1794b29a760f2c0f60cb43b948974efa41e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 05:19:24 -0700 Subject: [PATCH] fix(wom): sanitize bone pivot NaN + clamp out-of-range parentBone Bones with NaN pivots produce broken skeleton matrices that ripple into every child bone via the parent-chain multiplication. Out-of-range parentBone indices would cause a use-after-free during bone-matrix computation. Both now defensively clamped. --- src/pipeline/wowee_model.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pipeline/wowee_model.cpp b/src/pipeline/wowee_model.cpp index 15ac0d16..391bb625 100644 --- a/src/pipeline/wowee_model.cpp +++ b/src/pipeline/wowee_model.cpp @@ -109,6 +109,18 @@ WoweeModel WoweeModelLoader::load(const std::string& basePath) { f.read(reinterpret_cast(&bone.parentBone), 2); f.read(reinterpret_cast(&bone.pivot), 12); f.read(reinterpret_cast(&bone.flags), 4); + // Sanitize pivot — bones with NaN pivots produce broken + // skeleton matrices that ripple into every child bone. + if (!std::isfinite(bone.pivot.x)) bone.pivot.x = 0.0f; + if (!std::isfinite(bone.pivot.y)) bone.pivot.y = 0.0f; + if (!std::isfinite(bone.pivot.z)) bone.pivot.z = 0.0f; + // parentBone must be < boneCount (or -1) — out-of-range + // parents would cause a use-after-free during bone-matrix + // computation that walks the parent chain. + if (bone.parentBone >= 0 && + static_cast(bone.parentBone) >= boneCount) { + bone.parentBone = -1; + } } }