qt/qt-everywhere-opensource-sr...

1417 lines
58 KiB
Diff

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<SVGUseElement*>(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<SVGShadowTreeRootElement> 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 <wildfox@kde.org>
+ Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005, 2006 Rob Buis <buis@kde.org>
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<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
+ if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement())
+ return;
+
+ FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(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<RenderStyle> 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<RenderStyle>, 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<ContainerNode*>(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 <wtf/RefCountedLeakCounter.h>
-#if USE(JSC)
-#include "GCController.h"
-#endif
-
namespace WebCore {
#ifndef NDEBUG
@@ -51,8 +47,7 @@
}
SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> 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<SVGElementInstance> child)
{
appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this);
@@ -114,27 +95,24 @@
void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
{
- if (!element)
+ if (!element || !element->isStyled())
+ return;
+
+ if (static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked())
return;
HashSet<SVGElementInstance*> 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<SVGElementInstance*>::const_iterator it = set.begin();
const HashSet<SVGElementInstance*>::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<EventListener>, bool useCapture);
@@ -129,7 +126,6 @@
void appendChild(PassRefPtr<SVGElementInstance> child);
void setShadowTreeElement(SVGElement*);
- void forgetWrapper();
template<class GenericNode, class GenericNodeContainer>
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<SVGElement> m_element;
RefPtr<SVGElement> 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<const SVGStyledElement*>* 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<const SVGStyledElement*>;
- 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 <zimmermann@kde.org>
2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- 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<RenderSVGShadowTreeRootContainer*>(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<SVGGElement*>(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<SVGUseElement*>(correspondingElement);
+ SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(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<SVGGElement*>(parentNode)->isShadowTreeContainerElement());
- return false;
+ SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(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<RenderStyle> 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<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation();
+ m_needsShadowTreeRecreation = false;
}
- // Only change==Detach needs special treatment, for anything else recalcStyle() works.
- m_shadowTreeRootElement->recalcStyle(change);
+ RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(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 <use> 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<SVGElement*>(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 <use> 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: <use> on <symbol>, <use> on <svg>.
- buildShadowTree(target, m_targetElementInstance.get());
+ buildShadowTree(shadowRoot, target, m_targetElementInstance.get());
#if ENABLE(SVG) && ENABLE(SVG_USE)
// Expand all <use> elements in the shadow tree.
// Expand means: replace the actual <use> element by what it references.
- expandUseElementsInShadowTree(m_shadowTreeRootElement.get());
+ expandUseElementsInShadowTree(shadowRoot, shadowRoot);
// Expand all <symbol> elements in the shadow tree.
// Expand means: replace the actual <symbol> element by the <svg> 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. <use> on <foreignObject>)
+ // 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<XMLSerializer> 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 <use> 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<SVGUseElement*>(this)->buildPendingResource();
+ Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
+ if (!n)
+ return Path();
- Node* n = m_shadowTreeRootElement->firstChild();
if (n->isSVGElement() && static_cast<SVGElement*>(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<SVGElementInstance> instancePtr = SVGElementInstance::create(this, element);
- targetInstance->appendChild(instancePtr.get());
+ RefPtr<SVGElementInstance> 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<SVGElementInstance> 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 <use> on <foreignObject> (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 <svg> 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 <use> elements in the shadow tree here, and not just
// do this directly in buildShadowTree, if we encounter a <use> element?
@@ -611,28 +683,14 @@
// Don't ASSERT(target) here, it may be "pending", too.
if (target) {
// Setup sub-shadow tree root node
- RefPtr<SVGElement> cloneParent = new SVGGElement(SVGNames::gTag, document());
+ RefPtr<SVGShadowTreeContainerElement> 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 <use> on <foreignObject> (direct case).
if (isDisallowedElement(target)) {
// We still have to setup the <use> replacment (<g>). Otherwhise
@@ -640,7 +698,7 @@
// Replace <use> 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 <use> with referenced content.
ASSERT(use->parentNode());
use->parentNode()->replaceChild(cloneParent.release(), use, ec);
- ASSERT(ec == 0);
+ ASSERT(!ec);
// Handle use referencing <svg> 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<Node> 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<Node> 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 <symbol> with <svg>.
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<Node> 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<RenderStyle> 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<SVGSVGElement> 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<SVGElement> m_shadowTreeRootElement;
+ bool m_isPendingResource;
+ bool m_needsShadowTreeRecreation;
+ String m_resourceId;
RefPtr<SVGElementInstance> 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: