⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 179476 in webkit


Ignore:
Timestamp:
Feb 2, 2015, 10:12:32 AM (12 years ago)
Author:
Darin Adler
Message:

REGRESSION (r170576): Storage leaks in parsing of CSS image sizes
https://bugs.webkit.org/show_bug.cgi?id=141026

Reviewed by Anders Carlsson.

  • css/CSSGrammar.y.in: Fixed all the shift/reduce conflicts caused

by the ENABLE_PICTURE_SIZES code by removing all the redundant
maybe_space which caused them. Rearranged the productions for
ENABLE_PICTURE_SIZES to tighten up the code quite a bit. Changed
the code to build up the source size vector as a Vector instead of
a special class, and use the SourceSize struct from inside the
CSSParser class.'

  • css/CSSParser.cpp:

(WebCore::CSSParser::setupParser): Changed this to take a StringView.
In the future we can change all the parsing functions to take StringView,
since they don't work with the String in place.
(WebCore::CSSParser::parseSizesAttribute): Changed to return a vector
of SourceSize instead of a SourceSizeList. This is better because it's
a real CSS data structure that does not contain a CSSParserValue.
(WebCore::CSSParser::sourceSize): Added. Helper that creates a
SourceSize, mapping parser data structures into real CSS ones.

  • css/CSSParser.h: Updated for changes above.
  • css/MediaQuery.cpp:

(WebCore::MediaQuery::MediaQuery): Use std::make_unique and the copy
constructor directly instead of using a MediaQuery::copy function.

  • css/MediaQueryExp.cpp: Streamlined the class a little bit.
  • css/MediaQueryExp.h: Removed unneeded includes. Moved functions out

of the class body so the class is easier to read. Removed the unneeded
copy function.

  • css/SourceSizeList.cpp:

(WebCore::SourceSize::match): Changed to use WTF::move instead
of releasing and then re-creating the unique_ptr.
(WebCore::computeLength): Added a comment to explain this function
is using an incorrect strategy. Also added some type checking code
to handle cases where a null or non-primitive CSS value might be
returned. Probably dead code, but we don't want to risk a bad cast.
Worthe cleaning up when we fix the strategy.
(WebCore::SourceSizeList::getEffectiveSize): Updated since the
vector now contains actual SourceSize objects rather than pointers
to SourceSize objects on the heap.

  • css/SourceSizeList.h: Changed the CSSParserValue argument to be

an rvalue reference to make it clearer that we take ownership of it
when it's moved in. Added a move constructor and a destructor. Added
comments explaining that it's not correct design to use a
CSSParserValue here, outside the parser. Changed SourceSizeList's
append function to move a SourceSize in rather than a unique_ptr.
Made getEffectiveSize private. Moved the various inline functions to
the bottom of the file to make the class definitions easier to read.

  • css/SourceSizeList.cpp: Made almost everything about this private

to this source file instead of public in the header.
(WebCore::match): Made this a free function instead of a member function
and made it take the media query expression as an argument.
(WebCore::computeLength): Changed the argument type to CSSValue*,
rather than using CSSParserValue here outside the parser.
(WebCore::parseSizesAttribute): Streamlined and simplified this.
Now that the parser builds the list in the correct order, there was
no need to iterate backwards any more so we could use a modern for
loop.

  • css/SourceSizeList.h: Removed almost everything in this header.
  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::parseAttribute): Call the
parseSizesAttribute function as free function since it's no longer
a member of a SourceSizeList class.

  • html/parser/HTMLPreloadScanner.cpp:

(WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
Ditto.

Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r179473 r179476  
     12015-02-02  Darin Adler  <darin@apple.com>
     2
     3        REGRESSION (r170576): Storage leaks in parsing of CSS image sizes
     4        https://bugs.webkit.org/show_bug.cgi?id=141026
     5
     6        Reviewed by Anders Carlsson.
     7
     8        * css/CSSGrammar.y.in: Fixed all the shift/reduce conflicts caused
     9        by the ENABLE_PICTURE_SIZES code by removing all the redundant
     10        maybe_space which caused them. Rearranged the productions for
     11        ENABLE_PICTURE_SIZES to tighten up the code quite a bit. Changed
     12        the code to build up the source size vector as a Vector instead of
     13        a special class, and use the SourceSize struct from inside the
     14        CSSParser class.'
     15
     16        * css/CSSParser.cpp:
     17        (WebCore::CSSParser::setupParser): Changed this to take a StringView.
     18        In the future we can change all the parsing functions to take StringView,
     19        since they don't work with the String in place.
     20        (WebCore::CSSParser::parseSizesAttribute): Changed to return a vector
     21        of SourceSize instead of a SourceSizeList. This is better because it's
     22        a real CSS data structure that does not contain a CSSParserValue.
     23        (WebCore::CSSParser::sourceSize): Added. Helper that creates a
     24        SourceSize, mapping parser data structures into real CSS ones.
     25
     26        * css/CSSParser.h: Updated for changes above.
     27
     28        * css/MediaQuery.cpp:
     29        (WebCore::MediaQuery::MediaQuery): Use std::make_unique and the copy
     30        constructor directly instead of using a MediaQuery::copy function.
     31
     32        * css/MediaQueryExp.cpp: Streamlined the class a little bit.
     33        * css/MediaQueryExp.h: Removed unneeded includes. Moved functions out
     34        of the class body so the class is easier to read. Removed the unneeded
     35        copy function.
     36
     37        * css/SourceSizeList.cpp:
     38        (WebCore::SourceSize::match): Changed to use WTF::move instead
     39        of releasing and then re-creating the unique_ptr.
     40        (WebCore::computeLength): Added a comment to explain this function
     41        is using an incorrect strategy. Also added some type checking code
     42        to handle cases where a null or non-primitive CSS value might be
     43        returned. Probably dead code, but we don't want to risk a bad cast.
     44        Worthe cleaning up when we fix the strategy.
     45        (WebCore::SourceSizeList::getEffectiveSize): Updated since the
     46        vector now contains actual SourceSize objects rather than pointers
     47        to SourceSize objects on the heap.
     48
     49        * css/SourceSizeList.h: Changed the CSSParserValue argument to be
     50        an rvalue reference to make it clearer that we take ownership of it
     51        when it's moved in. Added a move constructor and a destructor. Added
     52        comments explaining that it's not correct design to use a
     53        CSSParserValue here, outside the parser. Changed SourceSizeList's
     54        append function to move a SourceSize in rather than a unique_ptr.
     55        Made getEffectiveSize private. Moved the various inline functions to
     56        the bottom of the file to make the class definitions easier to read.
     57
     58
     59        * css/SourceSizeList.cpp: Made almost everything about this private
     60        to this source file instead of public in the header.
     61        (WebCore::match): Made this a free function instead of a member function
     62        and made it take the media query expression as an argument.
     63        (WebCore::computeLength): Changed the argument type to CSSValue*,
     64        rather than using CSSParserValue here outside the parser.
     65        (WebCore::parseSizesAttribute): Streamlined and simplified this.
     66        Now that the parser builds the list in the correct order, there was
     67        no need to iterate backwards any more so we could use a modern for
     68        loop.
     69
     70        * css/SourceSizeList.h: Removed almost everything in this header.
     71
     72        * html/HTMLImageElement.cpp:
     73        (WebCore::HTMLImageElement::parseAttribute): Call the
     74        parseSizesAttribute function as free function since it's no longer
     75        a member of a SourceSizeList class.
     76
     77        * html/parser/HTMLPreloadScanner.cpp:
     78        (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
     79        Ditto.
     80
    1812015-02-02  Darin Adler  <darin@apple.com>
    282
  • trunk/Source/WebCore/css/CSSGrammar.y.in

    r179362 r179476  
    11/*
    22 *  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
    3  *  Copyright (C) 2004-2014 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004-2015 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    55 *  Copyright (C) 2008 Eric Seidel <eric@webkit.org>
     
    105105
    106106#if ENABLE_CSS_GRID_LAYOUT
    107 #if ENABLE_PICTURE_SIZES
    108 %expect 36
    109 #else
    110107%expect 32
    111 #endif
    112 #else
    113 #if ENABLE_PICTURE_SIZES
    114 %expect 35
    115108#else
    116109%expect 31
    117 #endif
    118110#endif
    119111
     
    266258
    267259%union { MediaQueryExp* mediaQueryExp; }
    268 %type <mediaQueryExp> media_query_exp
    269 %destructor { delete $$; } media_query_exp
     260%type <mediaQueryExp> media_query_exp base_media_query_exp
     261%destructor { delete $$; } media_query_exp base_media_query_exp
    270262
    271263#if ENABLE_PICTURE_SIZES
    272 %union { MediaQueryExp* mediaCondition; }
    273 %type <mediaQueryExp> media_condition
    274 %destructor { delete $$; } media_condition
    275 
    276 %union { SourceSize* sourceSize; }
    277 %type <sourceSize> source_size
    278 %destructor { delete $$; } source_size
    279 
    280 %union { SourceSizeList* sourceSizeList; }
     264
     265%union { Vector<CSSParser::SourceSize>* sourceSizeList; }
    281266%type <sourceSizeList> source_size_list
    282267%destructor { delete $$; } source_size_list
    283268
     269%type <mediaQueryExp> maybe_source_media_query_exp
     270%destructor { delete $$; } maybe_source_media_query_exp
     271
    284272%type <value> source_size_length
     273%destructor { destroy($$); } source_size_length
     274
    285275#endif
    286276
     
    299289%destructor { delete $$; } keyframes_rule
    300290
    301 // These two parser values never need to be destroyed because they are never functions or value lists.
    302 %type <value> key unary_term
     291// These parser values never need to be destroyed because they are never functions or value lists.
     292%type <value> calc_func_term key unary_term
    303293
    304294// These parser values need to be destroyed because they might be functions.
    305 %type <value> calc_func_term calc_function function min_or_max_function term
    306 %destructor { destroy($$); } calc_func_term calc_function function min_or_max_function term
     295%type <value> calc_function function min_or_max_function term
     296%destructor { destroy($$); } calc_function function min_or_max_function term
    307297
    308298%union { CSSPropertyID id; }
     
    335325
    336326#if ENABLE_CSS_SELECTORS_LEVEL4
     327
    337328%type <string> lang_range
     329
    338330%union { Vector<CSSParserString>* stringList; }
    339331%type <stringList> comma_separated_lang_ranges
    340332%destructor { delete $$; } comma_separated_lang_ranges
     333
    341334#endif
    342335
     
    349342
    350343#if ENABLE_CSS_GRID_LAYOUT
     344
    351345%type <valueList> ident_list
    352346%destructor { delete $$; } ident_list
     
    354348%type <value> track_names_list
    355349%destructor { destroy($$); } track_names_list
     350
    356351#endif
    357352
     
    578573
    579574#if ENABLE_PICTURE_SIZES
    580 media_condition:
    581     maybe_space '(' maybe_space IDENT maybe_space maybe_media_value ')' maybe_space {
    582         std::unique_ptr<CSSParserValueList> mediaValue($6);
    583         $4.lower();
    584         $$ = new MediaQueryExp($4, mediaValue.get());
    585     }
    586     ;
    587575
    588576webkit_source_size_list:
    589     WEBKIT_SIZESATTR_SYM WHITESPACE source_size_list '}' { parser->m_sourceSizeList = std::unique_ptr<SourceSizeList>($3); };
     577    WEBKIT_SIZESATTR_SYM WHITESPACE source_size_list maybe_space '}' {
     578        parser->m_sourceSizeList = std::unique_ptr<Vector<CSSParser::SourceSize>>($3);
     579    }
     580    ;
    590581
    591582source_size_list:
    592     maybe_space source_size maybe_space {
    593         $$ = new SourceSizeList();
    594         $$->append(std::unique_ptr<SourceSize>($2));
    595     }
    596     | maybe_space source_size maybe_space ',' maybe_space source_size_list maybe_space {
    597         $$ = $6;
    598         $$->append(std::unique_ptr<SourceSize>($2));
    599     };
    600 
    601 source_size_length:
    602     unary_term {
     583    maybe_source_media_query_exp source_size_length {
     584        $$ = new Vector<CSSParser::SourceSize>;
     585        $$->append(parser->sourceSize(std::unique_ptr<MediaQueryExp>($1), $2));
     586    }
     587    | source_size_list maybe_space ',' maybe_space maybe_source_media_query_exp source_size_length {
    603588        $$ = $1;
    604     }
    605     | calc_function {
    606         $$ = $1;
    607     };
    608 
    609 source_size:
    610     media_condition source_size_length {
    611         $$ = new SourceSize(std::unique_ptr<MediaQueryExp>($1), $2);
    612     }
    613     | source_size_length {
    614         $$ = new SourceSize(std::make_unique<MediaQueryExp>(emptyString(), nullptr), $1);
    615     };
    616 #endif
     589        $$->append(parser->sourceSize(std::unique_ptr<MediaQueryExp>($5), $6));
     590    }
     591    ;
     592
     593maybe_source_media_query_exp:
     594    /* empty */ {
     595        $$ = new MediaQueryExp;
     596    }
     597    | base_media_query_exp maybe_space;
     598
     599source_size_length: unary_term | calc_function;
     600
     601#endif
     602
     603base_media_query_exp: '(' maybe_space IDENT maybe_space maybe_media_value ')' {
     604        std::unique_ptr<CSSParserValueList> mediaValue($5);
     605        $3.lower();
     606        $$ = new MediaQueryExp($3, mediaValue.get());
     607    }
     608    ;
    617609
    618610media_query_exp:
    619     maybe_media_restrictor maybe_space '(' maybe_space IDENT maybe_space maybe_media_value ')' maybe_space {
    620         // If restrictor is specified, media query expression is invalid.
    621         // Create empty media query expression and continue parsing media query.
    622         std::unique_ptr<CSSParserValueList> mediaValue($7);
    623         if ($1 != MediaQuery::None)
    624             $$ = new MediaQueryExp(emptyString(), nullptr);
    625         else {
    626             $5.lower();
    627             $$ = new MediaQueryExp($5, mediaValue.get());
    628         }
     611    maybe_media_restrictor maybe_space base_media_query_exp maybe_space {
     612        if ($1 != MediaQuery::None) {
     613            // If restrictor is specified, media query expression is invalid.
     614            // Create empty media query expression and continue parsing media query.
     615            delete $3;
     616            $$ = new MediaQueryExp;
     617        } else
     618            $$ = $3;
    629619    }
    630620    ;
     
    19161906
    19171907%%
    1918 
  • trunk/Source/WebCore/css/CSSParser.cpp

    r179267 r179476  
    378378}
    379379
    380 void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
     380void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringView string, const char* suffix, unsigned suffixLength)
    381381{
    382382    m_parsedTextPrefixLength = prefixLength;
     
    14811481
    14821482#if ENABLE(PICTURE_SIZES)
    1483 std::unique_ptr<SourceSizeList> CSSParser::parseSizesAttribute(const String& string)
    1484 {
     1483
     1484Vector<CSSParser::SourceSize> CSSParser::parseSizesAttribute(StringView string)
     1485{
     1486    Vector<SourceSize> result;
     1487
    14851488    if (string.isEmpty())
    1486         return nullptr;
    1487 
    1488     ASSERT(!m_sourceSizeList.get());
     1489        return result;
     1490
     1491    ASSERT(!m_sourceSizeList);
    14891492
    14901493    setupParser("@-webkit-sizesattr ", string, "}");
    14911494    cssyyparse(this);
    14921495
    1493     return WTF::move(m_sourceSizeList);
    1494 }
     1496    if (!m_sourceSizeList)
     1497        return result;
     1498
     1499    result = WTF::move(*m_sourceSizeList);
     1500    m_sourceSizeList = nullptr;
     1501    return result;
     1502}
     1503
     1504CSSParser::SourceSize CSSParser::sourceSize(std::unique_ptr<MediaQueryExp>&& expression, CSSParserValue& parserValue)
     1505{
     1506    RefPtr<CSSValue> value;
     1507    if (isCalculation(parserValue)) {
     1508        auto* args = parserValue.function->args.get();
     1509        if (args && args->size())
     1510            value = CSSCalcValue::create(parserValue.function->name, *args, CalculationRangeNonNegative);
     1511    }
     1512    if (!value)
     1513        value = parserValue.createCSSValue();
     1514    // FIXME: Using a named local for the result here to work around an MSVC bug.
     1515    // With the other compilers, this works without explicitly stating the type name SourceSize or using a local.
     1516    SourceSize result { WTF::move(expression), value };
     1517    return result;
     1518}
     1519
    14951520#endif
    14961521
  • trunk/Source/WebCore/css/CSSParser.h

    r179197 r179476  
    11/*
    22 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
    3  * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
     3 * Copyright (C) 2004-2010, 2015 Apple Inc. All rights reserved.
    44 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
    55 * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. All rights reserved.
     
    118118    static Ref<ImmutableStyleProperties> parseInlineStyleDeclaration(const String&, Element*);
    119119    std::unique_ptr<MediaQuery> parseMediaQuery(const String&);
    120 #if ENABLE(PICTURE_SIZES)
    121     std::unique_ptr<SourceSizeList> parseSizesAttribute(const String&);
    122 #endif
    123120
    124121    void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
     
    138135
    139136    PassRefPtr<CSSValue> parseBackgroundColor();
     137
     138#if ENABLE(PICTURE_SIZES)
     139    struct SourceSize {
     140        std::unique_ptr<MediaQueryExp> expression;
     141        RefPtr<CSSValue> length;
     142    };
     143    Vector<SourceSize> parseSizesAttribute(StringView);
     144    SourceSize sourceSize(std::unique_ptr<MediaQueryExp>&&, CSSParserValue&);
     145#endif
    140146
    141147    // FIXME: Maybe these two methods could be combined into one.
     
    367373    std::unique_ptr<MediaQuery> m_mediaQuery;
    368374#if ENABLE(PICTURE_SIZES)
    369     std::unique_ptr<SourceSizeList> m_sourceSizeList;
     375    std::unique_ptr<Vector<SourceSize>> m_sourceSizeList;
    370376#endif
    371377    std::unique_ptr<CSSParserValueList> m_valueList;
     
    515521
    516522    template<unsigned prefixLength, unsigned suffixLength>
    517     inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
     523    void setupParser(const char (&prefix)[prefixLength], StringView string, const char (&suffix)[suffixLength])
    518524    {
    519525        setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
    520526    }
    521     void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
     527    void setupParser(const char* prefix, unsigned prefixLength, StringView, const char* suffix, unsigned suffixLength);
    522528    bool inShorthand() const { return m_inParseShorthand; }
    523529
  • trunk/Source/WebCore/css/MediaQuery.cpp

    r173212 r179476  
    111111{
    112112    for (unsigned i = 0; i < m_expressions->size(); ++i)
    113         (*m_expressions)[i] = o.m_expressions->at(i)->copy();
     113        (*m_expressions)[i] = std::make_unique<MediaQueryExp>(*o.m_expressions->at(i));
    114114}
    115115
  • trunk/Source/WebCore/css/MediaQueryExp.cpp

    r179055 r179476  
    11/*
    2  * CSS Media Query
    3  *
    42 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
    53 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    6  * Copyright (C) 2013 Apple Inc. All rights reserved.
     4 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    75 *
    86 * Redistribution and use in source and binary forms, with or without
     
    163161MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
    164162    : m_mediaFeature(mediaFeature)
    165     , m_value(0)
    166     , m_isValid(false)
    167163{
    168164    // Initialize media query expression that must have 1 or more values.
     
    229225}
    230226
    231 MediaQueryExp::~MediaQueryExp()
    232 {
    233 }
    234 
    235227String MediaQueryExp::serialize() const
    236228{
     
    247239    result.append(')');
    248240
    249     const_cast<MediaQueryExp*>(this)->m_serializationCache = result.toString();
     241    m_serializationCache = result.toString();
    250242    return m_serializationCache;
    251243}
  • trunk/Source/WebCore/css/MediaQueryExp.h

    r165676 r179476  
    11/*
    2  * CSS Media Query
    3  *
    42 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
    53 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 * Copyright (C) 2015 Apple Inc. All rights reserved.
    65 *
    76 * Redistribution and use in source and binary forms, with or without
     
    3332#include "MediaFeatureNames.h"
    3433#include <memory>
    35 #include <wtf/RefPtr.h>
    3634#include <wtf/text/AtomicString.h>
    3735
    3836namespace WebCore {
     37
    3938class CSSParserValueList;
    4039
     
    4241    WTF_MAKE_FAST_ALLOCATED;
    4342public:
    44     MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values);
    45     ~MediaQueryExp();
     43    explicit MediaQueryExp(const AtomicString& mediaFeature = emptyAtom, CSSParserValueList* values = nullptr);
    4644
    47     AtomicString mediaFeature() const { return m_mediaFeature; }
     45    const AtomicString& mediaFeature() const;
     46    CSSValue* value() const;
    4847
    49     CSSValue* value() const { return m_value.get(); }
    50 
    51     bool operator==(const MediaQueryExp& other) const
    52     {
    53         return (other.m_mediaFeature == m_mediaFeature)
    54             && ((!other.m_value && !m_value)
    55                 || (other.m_value && m_value && other.m_value->equals(*m_value)));
    56     }
    57 
    58     bool isValid() const { return m_isValid; }
    59 
    60     bool isViewportDependent() const { return m_mediaFeature == MediaFeatureNames::widthMediaFeature
    61                                             || m_mediaFeature == MediaFeatureNames::heightMediaFeature
    62                                             || m_mediaFeature == MediaFeatureNames::min_widthMediaFeature
    63                                             || m_mediaFeature == MediaFeatureNames::min_heightMediaFeature
    64                                             || m_mediaFeature == MediaFeatureNames::max_widthMediaFeature
    65                                             || m_mediaFeature == MediaFeatureNames::max_heightMediaFeature
    66                                             || m_mediaFeature == MediaFeatureNames::orientationMediaFeature
    67                                             || m_mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature
    68                                             || m_mediaFeature == MediaFeatureNames::min_aspect_ratioMediaFeature
    69                                             || m_mediaFeature == MediaFeatureNames::max_aspect_ratioMediaFeature;  }
     48    bool isValid() const;
     49    bool isViewportDependent() const;
    7050
    7151    String serialize() const;
    7252
    73     std::unique_ptr<MediaQueryExp> copy() const { return std::make_unique<MediaQueryExp>(*this); }
     53    bool operator==(const MediaQueryExp&) const;
    7454
    7555private:
    7656    AtomicString m_mediaFeature;
    7757    RefPtr<CSSValue> m_value;
    78     bool m_isValid;
    79     String m_serializationCache;
     58    bool m_isValid { false };
     59    mutable String m_serializationCache;
    8060};
     61
     62inline const AtomicString& MediaQueryExp::mediaFeature() const
     63{
     64    return m_mediaFeature;
     65}
     66
     67inline CSSValue* MediaQueryExp::value() const
     68{
     69    return m_value.get();
     70}
     71
     72inline bool MediaQueryExp::operator==(const MediaQueryExp& other) const
     73{
     74    return (other.m_mediaFeature == m_mediaFeature)
     75        && ((!other.m_value && !m_value)
     76            || (other.m_value && m_value && other.m_value->equals(*m_value)));
     77}
     78
     79inline bool MediaQueryExp::isValid() const
     80{
     81    return m_isValid;
     82}
     83
     84inline bool MediaQueryExp::isViewportDependent() const
     85{
     86    return m_mediaFeature == MediaFeatureNames::widthMediaFeature
     87        || m_mediaFeature == MediaFeatureNames::heightMediaFeature
     88        || m_mediaFeature == MediaFeatureNames::min_widthMediaFeature
     89        || m_mediaFeature == MediaFeatureNames::min_heightMediaFeature
     90        || m_mediaFeature == MediaFeatureNames::max_widthMediaFeature
     91        || m_mediaFeature == MediaFeatureNames::max_heightMediaFeature
     92        || m_mediaFeature == MediaFeatureNames::orientationMediaFeature
     93        || m_mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature
     94        || m_mediaFeature == MediaFeatureNames::min_aspect_ratioMediaFeature
     95        || m_mediaFeature == MediaFeatureNames::max_aspect_ratioMediaFeature;
     96}
    8197
    8298} // namespace
  • trunk/Source/WebCore/css/SourceSizeList.cpp

    r176719 r179476  
    11/*
    22 * Copyright (C) 2014 Yoav Weiss <yoav@yoav.ws>
     3 * Copyright (C) 2015 Apple Inc. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
     
    2324#include "CSSParser.h"
    2425#include "CSSToLengthConversionData.h"
    25 #include "Document.h"
    2626#include "MediaList.h"
    2727#include "MediaQuery.h"
    2828#include "MediaQueryEvaluator.h"
    29 #include "RenderObject.h"
     29#include "MediaQueryExp.h"
    3030#include "RenderStyle.h"
    3131#include "RenderView.h"
     
    3333namespace WebCore {
    3434
    35 #if ENABLE(PICTURE_SIZES)
    36 bool SourceSize::match(RenderStyle& style, Frame* frame)
     35#if !ENABLE(PICTURE_SIZES)
     36
     37unsigned parseSizesAttribute(StringView, RenderView*, Frame*)
    3738{
    38     if (m_mediaExp->mediaFeature().isEmpty())
     39    return 0;
     40}
     41
     42#else
     43
     44static bool match(std::unique_ptr<MediaQueryExp>&& expression, RenderStyle& style, Frame* frame)
     45{
     46    if (expression->mediaFeature().isEmpty())
    3947        return true;
     48
    4049    auto expList = std::make_unique<Vector<std::unique_ptr<MediaQueryExp>>>();
    41     expList->append(m_mediaExp.release());
     50    expList->append(WTF::move(expression));
    4251
    4352    RefPtr<MediaQuerySet> mediaQuerySet = MediaQuerySet::create();
     
    4857}
    4958
    50 static unsigned computeLength(CSSParserValue& value, RenderStyle& style, RenderView* view)
     59static unsigned computeLength(CSSValue* value, RenderStyle& style, RenderView* view)
    5160{
    5261    CSSToLengthConversionData conversionData(&style, &style, view);
    53     if (CSSParser::isCalculation(value)) {
    54         CSSParserValueList* args = value.function->args.get();
    55         if (args && args->size()) {
    56             RefPtr<CSSCalcValue> calcValue = CSSCalcValue::create(value.function->name, *args, CalculationRangeNonNegative);
    57             Length length(calcValue->createCalculationValue(conversionData));
    58             RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::create(length, &style);
    59             return primitiveValue->computeLength<unsigned>(conversionData);
    60         }
     62    if (is<CSSPrimitiveValue>(value))
     63        return downcast<CSSPrimitiveValue>(*value).computeLength<unsigned>(conversionData);
     64    if (is<CSSCalcValue>(value)) {
     65        Length length(downcast<CSSCalcValue>(*value).createCalculationValue(conversionData));
     66        return CSSPrimitiveValue::create(length, &style)->computeLength<unsigned>(conversionData);
    6167    }
    62     RefPtr<CSSValue> cssValue = value.createCSSValue();
    63     RefPtr<CSSPrimitiveValue> primitiveValue = downcast<CSSPrimitiveValue>(cssValue.get());
    64     return primitiveValue->computeLength<unsigned>(conversionData);
     68    return 0;
    6569}
    6670
    67 static unsigned defaultValue(RenderStyle& style, RenderView* view)
    68 {
    69     const unsigned defaultSizesAttributeValueInVW = 100;
    70 
    71     CSSParserValue value;
    72     value.id = CSSValueInvalid;
    73     value.isInt = true;
    74     value.fValue = defaultSizesAttributeValueInVW;
    75     value.unit = CSSPrimitiveValue::CSS_VW;
    76 
    77     return computeLength(value, style, view);
    78 }
    79 
    80 unsigned SourceSize::length(RenderStyle& style, RenderView* view)
    81 {
    82     return computeLength(m_length, style, view);
    83 }
    84 
    85 unsigned SourceSizeList::parseSizesAttribute(const String& sizesAttribute, RenderView* view, Frame* frame)
     71unsigned parseSizesAttribute(StringView sizesAttribute, RenderView* view, Frame* frame)
    8672{
    8773    if (!view)
    8874        return 0;
    89     CSSParser parser(CSSStrictMode);
    90     std::unique_ptr<SourceSizeList> sourceSizeList = parser.parseSizesAttribute(sizesAttribute);
    91     if (!sourceSizeList)
    92         return defaultValue(view->style(), view);
    93     return sourceSizeList->getEffectiveSize(view->style(), view, frame);
    94 }
    95 
    96 unsigned SourceSizeList::getEffectiveSize(RenderStyle& style, RenderView* view, Frame* frame)
    97 {
    98     for (int i = m_list.size() - 1; i >= 0; --i) {
    99         SourceSize* sourceSize = m_list[i].get();
    100         if (sourceSize->match(style, frame))
    101             return sourceSize->length(style, view);
     75    RenderStyle& style = view->style();
     76    for (auto& sourceSize : CSSParser(CSSStrictMode).parseSizesAttribute(sizesAttribute)) {
     77        if (match(WTF::move(sourceSize.expression), style, frame))
     78            return computeLength(sourceSize.length.get(), style, view);
    10279    }
    103     return defaultValue(style, view);
     80    return computeLength(CSSPrimitiveValue::create(100, CSSPrimitiveValue::CSS_VW).ptr(), style, view);
    10481}
    10582
  • trunk/Source/WebCore/css/SourceSizeList.h

    r170774 r179476  
    11/*
    22 * Copyright (C) 2014 Yoav Weiss <yoav@yoav.ws>
     3 * Copyright (C) 2015 Apple Inc. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
     
    2122#define SourceSizeList_h
    2223
    23 #if ENABLE(PICTURE_SIZES)
    24 
    25 #include "CSSParserValues.h"
    26 #include "MediaQueryExp.h"
    27 #include <memory>
     24#include <wtf/Forward.h>
    2825
    2926namespace WebCore {
    3027
    31 class RenderStyle;
     28class Frame;
    3229class RenderView;
    33 class Frame;
    3430
    35 class SourceSize {
    36 public:
    37     SourceSize(std::unique_ptr<MediaQueryExp> mediaExp, const CSSParserValue& length)
    38         : m_mediaExp(WTF::move(mediaExp))
    39         , m_length(length)
    40     {
    41     }
    42 
    43     bool match(RenderStyle&, Frame*);
    44     unsigned length(RenderStyle&, RenderView*);
    45 
    46 private:
    47     std::unique_ptr<MediaQueryExp> m_mediaExp;
    48     CSSParserValue m_length;
    49 };
    50 
    51 class SourceSizeList {
    52 public:
    53     void append(std::unique_ptr<SourceSize> sourceSize)
    54     {
    55         m_list.append(WTF::move(sourceSize));
    56     }
    57 
    58     static unsigned parseSizesAttribute(const String& sizesAttribute, RenderView*, Frame*);
    59     unsigned getEffectiveSize(RenderStyle&, RenderView*, Frame*);
    60 
    61 private:
    62     Vector<std::unique_ptr<SourceSize>> m_list;
    63 };
     31unsigned parseSizesAttribute(StringView sizesAttribute, RenderView*, Frame*);
    6432
    6533} // namespace WebCore
    6634
    67 #endif // ENABLE(PICTURE_SIZES)
    68 
    6935#endif // SourceSizeList_h
    70 
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r177996 r179476  
    144144            downcast<RenderImage>(*renderer()).updateAltText();
    145145    } else if (name == srcAttr || name == srcsetAttr) {
    146         unsigned sourceSize = 0;
    147 #if ENABLE(PICTURE_SIZES)
    148         sourceSize = SourceSizeList::parseSizesAttribute(fastGetAttribute(sizesAttr), document().renderView(), document().frame());
    149 #endif
     146        unsigned sourceSize = parseSizesAttribute(fastGetAttribute(sizesAttr).string(), document().renderView(), document().frame());
    150147        ImageCandidate candidate = bestFitSourceForImageAttributes(document().deviceScaleFactor(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr), sourceSize);
    151148        setBestFitURLAndDPRFromImageCandidate(candidate);
  • trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp

    r178265 r179476  
    108108        // Resolve between src and srcSet if we have them.
    109109        if (!m_srcSetAttribute.isEmpty()) {
    110             unsigned sourceSize = 0;
    111 #if ENABLE(PICTURE_SIZES)
    112             sourceSize = SourceSizeList::parseSizesAttribute(m_sizesAttribute, document.renderView(), document.frame());
    113 #else
    114             UNUSED_PARAM(document);
    115 #endif
     110            unsigned sourceSize = parseSizesAttribute(m_sizesAttribute, document.renderView(), document.frame());
    116111            ImageCandidate imageCandidate = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute, sourceSize);
    117112            setUrlToLoad(imageCandidate.string.toString(), true);
Note: See TracChangeset for help on using the changeset viewer.