summaryrefslogtreecommitdiff
path: root/indra/llcharacter/llkeyframemotion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcharacter/llkeyframemotion.cpp')
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp106
1 files changed, 62 insertions, 44 deletions
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index f4dc3b927b..5b0867524e 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2,31 +2,25 @@
* @file llkeyframemotion.cpp
* @brief Implementation of LLKeyframeMotion class.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -1213,7 +1207,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (!dp.unpackS32(temp_priority, "base_priority"))
{
- llwarns << "can't read priority" << llendl;
+ llwarns << "can't read animation base_priority" << llendl;
return FALSE;
}
mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority;
@@ -1223,6 +1217,11 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
mJointMotionList->mBasePriority = (LLJoint::JointPriority)((int)LLJoint::ADDITIVE_PRIORITY-1);
mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority;
}
+ else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY)
+ {
+ llwarns << "bad animation base_priority " << mJointMotionList->mBasePriority << llendl;
+ return FALSE;
+ }
//-------------------------------------------------------------------------
// get duration
@@ -1233,7 +1232,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
- if (mJointMotionList->mDuration > MAX_ANIM_DURATION )
+ if (mJointMotionList->mDuration > MAX_ANIM_DURATION ||
+ !llfinite(mJointMotionList->mDuration))
{
llwarns << "invalid animation duration" << llendl;
return FALSE;
@@ -1248,16 +1248,24 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
+ if(mJointMotionList->mEmoteName==mID.asString())
+ {
+ llwarns << "Malformed animation mEmoteName==mID" << llendl;
+ return FALSE;
+ }
+
//-------------------------------------------------------------------------
// get loop
//-------------------------------------------------------------------------
- if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point"))
+ if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") ||
+ !llfinite(mJointMotionList->mLoopInPoint))
{
llwarns << "can't read loop point" << llendl;
return FALSE;
}
- if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point"))
+ if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") ||
+ !llfinite(mJointMotionList->mLoopOutPoint))
{
llwarns << "can't read loop point" << llendl;
return FALSE;
@@ -1272,13 +1280,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//-------------------------------------------------------------------------
// get easeIn and easeOut
//-------------------------------------------------------------------------
- if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration"))
+ if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") ||
+ !llfinite(mJointMotionList->mEaseInDuration))
{
llwarns << "can't read easeIn" << llendl;
return FALSE;
}
- if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration"))
+ if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") ||
+ !llfinite(mJointMotionList->mEaseOutDuration))
{
llwarns << "can't read easeOut" << llendl;
return FALSE;
@@ -1368,7 +1378,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
LLPointer<LLJointState> joint_state = new LLJointState;
mJointStates.push_back(joint_state);
- joint_state->setJoint( joint );
+ joint_state->setJoint( joint ); // note: can accept NULL
joint_state->setUsage( 0 );
//---------------------------------------------------------------------
@@ -1380,10 +1390,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
llwarns << "can't read joint priority." << llendl;
return FALSE;
}
+
+ if (joint_priority < LLJoint::USE_MOTION_PRIORITY)
+ {
+ llwarns << "joint priority unknown - too low." << llendl;
+ return FALSE;
+ }
joint_motion->mPriority = (LLJoint::JointPriority)joint_priority;
if (joint_priority != LLJoint::USE_MOTION_PRIORITY &&
- joint_priority > mJointMotionList->mMaxPriority)
+ joint_priority > mJointMotionList->mMaxPriority)
{
mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority;
}
@@ -1393,7 +1409,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//---------------------------------------------------------------------
// scan rotation curve header
//---------------------------------------------------------------------
- if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys"))
+ if (!dp.unpackS32(joint_motion->mRotationCurve.mNumKeys, "num_rot_keys") || joint_motion->mRotationCurve.mNumKeys < 0)
{
llwarns << "can't read number of rotation keys" << llendl;
return FALSE;
@@ -1417,7 +1433,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- if (!dp.unpackF32(time, "time"))
+ if (!dp.unpackF32(time, "time") ||
+ !llfinite(time))
{
llwarns << "can't read rotation key (" << k << ")" << llendl;
return FALSE;
@@ -1450,7 +1467,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- success = dp.unpackVector3(rot_angles, "rot_angles");
+ success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite();
LLQuaternion::Order ro = StringToOrder("ZYX");
rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
@@ -1486,7 +1503,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
//---------------------------------------------------------------------
// scan position curve header
//---------------------------------------------------------------------
- if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys"))
+ if (!dp.unpackS32(joint_motion->mPositionCurve.mNumKeys, "num_pos_keys") || joint_motion->mPositionCurve.mNumKeys < 0)
{
llwarns << "can't read number of position keys" << llendl;
return FALSE;
@@ -1510,7 +1527,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (old_version)
{
- if (!dp.unpackF32(pos_key.mTime, "time"))
+ if (!dp.unpackF32(pos_key.mTime, "time") ||
+ !llfinite(pos_key.mTime))
{
llwarns << "can't read position key (" << k << ")" << llendl;
return FALSE;
@@ -1579,9 +1597,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
- if (num_constraints > MAX_CONSTRAINTS)
+ if (num_constraints > MAX_CONSTRAINTS || num_constraints < 0)
{
- llwarns << "Too many constraints... ignoring" << llendl;
+ llwarns << "Bad number of constraints... ignoring: " << num_constraints << llendl;
}
else
{
@@ -1626,7 +1644,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
constraintp->mConstraintType = (EConstraintType)byte;
const S32 BIN_DATA_LENGTH = 16;
- U8 bin_data[BIN_DATA_LENGTH];
+ U8 bin_data[BIN_DATA_LENGTH+1];
if (!dp.unpackBinaryDataFixed(bin_data, BIN_DATA_LENGTH, "source_volume"))
{
llwarns << "can't read source volume name" << llendl;
@@ -1634,7 +1652,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
- bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
+ bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
str = (char*)bin_data;
constraintp->mSourceConstraintVolume = mCharacter->getCollisionVolumeID(str);
@@ -1659,7 +1677,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
- bin_data[BIN_DATA_LENGTH-1] = 0; // Ensure null termination
+ bin_data[BIN_DATA_LENGTH] = 0; // Ensure null termination
str = (char*)bin_data;
if (str == "GROUND")
{
@@ -1706,28 +1724,28 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
// constraintp->mTargetConstraintDir *= constraintp->mSourceConstraintOffset.magVec();
}
- if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start"))
+ if (!dp.unpackF32(constraintp->mEaseInStartTime, "ease_in_start") || !llfinite(constraintp->mEaseInStartTime))
{
llwarns << "can't read constraint ease in start time" << llendl;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop"))
+ if (!dp.unpackF32(constraintp->mEaseInStopTime, "ease_in_stop") || !llfinite(constraintp->mEaseInStopTime))
{
llwarns << "can't read constraint ease in stop time" << llendl;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start"))
+ if (!dp.unpackF32(constraintp->mEaseOutStartTime, "ease_out_start") || !llfinite(constraintp->mEaseOutStartTime))
{
llwarns << "can't read constraint ease out start time" << llendl;
delete constraintp;
return FALSE;
}
- if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop"))
+ if (!dp.unpackF32(constraintp->mEaseOutStopTime, "ease_out_stop") || !llfinite(constraintp->mEaseOutStopTime))
{
llwarns << "can't read constraint ease out stop time" << llendl;
delete constraintp;
@@ -1736,7 +1754,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
mJointMotionList->mConstraints.push_front(constraintp);
- constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1];
+ 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