From 7cdd855e3287492093749a833b8b56c67e8db800 Mon Sep 17 00:00:00 2001 From: "hmuller@adobe.com" Date: Fri, 27 Sep 2013 23:17:34 +0000 Subject: Crash on shape-outside when using calc() https://bugs.webkit.org/show_bug.cgi?id=121020 Reviewed by Dirk Schulze. Source/WebCore: This change prevents a crash caused by specifying a CSS Shape geometry Length attribute with a calc() expression. It adds support for converting Lengths to CSSPrimitive Values, in large part by migrating Blink changes made to the calc classes since the split. Doing so required a few supporting changes in some related classes, notably CSSPrimitiveValue. Tests: fast/shapes/shape-inside/shape-inside-calc-crash.html css3/calc/simplification.html * css/BasicShapeFunctions.cpp: (WebCore::convertToCSSPrimitiveValue): Effectively use the new CSSPrimtiveValue(length,style) constructor to convert Lengths to CSSValues. (WebCore::valueForBasicShape): Use the convertToCSSPrimitiveValue() function. (WebCore::convertToLength): Added the CalculatedConversion convertToLength() flag to enable support for calc() valued Length Shape attributes. * css/BasicShapeFunctions.h: * css/CSSCalculationValue.cpp: (WebCore::hasDoubleValue): (WebCore::buildCssText): (WebCore::CSSCalcValue::clampToPermittedRange): (WebCore::CSSCalcValue::doubleValue): (WebCore::CSSCalcExpressionNode::~CSSCalcExpressionNode): (WebCore::CSSCalcPrimitiveValue::create): (WebCore::CSSCalcPrimitiveValue::toCalcValue): (WebCore::CSSCalcPrimitiveValue::doubleValue): (WebCore::CSSCalcPrimitiveValue::computeLengthPx): (WebCore::CSSCalcPrimitiveValue::primitiveType): (WebCore::CSSCalcPrimitiveValue::CSSCalcPrimitiveValue): (WebCore::determineCategory): (WebCore::isIntegerResult): (WebCore::CSSCalcBinaryOperation::create): (WebCore::CSSCalcBinaryOperation::createSimplified): (WebCore::CSSCalcBinaryOperation::doubleValue): (WebCore::CSSCalcBinaryOperation::buildCssText): (WebCore::CSSCalcBinaryOperation::primitiveType): (WebCore::CSSCalcBinaryOperation::CSSCalcBinaryOperation): (WebCore::CSSCalcBinaryOperation::getNumberSide): (WebCore::CSSCalcBinaryOperation::evaluate): (WebCore::CSSCalcBinaryOperation::evaluateOperator): (WebCore::CSSCalcExpressionNodeParser::parseValue): (WebCore::CSSCalcExpressionNodeParser::parseValueTerm): (WebCore::CSSCalcExpressionNodeParser::parseValueMultiplicativeExpression): (WebCore::CSSCalcExpressionNodeParser::parseAdditiveValueExpression): (WebCore::CSSCalcValue::createExpressionNode): (WebCore::CSSCalcValue::create): * css/CSSCalculationValue.h: (WebCore::CSSCalcExpressionNode::category): (WebCore::CSSCalcValue::create): (WebCore::CSSCalcValue::isInt): (WebCore::CSSCalcValue::permittedValueRange): (WebCore::CSSCalcValue::expressionNode): (WebCore::CSSCalcValue::CSSCalcValue): (WebCore::toCSSCalcValue): * css/CSSComputedStyleDeclaration.cpp: (WebCore::ComputedStyleExtractor::propertyValue): Pass the style along to the new valueForBasicShape() function. * css/CSSPrimitiveValue.cpp: (WebCore::CSSPrimitiveValue::unitCategory): Made this function public so that CSSCalculationValue could use it. (WebCore::CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor): Ditto. (WebCore::CSSPrimitiveValue::primitiveType): Cleared trailing whitespace. (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Construct a CSSPrimitiveValue from a Length and a RenderStyle*. (WebCore::CSSPrimitiveValue::init): The common part of the two Length CSSPrimitiveValue constructors. (WebCore::CSSPrimitiveValue::computeLengthDouble): Moved the case labels to the left per check-webkit-style. (WebCore::CSSPrimitiveValue::getStringValue): Ditto. (WebCore::CSSPrimitiveValue::getDoubleValue): Removed trailing whitespace. * css/CSSPrimitiveValue.h: (WebCore::CSSPrimitiveValue::create): Construct a CSSPrimitiveValue from a Length and a RenderStyle*. (WebCore::toCSSPrimitiveValue): Check the CSSValue*'s validity with ASSERT_WITH_SECURITY_IMPLICATION before casting to CSSPrimitiveValue*. * css/CSSValuePool.h: (WebCore::CSSValuePool::createValue): A new overload that delegates to the new CSSPrimitiveValue(length,style) constructor. * platform/CalculationValue.h: (WebCore::CalculationValue::operator==): (WebCore::CalculationValue::isNonNegative): (WebCore::CalculationValue::expression): (WebCore::CalcExpressionNumber::value): (WebCore::toCalcExpressionNumber): (WebCore::CalcExpressionLength::CalcExpressionLength): (WebCore::CalcExpressionLength::length): (WebCore::toCalcExpressionLength): (WebCore::CalcExpressionBinaryOperation::leftSide): (WebCore::CalcExpressionBinaryOperation::rightSide): (WebCore::CalcExpressionBinaryOperation::getOperator): (WebCore::toCalcExpressionBinaryOperation): (WebCore::CalcExpressionBlendLength::CalcExpressionBlendLength): (WebCore::CalcExpressionBlendLength::from): (WebCore::CalcExpressionBlendLength::to): (WebCore::CalcExpressionBlendLength::progress): (WebCore::toCalcExpressionBlendLength): LayoutTests: Specifying a CSS Shape geometry Length attribute with a calc() expression or looking up the value with getComputedStyle(), caused crashes. * fast/shapes/shape-inside/shape-inside-calc-crash-expected.txt: Added. * fast/shapes/shape-inside/shape-inside-calc-crash.html: Added. * css3/calc/simplification-expected.txt: Added * css3/calc/simplification.html: Added * LayoutTests/css3/calc/cssom-expected.txt: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156586 268f45cc-cd09-0410-ab3c-d52691b4dbfc Change-Id: I38216be400bd7024999444d9c1c7e5ad79cce2de Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/css/BasicShapeFunctions.cpp | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'Source/WebCore/css/BasicShapeFunctions.cpp') diff --git a/Source/WebCore/css/BasicShapeFunctions.cpp b/Source/WebCore/css/BasicShapeFunctions.cpp index c5885095e..a99739a78 100644 --- a/Source/WebCore/css/BasicShapeFunctions.cpp +++ b/Source/WebCore/css/BasicShapeFunctions.cpp @@ -38,7 +38,7 @@ namespace WebCore { -PassRefPtr valueForBasicShape(const BasicShape* basicShape) +PassRefPtr valueForBasicShape(const RenderStyle* style, const BasicShape* basicShape) { RefPtr basicShapeValue; switch (basicShape->type()) { @@ -46,12 +46,12 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) const BasicShapeRectangle* rectangle = static_cast(basicShape); RefPtr rectangleValue = CSSBasicShapeRectangle::create(); - rectangleValue->setX(cssValuePool().createValue(rectangle->x())); - rectangleValue->setY(cssValuePool().createValue(rectangle->y())); - rectangleValue->setWidth(cssValuePool().createValue(rectangle->width())); - rectangleValue->setHeight(cssValuePool().createValue(rectangle->height())); - rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX())); - rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY())); + rectangleValue->setX(cssValuePool().createValue(rectangle->x(), style)); + rectangleValue->setY(cssValuePool().createValue(rectangle->y(), style)); + rectangleValue->setWidth(cssValuePool().createValue(rectangle->width(), style)); + rectangleValue->setHeight(cssValuePool().createValue(rectangle->height(), style)); + rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX(), style)); + rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY(), style)); basicShapeValue = rectangleValue.release(); break; @@ -60,9 +60,9 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) const BasicShapeCircle* circle = static_cast(basicShape); RefPtr circleValue = CSSBasicShapeCircle::create(); - circleValue->setCenterX(cssValuePool().createValue(circle->centerX())); - circleValue->setCenterY(cssValuePool().createValue(circle->centerY())); - circleValue->setRadius(cssValuePool().createValue(circle->radius())); + circleValue->setCenterX(cssValuePool().createValue(circle->centerX(), style)); + circleValue->setCenterY(cssValuePool().createValue(circle->centerY(), style)); + circleValue->setRadius(cssValuePool().createValue(circle->radius(), style)); basicShapeValue = circleValue.release(); break; @@ -71,10 +71,10 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) const BasicShapeEllipse* ellipse = static_cast(basicShape); RefPtr ellipseValue = CSSBasicShapeEllipse::create(); - ellipseValue->setCenterX(cssValuePool().createValue(ellipse->centerX())); - ellipseValue->setCenterY(cssValuePool().createValue(ellipse->centerY())); - ellipseValue->setRadiusX(cssValuePool().createValue(ellipse->radiusX())); - ellipseValue->setRadiusY(cssValuePool().createValue(ellipse->radiusY())); + ellipseValue->setCenterX(cssValuePool().createValue(ellipse->centerX(), style)); + ellipseValue->setCenterY(cssValuePool().createValue(ellipse->centerY(), style)); + ellipseValue->setRadiusX(cssValuePool().createValue(ellipse->radiusX(), style)); + ellipseValue->setRadiusY(cssValuePool().createValue(ellipse->radiusY(), style)); basicShapeValue = ellipseValue.release(); break; @@ -86,7 +86,7 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) polygonValue->setWindRule(polygon->windRule()); const Vector& values = polygon->values(); for (unsigned i = 0; i < values.size(); i += 2) - polygonValue->appendPoint(cssValuePool().createValue(values.at(i)), cssValuePool().createValue(values.at(i + 1))); + polygonValue->appendPoint(cssValuePool().createValue(values.at(i), style), cssValuePool().createValue(values.at(i + 1), style)); basicShapeValue = polygonValue.release(); break; @@ -95,12 +95,12 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) const BasicShapeInsetRectangle* rectangle = static_cast(basicShape); RefPtr rectangleValue = CSSBasicShapeInsetRectangle::create(); - rectangleValue->setTop(cssValuePool().createValue(rectangle->top())); - rectangleValue->setRight(cssValuePool().createValue(rectangle->right())); - rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom())); - rectangleValue->setLeft(cssValuePool().createValue(rectangle->left())); - rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX())); - rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY())); + rectangleValue->setTop(cssValuePool().createValue(rectangle->top(), style)); + rectangleValue->setRight(cssValuePool().createValue(rectangle->right(), style)); + rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom(), style)); + rectangleValue->setLeft(cssValuePool().createValue(rectangle->left(), style)); + rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX(), style)); + rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY(), style)); basicShapeValue = rectangleValue.release(); break; @@ -113,7 +113,7 @@ PassRefPtr valueForBasicShape(const BasicShape* basicShape) static Length convertToLength(const RenderStyle* style, const RenderStyle* rootStyle, CSSPrimitiveValue* value) { - return value->convertToLength(style, rootStyle, style->effectiveZoom()); + return value->convertToLength(style, rootStyle, style->effectiveZoom()); } PassRefPtr basicShapeForValue(const RenderStyle* style, const RenderStyle* rootStyle, const CSSBasicShape* basicShapeValue) -- cgit v1.2.1