Title: [225872] trunk
Revision
225872
Author
[email protected]
Date
2017-12-13 14:13:32 -0800 (Wed, 13 Dec 2017)

Log Message

RenderImage can be destroyed even before setting the style on it.
https://bugs.webkit.org/show_bug.cgi?id=180767
<rdar://problem/33965995>

Reviewed by Simon Fraser.

Source/WebCore:

In certain cases, when the newly constructed renderer can't be inserted into the tree (parent can only have specific type of children etc),
RenderTreeUpdater destroys it right away. While destroying a RenderImage, the associated image resource assumes
that the image renderer has been initialized through RenderElement::initializeStyle(). This is an incorrect
assumption.
This patch also makes RenderImageResource's m_renderer a weak pointer.

Test: fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html

* rendering/RenderImageResource.cpp:
(WebCore::RenderImageResource::initialize):
(WebCore::RenderImageResource::setCachedImage):
(WebCore::RenderImageResource::resetAnimation):
(WebCore::RenderImageResource::image const):
(WebCore::RenderImageResource::setContainerContext):
(WebCore::RenderImageResource::imageSize const):
* rendering/RenderImageResource.h:
(WebCore::RenderImageResource::renderer const):
* rendering/RenderImageResourceStyleImage.cpp:
(WebCore::RenderImageResourceStyleImage::shutdown):

LayoutTests:

* fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle-expected.txt: Added.
* fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225871 => 225872)


--- trunk/LayoutTests/ChangeLog	2017-12-13 21:58:19 UTC (rev 225871)
+++ trunk/LayoutTests/ChangeLog	2017-12-13 22:13:32 UTC (rev 225872)
@@ -1,3 +1,14 @@
+2017-12-13  Zalan Bujtas  <[email protected]>
+
+        RenderImage can be destroyed even before setting the style on it.
+        https://bugs.webkit.org/show_bug.cgi?id=180767
+        <rdar://problem/33965995>
+
+        Reviewed by Simon Fraser.
+
+        * fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle-expected.txt: Added.
+        * fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html: Added.
+
 2017-12-13  Matt Lewis  <[email protected]>
 
         Marked accessibility/mac/html5-input-number.html as flaky on macOS.

Added: trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle-expected.txt (0 => 225872)


--- trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle-expected.txt	2017-12-13 22:13:32 UTC (rev 225872)
@@ -0,0 +1,2 @@
+PASS if no crash.
+

Added: trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html (0 => 225872)


--- trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html	2017-12-13 22:13:32 UTC (rev 225872)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+col { content: url(data:image/gif;base64,foobar); }
+</style>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+</head>
+<body>
+PASS if no crash.
+<table>
+<col>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (225871 => 225872)


--- trunk/Source/WebCore/ChangeLog	2017-12-13 21:58:19 UTC (rev 225871)
+++ trunk/Source/WebCore/ChangeLog	2017-12-13 22:13:32 UTC (rev 225872)
@@ -1,3 +1,31 @@
+2017-12-13  Zalan Bujtas  <[email protected]>
+
+        RenderImage can be destroyed even before setting the style on it.
+        https://bugs.webkit.org/show_bug.cgi?id=180767
+        <rdar://problem/33965995>
+
+        Reviewed by Simon Fraser.
+
+        In certain cases, when the newly constructed renderer can't be inserted into the tree (parent can only have specific type of children etc),
+        RenderTreeUpdater destroys it right away. While destroying a RenderImage, the associated image resource assumes
+        that the image renderer has been initialized through RenderElement::initializeStyle(). This is an incorrect
+        assumption.
+        This patch also makes RenderImageResource's m_renderer a weak pointer.
+           
+        Test: fast/images/crash-when-image-renderer-is-destroyed-before-calling-initializeStyle.html
+
+        * rendering/RenderImageResource.cpp:
+        (WebCore::RenderImageResource::initialize):
+        (WebCore::RenderImageResource::setCachedImage):
+        (WebCore::RenderImageResource::resetAnimation):
+        (WebCore::RenderImageResource::image const):
+        (WebCore::RenderImageResource::setContainerContext):
+        (WebCore::RenderImageResource::imageSize const):
+        * rendering/RenderImageResource.h:
+        (WebCore::RenderImageResource::renderer const):
+        * rendering/RenderImageResourceStyleImage.cpp:
+        (WebCore::RenderImageResourceStyleImage::shutdown):
+
 2017-12-13  Ryosuke Niwa  <[email protected]>
 
         Update the SVG use element's shadow trees explicitly before the style recall

Modified: trunk/Source/WebCore/rendering/RenderImageResource.cpp (225871 => 225872)


--- trunk/Source/WebCore/rendering/RenderImageResource.cpp	2017-12-13 21:58:19 UTC (rev 225871)
+++ trunk/Source/WebCore/rendering/RenderImageResource.cpp	2017-12-13 22:13:32 UTC (rev 225872)
@@ -47,7 +47,7 @@
 {
     ASSERT(!m_renderer);
     ASSERT(!m_cachedImage);
-    m_renderer = &renderer;
+    m_renderer = makeWeakPtr(renderer);
     m_cachedImage = styleCachedImage;
     m_cachedImageRemoveClientIsNeeded = !styleCachedImage;
 }
@@ -65,15 +65,15 @@
 
     ASSERT(m_renderer);
     if (m_cachedImage && m_cachedImageRemoveClientIsNeeded)
-        m_cachedImage->removeClient(*m_renderer);
+        m_cachedImage->removeClient(*renderer());
     m_cachedImage = newImage;
     m_cachedImageRemoveClientIsNeeded = true;
     if (!m_cachedImage)
         return;
 
-    m_cachedImage->addClient(*m_renderer);
+    m_cachedImage->addClient(*renderer());
     if (m_cachedImage->errorOccurred())
-        m_renderer->imageChanged(m_cachedImage.get());
+        renderer()->imageChanged(m_cachedImage.get());
 }
 
 void RenderImageResource::resetAnimation()
@@ -84,8 +84,8 @@
     ASSERT(m_renderer);
     image()->resetAnimation();
 
-    if (!m_renderer->needsLayout())
-        m_renderer->repaint();
+    if (!renderer()->needsLayout())
+        renderer()->repaint();
 }
 
 RefPtr<Image> RenderImageResource::image(const IntSize&) const
@@ -92,7 +92,7 @@
 {
     if (!m_cachedImage)
         return &Image::nullImage();
-    if (auto image = m_cachedImage->imageForRenderer(m_renderer))
+    if (auto image = m_cachedImage->imageForRenderer(renderer()))
         return image;
     return &Image::nullImage();
 }
@@ -102,7 +102,7 @@
     if (!m_cachedImage)
         return;
     ASSERT(m_renderer);
-    m_cachedImage->setContainerContextForClient(*m_renderer, imageContainerSize, m_renderer->style().effectiveZoom(), imageURL);
+    m_cachedImage->setContainerContextForClient(*renderer(), imageContainerSize, renderer()->style().effectiveZoom(), imageURL);
 }
 
 LayoutSize RenderImageResource::imageSize(float multiplier, CachedImage::SizeType type) const
@@ -109,9 +109,9 @@
 {
     if (!m_cachedImage)
         return LayoutSize();
-    LayoutSize size = m_cachedImage->imageSizeForRenderer(m_renderer, multiplier, type);
-    if (is<RenderImage>(m_renderer))
-        size.scale(downcast<RenderImage>(*m_renderer).imageDevicePixelRatio());
+    LayoutSize size = m_cachedImage->imageSizeForRenderer(renderer(), multiplier, type);
+    if (is<RenderImage>(renderer()))
+        size.scale(downcast<RenderImage>(*renderer()).imageDevicePixelRatio());
     return size;
 }
 

Modified: trunk/Source/WebCore/rendering/RenderImageResource.h (225871 => 225872)


--- trunk/Source/WebCore/rendering/RenderImageResource.h	2017-12-13 21:58:19 UTC (rev 225871)
+++ trunk/Source/WebCore/rendering/RenderImageResource.h	2017-12-13 22:13:32 UTC (rev 225872)
@@ -29,6 +29,7 @@
 #include "CachedResourceHandle.h"
 #include "StyleImage.h"
 #include <wtf/IsoMalloc.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -63,13 +64,13 @@
     virtual WrappedImagePtr imagePtr() const { return m_cachedImage.get(); }
 
 protected:
-    RenderElement* renderer() const { return m_renderer; }
+    RenderElement* renderer() const { return m_renderer.get(); }
     void initialize(RenderElement&, CachedImage*);
     
 private:
     virtual LayoutSize imageSize(float multiplier, CachedImage::SizeType) const;
 
-    RenderElement* m_renderer { nullptr };
+    WeakPtr<RenderElement> m_renderer;
     CachedResourceHandle<CachedImage> m_cachedImage;
     bool m_cachedImageRemoveClientIsNeeded { true };
 };

Modified: trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp (225871 => 225872)


--- trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp	2017-12-13 21:58:19 UTC (rev 225871)
+++ trunk/Source/WebCore/rendering/RenderImageResourceStyleImage.cpp	2017-12-13 22:13:32 UTC (rev 225872)
@@ -50,9 +50,9 @@
 
 void RenderImageResourceStyleImage::shutdown()
 {
-    ASSERT(renderer());
     RenderImageResource::shutdown();
-    m_styleImage->removeClient(renderer());
+    if (renderer())
+        m_styleImage->removeClient(renderer());
 }
 
 RefPtr<Image> RenderImageResourceStyleImage::image(const IntSize& size) const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to