diff options
author | Xiaohong Bao <bao@lindenlab.com> | 2009-06-27 01:05:56 +0000 |
---|---|---|
committer | Xiaohong Bao <bao@lindenlab.com> | 2009-06-27 01:05:56 +0000 |
commit | cb8641a639d077fe03853e69be597ee359f5a01f (patch) | |
tree | f6f76a534fc45fd4a2bbdface46d62cc5d6237f6 /indra/newview | |
parent | 6f613fb70ff28ee090dc0871b461a62bd2aa0d08 (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.cpp | 45 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 2 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 2 |
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; } |