Title: [261291] trunk/Source/WebCore
Revision
261291
Author
da...@apple.com
Date
2020-05-07 09:00:55 -0700 (Thu, 07 May 2020)

Log Message

Fix assertions seen when trying to draw an absurdly large shadow
https://bugs.webkit.org/show_bug.cgi?id=211541
rdar://62843377

Reviewed by Geoffrey Garen.

* platform/graphics/IntSize.h:
(WebCore::IntSize::unclampedArea const): Return uint64_t instead of
size_t. Two 32-bit positive integers multiplied fit in a 64-bit integer,
but there's no guarantee they fit in a "pointer sized" integer.

* platform/graphics/ShadowBlur.cpp:
(WebCore::ShadowBlur::drawRectShadow): When comparing an IntSize area with
a FloatSize area, avoid checked overflow by using IntSize::unclampedArea,
which returns something we can compare with a float. Using IntSize::area
meant we'd intentionally crash the process if the area number doesn't fit
in a 32-bit int, which is not important or helpful.
(WebCore::ShadowBlur::drawRectShadowWithTiling): Make sure
ScratchBuffer::scheduleScratchBufferPurge is always called after
ScratchBuffer::getScratchBuffer, even it returns nullptr. An alternative
would have been to change the logic inside getScratchBuffer, but this
seems easier to get right, and no need to optimize the failure case.
(WebCore::ShadowBlur::drawInsetShadowWithTiling): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261290 => 261291)


--- trunk/Source/WebCore/ChangeLog	2020-05-07 15:37:51 UTC (rev 261290)
+++ trunk/Source/WebCore/ChangeLog	2020-05-07 16:00:55 UTC (rev 261291)
@@ -1,3 +1,29 @@
+2020-05-07  Darin Adler  <da...@apple.com>
+
+        Fix assertions seen when trying to draw an absurdly large shadow
+        https://bugs.webkit.org/show_bug.cgi?id=211541
+        rdar://62843377
+
+        Reviewed by Geoffrey Garen.
+
+        * platform/graphics/IntSize.h:
+        (WebCore::IntSize::unclampedArea const): Return uint64_t instead of
+        size_t. Two 32-bit positive integers multiplied fit in a 64-bit integer,
+        but there's no guarantee they fit in a "pointer sized" integer.
+
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::drawRectShadow): When comparing an IntSize area with
+        a FloatSize area, avoid checked overflow by using IntSize::unclampedArea,
+        which returns something we can compare with a float. Using IntSize::area
+        meant we'd intentionally crash the process if the area number doesn't fit
+        in a 32-bit int, which is not important or helpful.
+        (WebCore::ShadowBlur::drawRectShadowWithTiling): Make sure
+        ScratchBuffer::scheduleScratchBufferPurge is always called after
+        ScratchBuffer::getScratchBuffer, even it returns nullptr. An alternative
+        would have been to change the logic inside getScratchBuffer, but this
+        seems easier to get right, and no need to optimize the failure case.
+        (WebCore::ShadowBlur::drawInsetShadowWithTiling): Ditto.
+
 2020-05-07  Youenn Fablet  <you...@apple.com>
 
         Fix potential threading issue in AudioMediaStreamTrackRendererCocoa::render

Modified: trunk/Source/WebCore/platform/graphics/IntSize.h (261290 => 261291)


--- trunk/Source/WebCore/platform/graphics/IntSize.h	2020-05-07 15:37:51 UTC (rev 261290)
+++ trunk/Source/WebCore/platform/graphics/IntSize.h	2020-05-07 16:00:55 UTC (rev 261291)
@@ -136,9 +136,9 @@
         return Checked<unsigned, T>(abs(m_width)) * abs(m_height);
     }
 
-    size_t unclampedArea() const
+    uint64_t unclampedArea() const
     {
-        return static_cast<size_t>(abs(m_width)) * abs(m_height);
+        return static_cast<uint64_t>(abs(m_width)) * abs(m_height);
     }
 
     int diagonalLengthSquared() const

Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp (261290 => 261291)


--- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2020-05-07 15:37:51 UTC (rev 261290)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2020-05-07 16:00:55 UTC (rev 261291)
@@ -39,6 +39,7 @@
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/Scope.h>
 
 namespace WebCore {
 
@@ -554,7 +555,7 @@
     const FloatRect& rect = shadowedRect.rect();
 
     if (templateSize.width() > rect.width() || templateSize.height() > rect.height()
-        || (templateSize.area() > layerImageProperties->shadowedResultSize.area()))
+        || (templateSize.unclampedArea() > layerImageProperties->shadowedResultSize.area()))
         canUseTilingTechnique = false;
 
     if (canUseTilingTechnique)
@@ -684,6 +685,9 @@
 {
 #if USE(CG)
     auto* layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
+    auto releaseLayerImage = makeScopeExit([] {
+        ScratchBuffer::singleton().scheduleScratchBufferPurge();
+    });
 #else
     UNUSED_PARAM(layerImageProperties);
     auto layerImageBuffer = ImageBuffer::create(templateSize, RenderingMode::Unaccelerated, 1);
@@ -729,10 +733,6 @@
     shadowBounds.inflateY(edgeSize.height());
 
     drawLayerPiecesAndFillCenter(*layerImage, shadowBounds, shadowedRect.radii(), edgeSize, templateSize, drawImage, fillRect);
-
-#if USE(CG)
-    ScratchBuffer::singleton().scheduleScratchBufferPurge();
-#endif
 }
 
 void ShadowBlur::drawInsetShadowWithTiling(const AffineTransform& transform, const FloatRect& fullRect, const FloatRoundedRect& holeRect, const IntSize& templateSize, const IntSize& edgeSize, const DrawImageCallback& drawImage, const FillRectWithHoleCallback& fillRectWithHole)
@@ -739,6 +739,9 @@
 {
 #if USE(CG)
     auto* layerImage = ScratchBuffer::singleton().getScratchBuffer(templateSize);
+    auto releaseLayerImage = makeScopeExit([] {
+        ScratchBuffer::singleton().scheduleScratchBufferPurge();
+    });
 #else
     auto layerImageBuffer = ImageBuffer::create(templateSize, RenderingMode::Unaccelerated, 1);
     auto* layerImage = layerImageBuffer.get();
@@ -793,10 +796,6 @@
     fillRectWithHole(boundingRect, destHoleBounds, m_color);
 
     drawLayerPieces(*layerImage, destHoleBounds, holeRect.radii(), edgeSize, templateSize, drawImage);
-
-#if USE(CG)
-    ScratchBuffer::singleton().scheduleScratchBufferPurge();
-#endif
 }
 
 void ShadowBlur::drawLayerPieces(ImageBuffer& layerImage, const FloatRect& shadowBounds, const FloatRoundedRect::Radii& radii, const IntSize& bufferPadding, const IntSize& templateSize, const DrawImageCallback& drawImage)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to