Commit ad2c8d9d authored by hmuller@adobe.com's avatar hmuller@adobe.com

Heap-use-after-free in WebCore::GraphicsContext::drawImage

Replaced getShapeImageAndRect() in ShapeOutsideInfo.cpp with
ShapeOutsideInfo::createShapeForImage(). The original function
failed to protect the PassRefPtr return value returned by StyleImage::image(). 

BUG=378469

Review URL: https://codereview.chromium.org/305173003

git-svn-id: svn://svn.chromium.org/blink/trunk@175176 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent c9bdf292
<!DOCTYPE html>
<html>
<!--
This is a regression test for https://code.google.com/p/chromium/issues/detail?id=378469
-->
<head>
<style>
#image-shape {
float: left;
shape-outside: linear-gradient(magenta, currentColor); // currentColor prevents gradient from being cached
width: 100px;
height: 100px;
}
</style>
<div>This test should not crash.</div>
<div>
<div id="image-shape"></div>
Hello World
</div>
<script>
if (window.testRunner)
testRunner.dumpAsText();
</script>
</body>
</html>
...@@ -97,26 +97,6 @@ static bool checkShapeImageOrigin(Document& document, const StyleImage& styleIma ...@@ -97,26 +97,6 @@ static bool checkShapeImageOrigin(Document& document, const StyleImage& styleIma
return false; return false;
} }
static void getShapeImageAndRect(const ShapeValue& shapeValue, const RenderBox& renderBox, const LayoutSize& referenceBoxSize, Image*& image, LayoutRect& rect)
{
ASSERT(shapeValue.isImageValid());
StyleImage* styleImage = shapeValue.image();
const IntSize& imageSize = renderBox.calculateImageIntrinsicDimensions(styleImage, roundedIntSize(referenceBoxSize), RenderImage::ScaleByEffectiveZoom);
styleImage->setContainerSizeForRenderer(&renderBox, imageSize, renderBox.style()->effectiveZoom());
image = 0;
if (styleImage->isImageResource() || styleImage->isImageResourceSet())
image = styleImage->cachedImage()->imageForRenderer(&renderBox);
else if (styleImage->isGeneratedImage())
image = styleImage->image(const_cast<RenderBox*>(&renderBox), imageSize).get();
if (renderBox.isRenderImage())
rect = toRenderImage(&renderBox)->replacedContentRect();
else
rect = LayoutRect(LayoutPoint(), imageSize);
}
static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const LayoutSize& referenceBoxLogicalSize) static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const LayoutSize& referenceBoxLogicalSize)
{ {
LayoutPoint marginBoxOrigin(-renderBox.marginLogicalLeft() - renderBox.borderAndPaddingLogicalLeft(), -renderBox.marginBefore() - renderBox.borderBefore() - renderBox.paddingBefore()); LayoutPoint marginBoxOrigin(-renderBox.marginLogicalLeft() - renderBox.borderAndPaddingLogicalLeft(), -renderBox.marginBefore() - renderBox.borderBefore() - renderBox.paddingBefore());
...@@ -124,6 +104,29 @@ static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const Layo ...@@ -124,6 +104,29 @@ static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const Layo
return LayoutRect(marginBoxOrigin, referenceBoxLogicalSize + marginBoxSizeDelta); return LayoutRect(marginBoxOrigin, referenceBoxLogicalSize + marginBoxSizeDelta);
} }
PassOwnPtr<Shape> ShapeOutsideInfo::createShapeForImage(StyleImage* styleImage, float shapeImageThreshold, WritingMode writingMode, float margin) const
{
const IntSize& imageSize = m_renderer.calculateImageIntrinsicDimensions(styleImage, roundedIntSize(m_referenceBoxLogicalSize), RenderImage::ScaleByEffectiveZoom);
styleImage->setContainerSizeForRenderer(&m_renderer, imageSize, m_renderer.style()->effectiveZoom());
const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
const LayoutRect& imageRect = (m_renderer.isRenderImage())
? toRenderImage(&m_renderer)->replacedContentRect()
: LayoutRect(LayoutPoint(), imageSize);
Image* image = 0;
RefPtr<Image> generatedImage;
if (styleImage->isImageResource() || styleImage->isImageResourceSet()) {
image = styleImage->cachedImage()->imageForRenderer(&m_renderer);
} else if (styleImage->isGeneratedImage()) {
generatedImage = styleImage->image(const_cast<RenderBox*>(&m_renderer), imageSize);
image = generatedImage.get();
}
return Shape::createRasterShape(image, shapeImageThreshold, imageRect, marginRect, writingMode, margin);
}
const Shape& ShapeOutsideInfo::computedShape() const const Shape& ShapeOutsideInfo::computedShape() const
{ {
if (Shape* shape = m_shape.get()) if (Shape* shape = m_shape.get())
...@@ -146,14 +149,10 @@ const Shape& ShapeOutsideInfo::computedShape() const ...@@ -146,14 +149,10 @@ const Shape& ShapeOutsideInfo::computedShape() const
ASSERT(shapeValue.shape()); ASSERT(shapeValue.shape());
m_shape = Shape::createShape(shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin); m_shape = Shape::createShape(shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
break; break;
case ShapeValue::Image: { case ShapeValue::Image:
Image* image; ASSERT(shapeValue.isImageValid());
LayoutRect imageRect; m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold, writingMode, margin);
getShapeImageAndRect(shapeValue, m_renderer, m_referenceBoxLogicalSize, image, imageRect);
const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
m_shape = Shape::createRasterShape(image, shapeImageThreshold, imageRect, marginRect, writingMode, margin);
break; break;
}
case ShapeValue::Box: { case ShapeValue::Box: {
const RoundedRect& shapeRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_renderer.view()); const RoundedRect& shapeRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_renderer.view());
m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin); m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
......
...@@ -101,6 +101,8 @@ protected: ...@@ -101,6 +101,8 @@ protected:
{ } { }
private: private:
PassOwnPtr<Shape> createShapeForImage(StyleImage*, float shapeImageThreshold, WritingMode, float margin) const;
LayoutUnit logicalTopOffset() const; LayoutUnit logicalTopOffset() const;
LayoutUnit logicalLeftOffset() const; LayoutUnit logicalLeftOffset() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment