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)