Ignore:
Timestamp:
Jul 23, 2012, 10:34:42 PM (13 years ago)
Author:
[email protected]
Message:

Null-pointer crash when a derived color like -webkit-activelink is set in a gradient stop
https://bugs.webkit.org/show_bug.cgi?id=89148

Patch by Douglas Stockwell <[email protected]> on 2012-07-23
Reviewed by Simon Fraser.

Source/WebCore:

CSSGradientValue attempted to resolve colors during paint, this crashed
when a derived color like -webkit-activelink was encountered because the
corresponding element was no longer available in the StyleResolver.
Instead, by adding a field to CSSGradientColorStop we can resolve and
then cache the resolved colors at the correct time. To avoid sharing
cached derived colors between elements we clone the gradient values when
needed.

Test: fast/css/crash-on-gradient-with-derived-color.html

  • css/CSSGradientValue.cpp:

(WebCore::CSSGradientValue::gradientWithStylesResolved): Added. Resolve and cache
resolved colors, clone if colors are derived from the element.
(WebCore):
(WebCore::CSSGradientValue::addStops):
(WebCore::CSSGradientValue::isCacheable): Defer to new logic in
StyleResolver.

  • css/CSSGradientValue.h:

(CSSGradientColorStop): Added cache of resolved color.
(CSSGradientValue):
(CSSLinearGradientValue):
(CSSRadialGradientValue):

  • css/CSSImageGeneratorValue.h:

(WebCore):

  • css/CSSValue.h:

(WebCore::CSSValue::isGradientValue):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::collectMatchingRulesForList):

  • css/StyleResolver.h:

(StyleResolver):

  • rendering/style/StyleGeneratedImage.cpp:

(WebCore::StyleGeneratedImage::image): Revert change from r96449. This
is no longer necessary as the gradient colors are now resolved at a
time when the style is set on StyleResolver.

LayoutTests:

  • fast/css/crash-on-gradient-with-derived-color-expected.txt: Added.
  • fast/css/crash-on-gradient-with-derived-color.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/css/CSSGradientValue.h

    r121289 r123426  
    4141
    4242struct CSSGradientColorStop {
     43    CSSGradientColorStop() : m_colorIsDerivedFromElement(false) { };
    4344    RefPtr<CSSPrimitiveValue> m_position; // percentage or length
    4445    RefPtr<CSSPrimitiveValue> m_color;
     46    Color m_resolvedColor;
     47    bool m_colorIsDerivedFromElement;
    4548};
    4649
     
    7275    bool isPending() const { return false; }
    7376    void loadSubimages(CachedResourceLoader*) { }
     77    PassRefPtr<CSSGradientValue> gradientWithStylesResolved(StyleResolver*);
    7478
    7579protected:
     
    8286    }
    8387
     88    CSSGradientValue(const CSSGradientValue& other, ClassType classType, bool deprecatedType = false)
     89        : CSSImageGeneratorValue(classType)
     90        , m_firstX(other.m_firstX)
     91        , m_firstY(other.m_firstY)
     92        , m_secondX(other.m_secondX)
     93        , m_secondY(other.m_secondY)
     94        , m_stops(other.m_stops)
     95        , m_stopsSorted(other.m_stopsSorted)
     96        , m_deprecatedType(deprecatedType)
     97        , m_repeating(other.isRepeating() ? Repeating : NonRepeating)
     98    {
     99    }
     100
    84101    void addStops(Gradient*, RenderObject*, RenderStyle* rootStyle, float maxLengthForRepeat = 0);
    85102
     
    118135    PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
    119136
     137    PassRefPtr<CSSLinearGradientValue> clone() const
     138    {
     139        return adoptRef(new CSSLinearGradientValue(*this));
     140    }
     141
    120142private:
    121143    CSSLinearGradientValue(CSSGradientRepeat repeat, bool deprecatedType = false)
     
    124146    }
    125147
     148    CSSLinearGradientValue(const CSSLinearGradientValue& other)
     149        : CSSGradientValue(other, LinearGradientClass, other.deprecatedType())
     150        , m_angle(other.m_angle)
     151    {
     152    }
     153
    126154    RefPtr<CSSPrimitiveValue> m_angle; // may be null.
    127155};
     
    134162    }
    135163
     164    PassRefPtr<CSSRadialGradientValue> clone() const
     165    {
     166        return adoptRef(new CSSRadialGradientValue(*this));
     167    }
     168
    136169    String customCssText() const;
    137170
     
    154187    }
    155188
     189    CSSRadialGradientValue(const CSSRadialGradientValue& other)
     190        : CSSGradientValue(other, RadialGradientClass, other.deprecatedType())
     191        , m_firstRadius(other.m_firstRadius)
     192        , m_secondRadius(other.m_secondRadius)
     193        , m_shape(other.m_shape)
     194        , m_sizingBehavior(other.m_sizingBehavior)
     195        , m_endHorizontalSize(other.m_endHorizontalSize)
     196        , m_endVerticalSize(other.m_endVerticalSize)
     197    {
     198    }
     199
     200
    156201    // Resolve points/radii to front end values.
    157202    float resolveRadius(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, float* widthOrHeight = 0);
Note: See TracChangeset for help on using the changeset viewer.