diff options
author | Rye Mutt <rye@alchemyviewer.org> | 2022-10-28 15:46:42 -0400 |
---|---|---|
committer | Rye Mutt <rye@alchemyviewer.org> | 2022-10-28 15:46:42 -0400 |
commit | 129301c8e9d48e29466597f6baee6d3566fac9dc (patch) | |
tree | 702e12c1d472b306ec704cceb39cb88d8b52dfef | |
parent | fabfbb93e666326a9daad7c14e690a23e4567d23 (diff) |
Fix multiple leaks in the case of failure to deserialize animations
-rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 185 |
1 files changed, 97 insertions, 88 deletions
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index ebf7454a61..403d5bcf49 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1229,7 +1229,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList); //------------------------------------------------------------------------- // get base priority @@ -1272,16 +1272,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo << " for animation " << asset_id << LL_ENDL; return FALSE; } - mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; - if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) + if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) { - mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); - mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); + joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; } - else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) { - LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority + LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1289,15 +1289,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get duration //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mDuration, "duration")) + if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) { LL_WARNS() << "can't read duration" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (mJointMotionList->mDuration > MAX_ANIM_DURATION || - !llfinite(mJointMotionList->mDuration)) + if (joint_motion_list->mDuration > MAX_ANIM_DURATION || + !llfinite(joint_motion_list->mDuration)) { LL_WARNS() << "invalid animation duration" << " for animation " << asset_id << LL_ENDL; @@ -1307,14 +1307,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get emote (optional) //------------------------------------------------------------------------- - if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) + if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) { LL_WARNS() << "can't read optional_emote_animation" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if(mJointMotionList->mEmoteName==mID.asString()) + if(joint_motion_list->mEmoteName==mID.asString()) { LL_WARNS() << "Malformed animation mEmoteName==mID" << " for animation " << asset_id << LL_ENDL; @@ -1324,23 +1324,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get loop //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || - !llfinite(mJointMotionList->mLoopInPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || + !llfinite(joint_motion_list->mLoopInPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || - !llfinite(mJointMotionList->mLoopOutPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || + !llfinite(joint_motion_list->mLoopOutPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackS32(mJointMotionList->mLoop, "loop")) + if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) { LL_WARNS() << "can't read loop" << " for animation " << asset_id << LL_ENDL; @@ -1353,22 +1353,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (female_land_anim == asset_id || formal_female_land_anim == asset_id) { LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; - mJointMotionList->mLoop = FALSE; + joint_motion_list->mLoop = FALSE; } //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || - !llfinite(mJointMotionList->mEaseInDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || + !llfinite(joint_motion_list->mEaseInDuration)) { LL_WARNS() << "can't read easeIn" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || - !llfinite(mJointMotionList->mEaseOutDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || + !llfinite(joint_motion_list->mEaseOutDuration)) { LL_WARNS() << "can't read easeOut" << " for animation " << asset_id << LL_ENDL; @@ -1393,7 +1393,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; + joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- // get number of joint motions @@ -1419,8 +1419,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + joint_motion_list->mJointMotionArray.clear(); + joint_motion_list->mJointMotionArray.reserve(num_motions); mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1431,7 +1431,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(U32 i=0; i<num_motions; ++i) { JointMotion* joint_motion = new JointMotion; - mJointMotionList->mJointMotionArray.push_back(joint_motion); + joint_motion_list->mJointMotionArray.push_back(joint_motion); std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1503,9 +1503,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > mJointMotionList->mMaxPriority) + joint_priority > joint_motion_list->mMaxPriority) { - mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; + joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; } joint_state->setPriority((LLJoint::JointPriority)joint_priority); @@ -1556,9 +1556,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - if (time < 0 || time > mJointMotionList->mDuration) + if (time < 0 || time > joint_motion_list->mDuration) { LL_WARNS() << "invalid frame time" << " for animation " << asset_id << LL_ENDL; @@ -1571,38 +1571,57 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LLVector3 rot_angles; U16 x, y, z; - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); + if (!dp.unpackVector3(rot_angles, "rot_angles")) + { + LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!rot_angles.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLQuaternion::Order ro = StringToOrder("ZYX"); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); } else { - success &= dp.unpackU16(x, "rot_angle_x"); - success &= dp.unpackU16(y, "rot_angle_y"); - success &= dp.unpackU16(z, "rot_angle_z"); + if (!dp.unpackU16(x, "rot_angle_x")) + { + LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "rot_angle_y")) + { + LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "rot_angle_z")) + { + LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLVector3 rot_vec; rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); + + if(!rot_vec.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } rot_key.mRotation.unpackFromVector3(rot_vec); } - if( !(rot_key.mRotation.isFinite()) ) - { - LL_WARNS() << "non-finite angle in rotation key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) + if(!rot_key.mRotation.isFinite()) { - LL_WARNS() << "can't read rotation key (" << k << ")" + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1655,14 +1674,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); } - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(pos_key.mPosition, "pos"); + if (!dp.unpackVector3(pos_key.mPosition, "pos")) + { + LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; + return FALSE; + } //MAINT-6162 pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1674,26 +1695,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { U16 x, y, z; - success &= dp.unpackU16(x, "pos_x"); - success &= dp.unpackU16(y, "pos_y"); - success &= dp.unpackU16(z, "pos_z"); + if (!dp.unpackU16(x, "pos_x")) + { + LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "pos_y")) + { + LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "pos_z")) + { + LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; + return FALSE; + } pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } - if( !(pos_key.mPosition.isFinite()) ) + if(!pos_key.mPosition.isFinite()) { LL_WARNS() << "non-finite position in key" << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) - { - LL_WARNS() << "can't read position key (" << k << ")" - << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1701,7 +1727,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (is_pelvis) { - mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); + joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); } } @@ -1733,23 +1759,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(S32 i = 0; i < num_constraints; ++i) { // read in constraint data - JointConstraintSharedData* constraintp = new JointConstraintSharedData; + std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData); U8 byte = 0; if (!dp.unpackU8(byte, "chain_length")) { LL_WARNS() << "can't read constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mChainLength = (S32) byte; - if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) { LL_WARNS() << "invalid constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1757,7 +1781,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1765,7 +1788,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "invalid constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mConstraintType = (EConstraintType)byte; @@ -1776,7 +1798,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read source volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1787,7 +1808,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid source constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1795,7 +1815,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1803,7 +1822,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1811,7 +1829,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read target volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1830,7 +1847,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid target constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } @@ -1839,7 +1855,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1847,7 +1862,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1855,7 +1869,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1863,7 +1876,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1877,7 +1889,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1885,7 +1896,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1893,7 +1903,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1901,33 +1910,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); - - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte - LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached if (!joint) { return FALSE; } + + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte + for (S32 i = 0; i < constraintp->mChainLength + 1; i++) { LLJoint* parent = joint->getParent(); if (!parent) { LL_WARNS() << "Joint with no parent: " << joint->getName() - << " Emote: " << mJointMotionList->mEmoteName + << " Emote: " << joint_motion_list->mEmoteName << " for animation " << asset_id << LL_ENDL; return FALSE; } joint = parent; constraintp->mJointStateIndices[i] = -1; - for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++) + for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) { LLJoint* constraint_joint = getJoint(j); @@ -1948,14 +1955,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "No joint index for constraint " << i << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } + + joint_motion_list->mConstraints.push_front(constraintp.release()); } } // *FIX: support cleanup of old keyframe data + mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member; LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; |