diff options
| author | hmuller@adobe.com <hmuller@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-09-27 23:17:34 +0000 |
|---|---|---|
| committer | Konstantin Tokarev <annulen@yandex.ru> | 2016-09-27 07:16:46 +0000 |
| commit | 7cdd855e3287492093749a833b8b56c67e8db800 (patch) | |
| tree | 44dba000af3df4eb85751e1f0acca62d358a0b4c /Source/WebCore/css/CSSCalculationValue.h | |
| parent | 3bb3f4e49fec10dfe1bd58e3466384317d71ffbe (diff) | |
| download | qtwebkit-7cdd855e3287492093749a833b8b56c67e8db800.tar.gz | |
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 <allan.jensen@qt.io>
Diffstat (limited to 'Source/WebCore/css/CSSCalculationValue.h')
| -rw-r--r-- | Source/WebCore/css/CSSCalculationValue.h | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/Source/WebCore/css/CSSCalculationValue.h b/Source/WebCore/css/CSSCalculationValue.h index 266e8f76c..13a17a3b7 100644 --- a/Source/WebCore/css/CSSCalculationValue.h +++ b/Source/WebCore/css/CSSCalculationValue.h @@ -32,6 +32,7 @@ #define CSSCalculationValue_h #include "CSSParserValues.h" +#include "CSSPrimitiveValue.h" #include "CSSValue.h" #include "CalculationValue.h" #include <wtf/PassOwnPtr.h> @@ -42,9 +43,10 @@ namespace WebCore { class CSSParserValueList; class CSSValueList; -class RenderStyle; class CalculationValue; class CalcExpressionNode; +class RenderStyle; +struct Length; enum CalculationCategory { CalcNumber = 0, @@ -57,7 +59,7 @@ enum CalculationCategory { #endif CalcOther }; - + class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> { public: enum Type { @@ -67,7 +69,7 @@ public: virtual ~CSSCalcExpressionNode() = 0; virtual bool isZero() const = 0; - virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const RenderStyle*, const RenderStyle* rootStyle, double zoom = 1.0) const = 0; + virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const RenderStyle*, const RenderStyle* rootStyle, double zoom = 1.0) const = 0; virtual double doubleValue() const = 0; virtual double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const = 0; virtual String customCssText() const = 0; @@ -78,56 +80,84 @@ public: virtual bool equals(const CSSCalcExpressionNode& other) const { return m_category == other.m_category && m_isInteger == other.m_isInteger; } virtual Type type() const = 0; - CalculationCategory category() const { return m_category; } + CalculationCategory category() const { return m_category; } + virtual CSSPrimitiveValue::UnitTypes primitiveType() const = 0; bool isInteger() const { return m_isInteger; } - + protected: CSSCalcExpressionNode(CalculationCategory category, bool isInteger) : m_category(category) , m_isInteger(isInteger) { } - + CalculationCategory m_category; bool m_isInteger; }; - + class CSSCalcValue : public CSSValue { public: static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, CalculationPermittedValueRange); - static PassRefPtr<CSSCalcValue> create(CalculationValue*); + static PassRefPtr<CSSCalcValue> create(PassRefPtr<CSSCalcExpressionNode>, CalculationPermittedValueRange = CalculationRangeAll); + static PassRefPtr<CSSCalcValue> create(const CalculationValue* value, const RenderStyle* style) { return adoptRef(new CSSCalcValue(value, style)); } + + static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSPrimitiveValue>, bool isInteger = false); + static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSCalcExpressionNode>, PassRefPtr<CSSCalcExpressionNode>, CalcOperator); + static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const CalcExpressionNode*, const RenderStyle*); + static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const Length&, const RenderStyle*); PassRefPtr<CalculationValue> toCalcValue(const RenderStyle* style, const RenderStyle* rootStyle, double zoom = 1.0) const { return CalculationValue::create(m_expression->toCalcValue(style, rootStyle, zoom), m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll); } CalculationCategory category() const { return m_expression->category(); } - bool isInt() const { return m_expression->isInteger(); } + bool isInt() const { return m_expression->isInteger(); } double doubleValue() const; bool isNegative() const { return m_expression->doubleValue() < 0; } + CalculationPermittedValueRange permittedValueRange() { return m_nonNegative ? CalculationRangeNonNegative : CalculationRangeAll; } double computeLengthPx(const RenderStyle* currentStyle, const RenderStyle* rootStyle, double multiplier = 1.0, bool computingFontSize = false) const; - + + CSSCalcExpressionNode* expressionNode() const { return m_expression.get(); } + String customCssText() const; bool equals(const CSSCalcValue&) const; #if ENABLE(CSS_VARIABLES) String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const; bool hasVariableReference() const; #endif - -private: + +private: CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression, CalculationPermittedValueRange range) : CSSValue(CalculationClass) , m_expression(expression) , m_nonNegative(range == CalculationRangeNonNegative) { } - + CSSCalcValue(const CalculationValue* value, const RenderStyle* style) + : CSSValue(CalculationClass) + , m_expression(createExpressionNode(value->expression(), style)) + , m_nonNegative(value->isNonNegative()) + { + } + double clampToPermittedRange(double) const; const RefPtr<CSSCalcExpressionNode> m_expression; const bool m_nonNegative; }; - + +inline CSSCalcValue* toCSSCalcValue(CSSValue* value) +{ + ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isCalculationValue()); + return static_cast<CSSCalcValue*>(value); +} + +inline const CSSCalcValue* toCSSCalcValue(const CSSValue* value) +{ + ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isCalculationValue()); + return static_cast<const CSSCalcValue*>(value); +} + } // namespace WebCore #endif // CSSCalculationValue_h |
