summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2009-06-27 01:05:56 +0000
committerXiaohong Bao <bao@lindenlab.com>2009-06-27 01:05:56 +0000
commitcb8641a639d077fe03853e69be597ee359f5a01f (patch)
treef6f76a534fc45fd4a2bbdface46d62cc5d6237f6 /indra/newview
parent6f613fb70ff28ee090dc0871b461a62bd2aa0d08 (diff)
fix for DEV-27483/SEC-283: Viewer crash: LLXform::setParent Creating loop when setting parent
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llviewerobject.cpp45
-rw-r--r--indra/newview/llviewerobject.h2
-rw-r--r--indra/newview/llvoavatar.cpp13
-rw-r--r--indra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvovolume.cpp9
-rw-r--r--indra/newview/llvovolume.h2
6 files changed, 44 insertions, 29 deletions
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index dc4f2b2990..a96ccfd848 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -512,15 +512,24 @@ BOOL LLViewerObject::isOverGroupOwnedLand() const
&& mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion());
}
-void LLViewerObject::setParent(LLViewerObject* parent)
+BOOL LLViewerObject::setParent(LLViewerObject* parent)
{
- LLPrimitive::setParent(parent);
+ if(mParent != parent)
+ {
+ LLViewerObject* old_parent = (LLViewerObject*)mParent ;
+ BOOL ret = LLPrimitive::setParent(parent);
+ if(ret && old_parent && parent)
+ {
+ old_parent->removeChild(this) ;
+ }
+ return ret ;
+ }
+
+ return FALSE ;
}
void LLViewerObject::addChild(LLViewerObject *childp)
{
- BOOL result = TRUE;
-
for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
{
if (*i == childp)
@@ -535,18 +544,9 @@ void LLViewerObject::addChild(LLViewerObject *childp)
childp->mbCanSelect = mbCanSelect;
}
- childp->setParent(this);
- mChildList.push_back(childp);
-
- if (!result)
+ if(childp->setParent(this))
{
- llwarns << "Failed to attach child " << childp->getID() << " to object " << getID() << llendl;
- removeChild(childp);
- if (mJointInfo)
- {
- delete mJointInfo;
- mJointInfo = NULL;
- }
+ mChildList.push_back(childp);
}
}
@@ -562,7 +562,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp)
}
mChildList.erase(i);
- childp->setParent(NULL);
+
+ if(childp->getParent() == this)
+ {
+ childp->setParent(NULL);
+ }
break;
}
}
@@ -644,11 +648,14 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
return FALSE;
}
+ BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+ if(!ret)
+ {
+ return FALSE ;
+ }
LLDrawable* old_parent = mDrawable->mParent;
-
mDrawable->mParent = parentp;
-
- BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
if( old_parent != parentp &&
old_parent || (parentp && parentp->isActive()))
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 72c713f2a6..2b2c2d5a95 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -237,7 +237,7 @@ public:
BOOL isProbablyModifiable() const;
*/
- virtual void setParent(LLViewerObject* parent);
+ virtual BOOL setParent(LLViewerObject* parent);
virtual void addChild(LLViewerObject *childp);
virtual void removeChild(LLViewerObject *childp);
const_child_list_t& getChildren() const { return mChildList; }
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 176f8fb37b..c2b54ec9c6 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5315,12 +5315,13 @@ void LLVOAvatar::hideSkirt()
mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE);
}
-void LLVOAvatar::setParent(LLViewerObject* parent)
+BOOL LLVOAvatar::setParent(LLViewerObject* parent)
{
+ BOOL ret ;
if (parent == NULL)
{
getOffObject();
- LLViewerObject::setParent(parent);
+ ret = LLViewerObject::setParent(parent);
if (isSelf())
{
gAgent.resetCamera();
@@ -5328,9 +5329,13 @@ void LLVOAvatar::setParent(LLViewerObject* parent)
}
else
{
- LLViewerObject::setParent(parent);
- sitOnObject(parent);
+ ret = LLViewerObject::setParent(parent);
+ if(ret)
+ {
+ sitOnObject(parent);
+ }
}
+ return ret ;
}
void LLVOAvatar::addChild(LLViewerObject *childp)
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 56a8e3cd11..b22c0deb33 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -776,7 +776,7 @@ private:
**/
public:
- virtual void setParent(LLViewerObject* parent);
+ virtual BOOL setParent(LLViewerObject* parent);
virtual void addChild(LLViewerObject *childp);
virtual void removeChild(LLViewerObject *childp);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index aff8fe8f1d..f31f09f60e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -934,17 +934,20 @@ void LLVOVolume::updateFaceFlags()
}
}
-void LLVOVolume::setParent(LLViewerObject* parent)
+BOOL LLVOVolume::setParent(LLViewerObject* parent)
{
+ BOOL ret = FALSE ;
if (parent != getParent())
{
- LLViewerObject::setParent(parent);
- if (mDrawable)
+ ret = LLViewerObject::setParent(parent);
+ if (ret && mDrawable)
{
gPipeline.markMoved(mDrawable);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
}
}
+
+ return ret ;
}
// NOTE: regenFaces() MUST be followed by genTriangles()!
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index f20e551671..5d7b373b3c 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -107,7 +107,7 @@ public:
/*virtual*/ BOOL isHUDAttachment() const;
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ void setParent(LLViewerObject* parent);
+ /*virtual*/ BOOL setParent(LLViewerObject* parent);
S32 getLOD() const { return mLOD; }
const LLVector3 getPivotPositionAgent() const;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }