diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp 1970-01-01 01:00:00.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp 2010-06-11 15:29:14.567278020 +0200 @@ -0,0 +1,101 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if ENABLE(SVG) +#include "RenderSVGShadowTreeRootContainer.h" + +#include "MouseEvent.h" +#include "SVGShadowTreeElements.h" +#include "SVGUseElement.h" + +namespace WebCore { + +RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement* node) + : RenderSVGTransformableContainer(node) + , m_recreateTree(false) +{ +} + +RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer() +{ + if (m_shadowRoot && m_shadowRoot->attached()) + m_shadowRoot->detach(); +} + +void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change) +{ + if (m_shadowRoot && m_shadowRoot->attached()) + m_shadowRoot->recalcStyle(change); +} + +void RenderSVGShadowTreeRootContainer::updateFromElement() +{ + bool hadExistingTree = m_shadowRoot; + + SVGUseElement* useElement = static_cast(node()); + if (!m_shadowRoot) { + ASSERT(!m_recreateTree); + m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement); + useElement->buildPendingResource(); + } + + ASSERT(m_shadowRoot->shadowParentNode() == useElement); + + bool shouldRecreateTree = m_recreateTree; + if (m_recreateTree) { + ASSERT(hadExistingTree); + + if (m_shadowRoot->attached()) + m_shadowRoot->detach(); + + m_shadowRoot->removeAllChildren(); + m_recreateTree = false; + } + + // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so + // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use + // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true. + if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) { + useElement->buildShadowAndInstanceTree(m_shadowRoot.get()); + + // Attach shadow root element + m_shadowRoot->attachElement(style(), renderArena()); + + // Attach subtree, as if it was a regular non-shadow tree + for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling()) + child->attach(); + } + + ASSERT(!m_recreateTree); + RenderSVGTransformableContainer::updateFromElement(); +} + +void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderSVGTransformableContainer::styleDidChange(diff, oldStyle); + + if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0) + shadowRootRenderer->setStyle(style()); +} + +} + +#endif diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h 1970-01-01 01:00:00.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h 2010-06-11 15:29:14.568278907 +0200 @@ -0,0 +1,50 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef RenderSVGShadowTreeRootContainer_h +#define RenderSVGShadowTreeRootContainer_h + +#if ENABLE(SVG) +#include "RenderSVGTransformableContainer.h" + +namespace WebCore { + +class SVGUseElement; +class SVGShadowTreeRootElement; + +class RenderSVGShadowTreeRootContainer : public RenderSVGTransformableContainer { +public: + RenderSVGShadowTreeRootContainer(SVGUseElement*); + virtual ~RenderSVGShadowTreeRootContainer(); + + void markShadowTreeForRecreation() { m_recreateTree = true; } + void updateStyle(Node::StyleChange); + virtual void updateFromElement(); + +private: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + + bool m_recreateTree; + RefPtr m_shadowRoot; +}; + +} + +#endif +#endif diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp 2010-06-02 04:03:11.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp 2010-06-11 15:29:14.568278907 +0200 @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann + Copyright (C) 2004, 2005 Nikolas Zimmermann 2004, 2005, 2006 Rob Buis 2009 Google, Inc. @@ -20,12 +20,12 @@ */ #include "config.h" -#if ENABLE(SVG) +#if ENABLE(SVG) #include "RenderSVGTransformableContainer.h" +#include "SVGShadowTreeElements.h" #include "SVGStyledTransformableElement.h" -#include "SVGTransformList.h" namespace WebCore { @@ -47,6 +47,14 @@ void RenderSVGTransformableContainer::calculateLocalTransform() { m_localTransform = static_cast(node())->animatedLocalTransform(); + if (!node()->hasTagName(SVGNames::gTag) || !static_cast(node())->isShadowTreeContainerElement()) + return; + + FloatSize translation = static_cast(node())->containerTranslation(); + if (translation.width() == 0 && translation.height() == 0) + return; + + m_localTransform.translateRight(translation.width(), translation.height()); } } diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp 1970-01-01 01:00:00.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp 2010-06-11 15:29:14.567278020 +0200 @@ -0,0 +1,80 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if ENABLE(SVG) +#include "SVGShadowTreeElements.h" + +#include "Document.h" +#include "FloatSize.h" +#include "RenderObject.h" +#include "SVGNames.h" + +namespace WebCore { + +// SVGShadowTreeContainerElement +SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document) + : SVGGElement(SVGNames::gTag, document) +{ +} + +SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement() +{ +} + +FloatSize SVGShadowTreeContainerElement::containerTranslation() const +{ + return FloatSize(m_xOffset.value(this), m_yOffset.value(this)); +} + +// SVGShadowTreeRootElement +SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* shadowParent) + : SVGShadowTreeContainerElement(document) + , m_shadowParent(shadowParent) +{ + setInDocument(true); +} + +SVGShadowTreeRootElement::~SVGShadowTreeRootElement() +{ +} + +void SVGShadowTreeRootElement::attachElement(PassRefPtr style, RenderArena* arena) +{ + ASSERT(m_shadowParent); + + // Create the renderer with the specified style + RenderObject* renderer = createRenderer(arena, style.get()); + if (renderer) { + setRenderer(renderer); + renderer->setStyle(style); + } + + // Set these explicitly since this normally happens during an attach() + setAttached(); + + // Add the renderer to the render tree + if (renderer) + m_shadowParent->renderer()->addChild(renderer); +} + +} + +#endif diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h 1970-01-01 01:00:00.000000000 +0100 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h 2010-06-11 15:29:14.568278907 +0200 @@ -0,0 +1,67 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SVGShadowTreeElements_h +#define SVGShadowTreeElements_h + +#if ENABLE(SVG) +#include "SVGGElement.h" +#include "SVGLength.h" + +namespace WebCore { + +class FloatSize; + +class SVGShadowTreeContainerElement : public SVGGElement { +public: + SVGShadowTreeContainerElement(Document*); + virtual ~SVGShadowTreeContainerElement(); + + virtual bool isShadowTreeContainerElement() const { return true; } + + FloatSize containerTranslation() const; + void setContainerOffset(const SVGLength& x, const SVGLength& y) + { + m_xOffset = x; + m_yOffset = y; + } + +private: + SVGLength m_xOffset; + SVGLength m_yOffset; +}; + +class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement { +public: + SVGShadowTreeRootElement(Document*, Node* shadowParent); + virtual ~SVGShadowTreeRootElement(); + + virtual bool isShadowNode() const { return m_shadowParent; } + virtual Node* shadowParentNode() { return m_shadowParent; } + + void attachElement(PassRefPtr, RenderArena*); + +private: + Node* m_shadowParent; +}; + +} + +#endif +#endif diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp 2010-06-11 15:29:14.559280466 +0200 @@ -54,7 +54,6 @@ SVGElement::SVGElement(const QualifiedName& tagName, Document* document) : StyledElement(tagName, document, CreateElementZeroRefCount) - , m_shadowParent(0) , m_cursorElement(0) , m_cursorImageValue(0) { @@ -285,7 +284,11 @@ ContainerNode* SVGElement::eventParentNode() { - return m_shadowParent ? m_shadowParent : StyledElement::eventParentNode(); + if (Node* shadowParent = shadowParentNode()) { + ASSERT(shadowParent->isContainerNode()); + return static_cast(shadowParent); + } + return StyledElement::eventParentNode(); } } diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.h 2010-06-02 04:03:11.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.h 2010-06-11 15:29:14.564280678 +0200 @@ -60,8 +60,6 @@ virtual bool isGradientStop() const { return false; } virtual bool isTextContent() const { return false; } - void setShadowParentNode(ContainerNode* node) { m_shadowParent = node; } - // For SVGTests virtual bool isValid() const { return true; } @@ -95,13 +93,9 @@ friend class SVGElementInstance; virtual bool isSVGElement() const { return true; } - virtual bool isSupported(StringImpl* feature, StringImpl* version) const; - - virtual bool isShadowNode() const { return m_shadowParent; } - virtual Node* shadowParentNode() { return m_shadowParent; } - virtual ContainerNode* eventParentNode(); + virtual ContainerNode* eventParentNode(); virtual void buildPendingResource() { } void mapInstanceToElement(SVGElementInstance*); @@ -109,7 +103,6 @@ virtual bool haveLoadedRequiredResources(); - ContainerNode* m_shadowParent; mutable SynchronizablePropertyController m_propertyController; SVGCursorElement* m_cursorElement; diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp 2010-06-11 15:29:14.560280508 +0200 @@ -33,10 +33,6 @@ #include -#if USE(JSC) -#include "GCController.h" -#endif - namespace WebCore { #ifndef NDEBUG @@ -51,8 +47,7 @@ } SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr originalElement) - : m_needsUpdate(false) - , m_useElement(useElement) + : m_useElement(useElement) , m_element(originalElement) , m_previousSibling(0) , m_nextSibling(0) @@ -93,20 +88,6 @@ m_shadowTreeElement = element; } -void SVGElementInstance::forgetWrapper() -{ -#if USE(JSC) - // FIXME: This is fragile, as discussed with Sam. Need to find a better solution. - // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;". - // We still have to recreate this wrapper somehow. The gc collection below, won't catch it. - - // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects - // are still holding RefPtrs of SVGElementInstance objects, which prevent us to - // be deleted (and the shadow tree is not destructed as well). Force JS GC. - gcController().garbageCollectNow(); -#endif -} - void SVGElementInstance::appendChild(PassRefPtr child) { appendChildToContainer(child.get(), this); @@ -114,27 +95,24 @@ void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) { - if (!element) + if (!element || !element->isStyled()) + return; + + if (static_cast(element)->instanceUpdatesBlocked()) return; HashSet set = element->instancesForElement(); if (set.isEmpty()) return; - // Find all use elements referencing the instances - ask them _once_ to rebuild. + // Mark all use elements referencing 'element' for rebuilding HashSet::const_iterator it = set.begin(); const HashSet::const_iterator end = set.end(); - for (; it != end; ++it) - (*it)->setNeedsUpdate(true); -} - -void SVGElementInstance::setNeedsUpdate(bool value) -{ - m_needsUpdate = value; - - if (m_needsUpdate) - correspondingUseElement()->setNeedsStyleRecalc(); + for (; it != end; ++it) { + ASSERT((*it)->correspondingElement() == element); + (*it)->correspondingUseElement()->invalidateShadowTree(); + } } ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h 2010-06-02 04:03:11.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h 2010-06-11 15:29:14.556183347 +0200 @@ -46,9 +46,6 @@ virtual ~SVGElementInstance(); - bool needsUpdate() const { return m_needsUpdate; } - void setNeedsUpdate(bool); - virtual ScriptExecutionContext* scriptExecutionContext() const; virtual bool addEventListener(const AtomicString& eventType, PassRefPtr, bool useCapture); @@ -129,7 +126,6 @@ void appendChild(PassRefPtr child); void setShadowTreeElement(SVGElement*); - void forgetWrapper(); template friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container); @@ -153,8 +149,6 @@ virtual EventTargetData* eventTargetData(); virtual EventTargetData* ensureEventTargetData(); - bool m_needsUpdate : 1; - SVGUseElement* m_useElement; RefPtr m_element; RefPtr m_shadowTreeElement; diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGGElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGGElement.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGGElement.h 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGGElement.h 2010-06-11 15:29:14.564280678 +0200 @@ -37,6 +37,7 @@ SVGGElement(const QualifiedName&, Document*); virtual ~SVGGElement(); + virtual bool isShadowTreeContainerElement() const { return false; } virtual bool isValid() const { return SVGTests::isValid(); } virtual void parseMappedAttribute(MappedAttribute*); diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp 2010-06-02 04:03:11.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp 2010-06-11 15:29:14.562280735 +0200 @@ -45,11 +45,11 @@ using namespace SVGNames; char SVGStyledElementIdentifier[] = "SVGStyledElement"; -static HashSet* gElementsWithInstanceUpdatesBlocked = 0; SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) , m_className(this, HTMLNames::classAttr) + , m_instanceUpdatesBlocked(false) { } @@ -270,19 +270,6 @@ SVGResource::removeClient(this); SVGElement::detach(); } - -void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates) -{ - if (blockUpdates) { - if (!gElementsWithInstanceUpdatesBlocked) - gElementsWithInstanceUpdatesBlocked = new HashSet; - gElementsWithInstanceUpdatesBlocked->add(this); - } else { - ASSERT(gElementsWithInstanceUpdatesBlocked); - ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this)); - gElementsWithInstanceUpdatesBlocked->remove(this); - } -} } diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h 2010-06-11 15:29:14.554166596 +0200 @@ -49,10 +49,9 @@ virtual bool rendererIsNeeded(RenderStyle*); virtual SVGResource* canvasResource() { return 0; } - + virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; virtual void parseMappedAttribute(MappedAttribute*); - virtual void svgAttributeChanged(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); @@ -62,8 +61,9 @@ void invalidateResourcesInAncestorChain() const; virtual void detach(); - - void setInstanceUpdatesBlocked(bool); + + bool instanceUpdatesBlocked() const { return m_instanceUpdatesBlocked; } + void setInstanceUpdatesBlocked(bool value) { m_instanceUpdatesBlocked = value; } protected: virtual bool hasRelativeValues() const { return true; } @@ -72,6 +72,7 @@ private: ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className) + bool m_instanceUpdatesBlocked; }; } // namespace WebCore diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp 2010-06-11 15:43:17.347280236 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann 2004, 2005, 2006, 2007 Rob Buis - Copyright (C) Research In Motion Limited 2009. All rights reserved. + Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. This file is part of the KDE project @@ -35,12 +35,13 @@ #include "MappedAttribute.h" #include "NodeRenderStyle.h" #include "RegisteredEventListener.h" -#include "RenderSVGTransformableContainer.h" +#include "RenderSVGShadowTreeRootContainer.h" #include "SVGElementInstance.h" #include "SVGElementInstanceList.h" #include "SVGGElement.h" #include "SVGLength.h" #include "SVGPreserveAspectRatio.h" +#include "SVGShadowTreeElements.h" #include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "SVGSymbolElement.h" @@ -67,6 +68,8 @@ , m_height(this, SVGNames::heightAttr, LengthModeHeight) , m_href(this, XLinkNames::hrefAttr) , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_isPendingResource(false) + , m_needsShadowTreeRecreation(false) { } @@ -76,6 +79,16 @@ SVGElementInstance* SVGUseElement::instanceRoot() const { + // If there is no element instance tree, force immediate SVGElementInstance tree + // creation, as we can't wait for the lazy creation to happen if ie. JS wants to + // access the instanceRoot object right after creating the element on-the-fly + if (!m_targetElementInstance) { + if (RenderSVGShadowTreeRootContainer* shadowRoot = static_cast(renderer())) { + shadowRoot->markShadowTreeForRecreation(); + shadowRoot->updateFromElement(); + } + } + return m_targetElementInstance.get(); } @@ -114,14 +127,15 @@ void SVGUseElement::insertedIntoDocument() { + // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. SVGElement::insertedIntoDocument(); - buildPendingResource(); + ASSERT(!m_targetElementInstance); + ASSERT(!m_isPendingResource); } void SVGUseElement::removedFromDocument() { m_targetElementInstance = 0; - m_shadowTreeRootElement = 0; SVGElement::removedFromDocument(); } @@ -129,87 +143,120 @@ { SVGStyledTransformableElement::svgAttributeChanged(attrName); - if (!attached()) + if (!renderer()) return; - if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || - attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || - SVGTests::isKnownAttribute(attrName) || - SVGLangSpace::isKnownAttribute(attrName) || - SVGExternalResourcesRequired::isKnownAttribute(attrName) || - SVGURIReference::isKnownAttribute(attrName) || - SVGStyledTransformableElement::isKnownAttribute(attrName)) { - buildPendingResource(); + if (SVGURIReference::isKnownAttribute(attrName)) { + if (m_isPendingResource) { + document()->accessSVGExtensions()->removePendingResource(m_resourceId); + m_resourceId = String(); + m_isPendingResource = false; + } - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); + invalidateShadowTree(); + return; + } + + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { + updateContainerOffsets(); + return; + } + + // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! + if (SVGStyledElement::isKnownAttribute(attrName)) { + setNeedsStyleRecalc(); + return; + } + + // TODO: We should be able to remove the need for width/height to require a reclone, similar to the x/y logic. + if (attrName == SVGNames::widthAttr + || attrName == SVGNames::heightAttr + || SVGTests::isKnownAttribute(attrName) + || SVGLangSpace::isKnownAttribute(attrName) + || SVGExternalResourcesRequired::isKnownAttribute(attrName) + || SVGStyledTransformableElement::isKnownAttribute(attrName)) { + invalidateShadowTree(); } } -void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +static void updateContainerOffset(SVGElementInstance* targetInstance) { - SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + // Depth-first used to write the method in early exit style, no particular other reason. + for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) + updateContainerOffset(instance); - if (!attached()) + SVGElement* correspondingElement = targetInstance->correspondingElement(); + ASSERT(correspondingElement); + + if (!correspondingElement->hasTagName(SVGNames::useTag)) return; - buildPendingResource(); + SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); + ASSERT(shadowTreeElement); + ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag)); + + if (!static_cast(shadowTreeElement)->isShadowTreeContainerElement()) + return; - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); + // Spec: An additional transformation translate(x,y) is appended to the end + // (i.e., right-side) of the transform attribute on the generated 'g', where x + // and y represent the values of the x and y attributes on the 'use' element. + SVGUseElement* useElement = static_cast(correspondingElement); + SVGShadowTreeContainerElement* containerElement = static_cast(shadowTreeElement); + containerElement->setContainerOffset(useElement->x(), useElement->y()); } - -static bool shadowTreeContainsChangedNodes(SVGElementInstance* target) + +void SVGUseElement::updateContainerOffsets() { - if (!target) // when use is referencing an non-existing element, there will be no Instance tree built - return false; + if (!m_targetElementInstance) + return; - if (target->needsUpdate()) - return true; + // Update root container offset (not reachable through instance tree) + SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement(); + ASSERT(shadowRoot); - for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) - if (shadowTreeContainsChangedNodes(instance)) - return true; + Node* parentNode = shadowRoot->parentNode(); + ASSERT(parentNode); + ASSERT(parentNode->isSVGElement()); + ASSERT(parentNode->hasTagName(SVGNames::gTag)); + ASSERT(static_cast(parentNode)->isShadowTreeContainerElement()); - return false; + SVGShadowTreeContainerElement* containerElement = static_cast(parentNode); + containerElement->setContainerOffset(x(), y()); + + // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree + updateContainerOffset(m_targetElementInstance.get()); + + if (renderer()) + renderer()->setNeedsLayout(true); } void SVGUseElement::recalcStyle(StyleChange change) { - if (attached() && needsStyleRecalc() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) { - buildPendingResource(); - - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); + // Eventually mark shadow root element needing style recalc + if (needsStyleRecalc() && m_targetElementInstance) { + if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement()) + shadowRoot->setNeedsStyleRecalc(); } - SVGStyledElement::recalcStyle(change); + SVGStyledTransformableElement::recalcStyle(change); - // The shadow tree root element is NOT a direct child element of us. - // So we have to take care it receives style updates, manually. - if (!m_shadowTreeRootElement || !m_shadowTreeRootElement->attached()) - return; - - // Mimic Element::recalcStyle(). The main difference is that we don't call attach() on the - // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash - // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky. - if (change >= Inherit || m_shadowTreeRootElement->needsStyleRecalc()) { - RefPtr newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get()); - StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get()); - if (ch == Detach) { - ASSERT(m_shadowTreeRootElement->attached()); - m_shadowTreeRootElement->detach(); - attachShadowTree(); - - // attach recalulates the style for all children. No need to do it twice. - m_shadowTreeRootElement->setNeedsStyleRecalc(NoStyleChange); - m_shadowTreeRootElement->setChildNeedsStyleRecalc(false); - return; - } + bool needsStyleUpdate = !m_needsShadowTreeRecreation; + if (m_needsShadowTreeRecreation) { + static_cast(renderer())->markShadowTreeForRecreation(); + m_needsShadowTreeRecreation = false; } - // Only change==Detach needs special treatment, for anything else recalcStyle() works. - m_shadowTreeRootElement->recalcStyle(change); + RenderSVGShadowTreeRootContainer* shadowRoot = static_cast(renderer()); + if (!shadowRoot) + return; + + shadowRoot->updateFromElement(); + + if (!needsStyleUpdate) + return; + + shadowRoot->updateStyle(change); } #ifdef DUMP_INSTANCE_TREE @@ -218,17 +265,21 @@ SVGElement* element = targetInstance->correspondingElement(); ASSERT(element); + SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); + ASSERT(shadowTreeElement); + String elementId = element->getIDAttribute(); String elementNodeName = element->nodeName(); + String shadowTreeElementNodeName = shadowTreeElement->nodeName(); String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null"; String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null"; for (unsigned int i = 0; i < depth; ++i) text += " "; - text += String::format("SVGElementInstance this=%p, (parentNode=%s, firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n", - targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(), - element, targetInstance->shadowTreeElement(), elementId.latin1().data()); + text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n", + targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(), + elementNodeName.latin1().data(), element, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data()); for (unsigned int i = 0; i < depth; ++i) text += " "; @@ -284,16 +335,36 @@ void SVGUseElement::buildPendingResource() { + // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer) + // we either determine that our target is available or not - then we add ourselves to the pending resource list + // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time. String id = SVGURIReference::getTarget(href()); Element* targetElement = document()->getElementById(id); + ASSERT(!m_targetElementInstance); if (!targetElement) { - // TODO: We want to deregister as pending resource, if our href() changed! - // TODO: Move to svgAttributeChanged, once we're fixing use & the new dynamic update concept. + if (m_isPendingResource) + return; + + m_isPendingResource = true; + m_resourceId = id; document()->accessSVGExtensions()->addPendingResource(id, this); return; } + if (m_isPendingResource) { + ASSERT(!m_targetElementInstance); + m_isPendingResource = false; + invalidateShadowTree(); + } +} + +void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowRoot) +{ + String id = SVGURIReference::getTarget(href()); + Element* targetElement = document()->getElementById(id); + ASSERT(targetElement); + // Do not build the shadow/instance tree for elements living in a shadow tree. // The will be expanded soon anyway - see expandUseElementsInShadowTree(). Node* parent = parentNode(); @@ -308,17 +379,13 @@ if (targetElement && targetElement->isSVGElement()) target = static_cast(targetElement); - if (m_targetElementInstance) { - m_targetElementInstance->forgetWrapper(); + if (m_targetElementInstance) m_targetElementInstance = 0; - } // Do not allow self-referencing. // 'target' may be null, if it's a non SVG namespaced element. - if (!target || target == this) { - m_shadowTreeRootElement = 0; + if (!target || target == this) return; - } // Why a seperated instance/shadow tree? SVG demands it: // The instance tree is accesable from JavaScript, and has to @@ -340,45 +407,45 @@ // Non-appearing content is easier to debug, then half-appearing content. if (foundProblem) { m_targetElementInstance = 0; - m_shadowTreeRootElement = 0; return; } // Assure instance tree building was successfull ASSERT(m_targetElementInstance); + ASSERT(!m_targetElementInstance->shadowTreeElement()); ASSERT(m_targetElementInstance->correspondingUseElement() == this); - // Setup shadow tree root node - m_shadowTreeRootElement = new SVGGElement(SVGNames::gTag, document()); - m_shadowTreeRootElement->setInDocument(); - m_shadowTreeRootElement->setShadowParentNode(this); - - // Spec: An additional transformation translate(x,y) is appended to the end - // (i.e., right-side) of the transform attribute on the generated 'g', where x - // and y represent the values of the x and y attributes on the 'use' element. - if (x().value(this) != 0.0 || y().value(this) != 0.0) { - String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this)); - m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString); - } + ASSERT(m_targetElementInstance->correspondingElement() == target); // Build shadow tree from instance tree // This also handles the special cases: on , on . - buildShadowTree(target, m_targetElementInstance.get()); + buildShadowTree(shadowRoot, target, m_targetElementInstance.get()); #if ENABLE(SVG) && ENABLE(SVG_USE) // Expand all elements in the shadow tree. // Expand means: replace the actual element by what it references. - expandUseElementsInShadowTree(m_shadowTreeRootElement.get()); + expandUseElementsInShadowTree(shadowRoot, shadowRoot); // Expand all elements in the shadow tree. // Expand means: replace the actual element by the element. - expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get()); - + expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); #endif // Now that the shadow tree is completly expanded, we can associate // shadow tree elements <-> instances in the instance tree. - associateInstancesWithShadowTreeElements(m_shadowTreeRootElement->firstChild(), m_targetElementInstance.get()); + associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetElementInstance.get()); + + // If no shadow tree element is present, this means that the reference root + // element was removed, as it is disallowed (ie. on ) + // Do NOT leave an inconsistent instance tree around, instead destruct it. + if (!m_targetElementInstance->shadowTreeElement()) { + shadowRoot->removeAllChildren(); + m_targetElementInstance = 0; + return; + } + + // Consistency checks - this is assumed in updateContainerOffset(). + ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowRoot); // Eventually dump instance tree #ifdef DUMP_INSTANCE_TREE @@ -395,8 +462,8 @@ PassRefPtr serializer = XMLSerializer::create(); - String markup = serializer->serializeToString(m_shadowTreeRootElement.get(), ec); - ASSERT(ec == 0); + String markup = serializer->serializeToString(shadowRoot, ec); + ASSERT(!ec); fprintf(stderr, "Dumping shadow tree markup:\n%s\n", markup.latin1().data()); #endif @@ -404,30 +471,33 @@ // Transfer event listeners assigned to the referenced element to our shadow tree elements. transferEventListenersToShadowTree(m_targetElementInstance.get()); - // The DOM side is setup properly. Now we have to attach the root shadow - // tree element manually - using attach() won't work for "shadow nodes". - attachShadowTree(); + // Update container translation offsets + updateContainerOffsets(); } RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*) { - return new (arena) RenderSVGTransformableContainer(this); + return new (arena) RenderSVGShadowTreeRootContainer(this); +} + +static void updateFromElementCallback(Node* node) +{ + if (RenderObject* renderer = node->renderer()) + renderer->updateFromElement(); } void SVGUseElement::attach() { SVGStyledTransformableElement::attach(); - // If we're a pending resource, this doesn't have any effect. - attachShadowTree(); + if (renderer()) + queuePostAttachCallback(updateFromElementCallback, this); } void SVGUseElement::detach() { SVGStyledTransformableElement::detach(); - - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->detach(); + m_targetElementInstance = 0; } static bool isDirectReference(Node* n) @@ -443,10 +513,10 @@ Path SVGUseElement::toClipPath() const { - if (!m_shadowTreeRootElement) - const_cast(this)->buildPendingResource(); + Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0; + if (!n) + return Path(); - Node* n = m_shadowTreeRootElement->firstChild(); if (n->isSVGElement() && static_cast(n)->isStyledTransformable()) { if (!isDirectReference(n)) // Spec: Indirect references are an error (14.3.5) @@ -480,11 +550,12 @@ continue; // Create SVGElementInstance object, for both container/non-container nodes. - RefPtr instancePtr = SVGElementInstance::create(this, element); - targetInstance->appendChild(instancePtr.get()); + RefPtr instance = SVGElementInstance::create(this, element); + SVGElementInstance* instancePtr = instance.get(); + targetInstance->appendChild(instance.release()); // Enter recursion, appending new instance tree nodes to the "instance" object. - buildInstanceTree(element, instancePtr.get(), foundProblem); + buildInstanceTree(element, instancePtr, foundProblem); } // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced @@ -525,10 +596,11 @@ // Create an instance object, even if we're dealing with a cycle RefPtr newInstance = SVGElementInstance::create(this, target); - targetInstance->appendChild(newInstance); + SVGElementInstance* newInstancePtr = newInstance.get(); + targetInstance->appendChild(newInstance.release()); // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children - buildInstanceTree(target, newInstance.get(), foundProblem); + buildInstanceTree(target, newInstancePtr, foundProblem); } void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target) @@ -559,7 +631,7 @@ } } -void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance) +void SVGUseElement::buildShadowTree(SVGShadowTreeRootElement* shadowRoot, SVGElement* target, SVGElementInstance* targetInstance) { // For instance on (direct case). if (isDisallowedElement(target)) @@ -581,8 +653,8 @@ ASSERT(newChildPtr); ExceptionCode ec = 0; - m_shadowTreeRootElement->appendChild(newChild.release(), ec); - ASSERT(ec == 0); + shadowRoot->appendChild(newChild.release(), ec); + ASSERT(!ec); // Handle use referencing special case if (target->hasTagName(SVGNames::svgTag)) @@ -590,7 +662,7 @@ } #if ENABLE(SVG) && ENABLE(SVG_USE) -void SVGUseElement::expandUseElementsInShadowTree(Node* element) +void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) { // Why expand the elements in the shadow tree here, and not just // do this directly in buildShadowTree, if we encounter a element? @@ -611,28 +683,14 @@ // Don't ASSERT(target) here, it may be "pending", too. if (target) { // Setup sub-shadow tree root node - RefPtr cloneParent = new SVGGElement(SVGNames::gTag, document()); + RefPtr cloneParent = new SVGShadowTreeContainerElement(document()); // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element. transferUseAttributesToReplacedElement(use, cloneParent.get()); - // Spec: An additional transformation translate(x,y) is appended to the end - // (i.e., right-side) of the transform attribute on the generated 'g', where x - // and y represent the values of the x and y attributes on the 'use' element. - if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) { - if (!cloneParent->hasAttribute(SVGNames::transformAttr)) { - String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this)); - cloneParent->setAttribute(SVGNames::transformAttr, transformString); - } else { - String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this)); - const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr); - cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString); - } - } - ExceptionCode ec = 0; - + // For instance on (direct case). if (isDisallowedElement(target)) { // We still have to setup the replacment (). Otherwhise @@ -640,7 +698,7 @@ // Replace with referenced content. ASSERT(use->parentNode()); use->parentNode()->replaceChild(cloneParent.release(), use, ec); - ASSERT(ec == 0); + ASSERT(!ec); return; } @@ -660,28 +718,28 @@ ASSERT(newChildPtr); cloneParent->appendChild(newChild.release(), ec); - ASSERT(ec == 0); + ASSERT(!ec); // Replace with referenced content. ASSERT(use->parentNode()); use->parentNode()->replaceChild(cloneParent.release(), use, ec); - ASSERT(ec == 0); + ASSERT(!ec); // Handle use referencing special case if (target->hasTagName(SVGNames::svgTag)) alterShadowTreeForSVGTag(newChildPtr); // Immediately stop here, and restart expanding. - expandUseElementsInShadowTree(m_shadowTreeRootElement.get()); + expandUseElementsInShadowTree(shadowRoot, shadowRoot); return; } } for (RefPtr child = element->firstChild(); child; child = child->nextSibling()) - expandUseElementsInShadowTree(child.get()); + expandUseElementsInShadowTree(shadowRoot, child.get()); } -void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) +void SVGUseElement::expandSymbolElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) { if (element->hasTagName(SVGNames::symbolTag)) { // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, @@ -708,7 +766,7 @@ for (Node* child = element->firstChild(); child; child = child->nextSibling()) { RefPtr newChild = child->cloneNode(true); svgElement->appendChild(newChild.release(), ec); - ASSERT(ec == 0); + ASSERT(!ec); } // We don't walk the target tree element-by-element, and clone each element, @@ -722,43 +780,19 @@ // Replace with . ASSERT(element->parentNode()); element->parentNode()->replaceChild(svgElement.release(), element, ec); - ASSERT(ec == 0); + ASSERT(!ec); // Immediately stop here, and restart expanding. - expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get()); + expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); return; } for (RefPtr child = element->firstChild(); child; child = child->nextSibling()) - expandSymbolElementsInShadowTree(child.get()); + expandSymbolElementsInShadowTree(shadowRoot, child.get()); } #endif - -void SVGUseElement::attachShadowTree() -{ - if (!m_shadowTreeRootElement || m_shadowTreeRootElement->attached() || !document()->shouldCreateRenderers() || !attached() || !renderer()) - return; - // Inspired by RenderTextControl::createSubtreeIfNeeded(). - if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) { - RefPtr style = m_shadowTreeRootElement->styleForRenderer(); - - if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) { - m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get())); - if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) { - shadowRenderer->setStyle(style.release()); - renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer()); - m_shadowTreeRootElement->setAttached(); - } - } - - // This will take care of attaching all shadow tree child nodes. - for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling()) - child->attach(); - } -} - void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target) { if (!target) @@ -846,14 +880,19 @@ return instance; for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) { - SVGElementInstance* search = instanceForShadowTreeElement(element, current); - if (search) + if (SVGElementInstance* search = instanceForShadowTreeElement(element, current)) return search; } return 0; } +void SVGUseElement::invalidateShadowTree() +{ + m_needsShadowTreeRecreation = true; + setNeedsStyleRecalc(); +} + void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const { ASSERT(from); @@ -864,19 +903,19 @@ ExceptionCode ec = 0; to->removeAttribute(SVGNames::xAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::yAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::widthAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::heightAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(XLinkNames::hrefAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); } } diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h 2010-06-02 04:03:10.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h 2010-06-11 15:29:14.557181915 +0200 @@ -32,6 +32,7 @@ class SVGElementInstance; class SVGLength; + class SVGShadowTreeRootElement; class SVGUseElement : public SVGStyledTransformableElement, public SVGTests, @@ -52,11 +53,9 @@ virtual void buildPendingResource(); virtual void parseMappedAttribute(MappedAttribute*); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); - virtual void svgAttributeChanged(const QualifiedName&); - virtual void recalcStyle(StyleChange = NoChange); + virtual void recalcStyle(StyleChange = NoChange); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual void attach(); virtual void detach(); @@ -65,6 +64,12 @@ static void removeDisallowedElementsFromSubtree(Node* element); SVGElementInstance* instanceForShadowTreeElement(Node* element) const; + void invalidateShadowTree(); + + private: + friend class RenderSVGShadowTreeRootContainer; + bool isPendingResource() const { return m_isPendingResource; } + void buildShadowAndInstanceTree(SVGShadowTreeRootElement*); private: ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::xAttrString, SVGLength, X, x) @@ -86,26 +91,25 @@ void handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundCycle); // Shadow tree handling - PassRefPtr buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance); - void alterShadowTreeForSVGTag(SVGElement* target); - - void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance); + void alterShadowTreeForSVGTag(SVGElement*); + void buildShadowTree(SVGShadowTreeRootElement*, SVGElement* target, SVGElementInstance* targetInstance); #if ENABLE(SVG) && ENABLE(SVG_USE) - void expandUseElementsInShadowTree(Node* element); - void expandSymbolElementsInShadowTree(Node* element); + void expandUseElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); + void expandSymbolElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); #endif - void attachShadowTree(); - // "Tree connector" void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance); SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const; void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const; void transferEventListenersToShadowTree(SVGElementInstance* target); + void updateContainerOffsets(); - RefPtr m_shadowTreeRootElement; + bool m_isPendingResource; + bool m_needsShadowTreeRecreation; + String m_resourceId; RefPtr m_targetElementInstance; }; diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/WebCore.pro qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/WebCore.pro --- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/WebCore.pro 2010-06-02 04:03:11.000000000 +0200 +++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/WebCore.pro 2010-06-11 15:29:11.343280486 +0200 @@ -2066,6 +2066,7 @@ rendering/RenderSVGInlineText.h \ rendering/RenderSVGModelObject.h \ rendering/RenderSVGRoot.h \ + rendering/RenderSVGShadowTreeRootContainer.h \ rendering/RenderSVGText.h \ rendering/RenderSVGTextPath.h \ rendering/RenderSVGTransformableContainer.h \ @@ -2121,6 +2122,7 @@ rendering/SVGRenderSupport.h \ rendering/SVGRenderTreeAsText.h \ rendering/SVGRootInlineBox.h \ + rendering/SVGShadowTreeElements.h \ rendering/TextControlInnerElements.h \ rendering/TransformState.h \ svg/animation/SMILTimeContainer.h \ @@ -3093,6 +3095,7 @@ rendering/RenderSVGInlineText.cpp \ rendering/RenderSVGModelObject.cpp \ rendering/RenderSVGRoot.cpp \ + rendering/RenderSVGShadowTreeRootContainer.cpp \ rendering/RenderSVGText.cpp \ rendering/RenderSVGTextPath.cpp \ rendering/RenderSVGTransformableContainer.cpp \ @@ -3102,7 +3105,8 @@ rendering/SVGInlineFlowBox.cpp \ rendering/SVGInlineTextBox.cpp \ rendering/SVGRenderSupport.cpp \ - rendering/SVGRootInlineBox.cpp + rendering/SVGRootInlineBox.cpp \ + rendering/SVGShadowTreeElements.cpp # GENERATOR 5-C: