Bug 384637 - Self-referencing svg:mask causes stack overflow crash. r+sr=tor

This commit is contained in:
longsonr@gmail.com 2007-06-21 04:01:41 -07:00
parent 6993fe36b9
commit 88245a4f7b
2 changed files with 31 additions and 0 deletions

View File

@ -74,6 +74,7 @@ nsSVGMaskFrame::InitSVG()
return rv;
mMaskParentMatrix = nsnull;
mInUse = PR_FALSE;
nsCOMPtr<nsIDOMSVGMaskElement> mask = do_QueryInterface(mContent);
NS_ASSERTION(mask, "wrong content element");
@ -88,6 +89,15 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
nsIDOMSVGMatrix* aMatrix,
float aOpacity)
{
// If the flag is set when we get here, it means this mask frame
// has already been used painting the current mask, and the document
// has a mask reference loop.
if (mInUse) {
NS_WARNING("Mask loop detected!");
return nsnull;
}
AutoMaskReferencer maskRef(this);
gfxContext *gfx = aContext->GetGfxContext();
gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);

View File

@ -75,8 +75,29 @@ class nsSVGMaskFrame : public nsSVGMaskFrameBase
#endif
private:
// A helper class to allow us to paint masks safely. The helper
// automatically sets and clears the mInUse flag on the mask frame
// (to prevent nasty reference loops). It's easy to mess this up
// and break things, so this helper makes the code far more robust.
class AutoMaskReferencer
{
public:
AutoMaskReferencer(nsSVGMaskFrame *aFrame)
: mFrame(aFrame) {
NS_ASSERTION(mFrame->mInUse == PR_FALSE, "reference loop!");
mFrame->mInUse = PR_TRUE;
}
~AutoMaskReferencer() {
mFrame->mInUse = PR_FALSE;
}
private:
nsSVGMaskFrame *mFrame;
};
nsISVGChildFrame *mMaskParent;
nsCOMPtr<nsIDOMSVGMatrix> mMaskParentMatrix;
// recursion prevention flag
PRPackedBool mInUse;
// nsSVGContainerFrame methods:
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM();