diff options
Diffstat (limited to 'WebCore/css/CSSParser.cpp')
-rw-r--r-- | WebCore/css/CSSParser.cpp | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp index 0da1b85..19d82ee 100644 --- a/WebCore/css/CSSParser.cpp +++ b/WebCore/css/CSSParser.cpp @@ -146,6 +146,9 @@ CSSParser::CSSParser(bool strictParsing) , m_defaultNamespace(starAtom) , m_data(0) , yy_start(1) + , m_allowImportRules(true) + , m_allowVariablesRules(true) + , m_allowNamespaceDeclarations(true) , m_floatingMediaQuery(0) , m_floatingMediaQueryExp(0) , m_floatingMediaQueryExpList(0) @@ -242,6 +245,7 @@ PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& str android::TimeCounter::start(android::TimeCounter::CSSParseTimeCounter); #endif m_styleSheet = sheet; + m_allowNamespaceDeclarations = false; setupParser("@-webkit-rule{", string, "} "); cssyyparse(this); #ifdef ANDROID_INSTRUMENT @@ -1297,6 +1301,9 @@ bool CSSParser::parseValue(int propId, bool important) case CSSPropertyWebkitBoxSizing: valid_primitive = id == CSSValueBorderBox || id == CSSValueContentBox; break; + case CSSPropertyWebkitColorCorrection: + valid_primitive = id == CSSValueSrgb || id == CSSValueDefault; + break; case CSSPropertyWebkitMarquee: { const int properties[5] = { CSSPropertyWebkitMarqueeDirection, CSSPropertyWebkitMarqueeIncrement, CSSPropertyWebkitMarqueeRepetition, @@ -1541,7 +1548,9 @@ bool CSSParser::parseValue(int propId, bool important) // Apple specific properties. These will never be standardized and are purely to // support custom WebKit-based Apple applications. case CSSPropertyWebkitLineClamp: - valid_primitive = (!id && validUnit(value, FPercent, false)); + // When specifying number of lines, don't allow 0 as a valid value + // When specifying either type of unit, require non-negative integers + valid_primitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, false)); break; case CSSPropertyWebkitTextSizeAdjust: if (id == CSSValueAuto || id == CSSValueNone) @@ -3388,6 +3397,12 @@ bool CSSParser::parseFontWeight(bool important) return false; } +static bool isValidFormatFunction(CSSParserValue* val) +{ + CSSParserValueList* args = val->function->args; + return equalIgnoringCase(val->function->name, "format(") && (args->current()->unit == CSSPrimitiveValue::CSS_STRING || args->current()->unit == CSSPrimitiveValue::CSS_IDENT); +} + bool CSSParser::parseFontFaceSrc() { RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated()); @@ -3415,7 +3430,7 @@ bool CSSParser::parseFontFaceSrc() CSSParserValue* a = args->current(); uriValue.clear(); parsedValue = CSSFontFaceSrcValue::createLocal(a->string); - } else if (equalIgnoringCase(val->function->name, "format(") && allowFormat && uriValue) { + } else if (allowFormat && uriValue && isValidFormatFunction(val)) { expectComma = true; allowFormat = false; uriValue->setFormat(args->current()->string); @@ -4673,11 +4688,13 @@ static inline int yyerror(const char*) { return 1; } int CSSParser::lex(void* yylvalWithoutType) { YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType); - int token = lex(); int length; + + lex(); + UChar* t = text(&length); - switch (token) { + switch (token()) { case WHITESPACE: case SGML_CD: case INCLUDES: @@ -4743,7 +4760,7 @@ int CSSParser::lex(void* yylvalWithoutType) break; } - return token; + return token(); } static inline bool isCSSWhitespace(UChar c) @@ -4751,6 +4768,28 @@ static inline bool isCSSWhitespace(UChar c) return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f'; } +void CSSParser::recheckAtKeyword(const UChar* str, int len) +{ + String ruleName(str, len); + if (equalIgnoringCase(ruleName, "@import")) + yyTok = IMPORT_SYM; + else if (equalIgnoringCase(ruleName, "@page")) + yyTok = PAGE_SYM; + else if (equalIgnoringCase(ruleName, "@media")) + yyTok = MEDIA_SYM; + else if (equalIgnoringCase(ruleName, "@font-face")) + yyTok = FONT_FACE_SYM; + else if (equalIgnoringCase(ruleName, "@charset")) + yyTok = CHARSET_SYM; + else if (equalIgnoringCase(ruleName, "@namespace")) + yyTok = NAMESPACE_SYM; + else if (equalIgnoringCase(ruleName, "@-webkit-keyframes")) + yyTok = WEBKIT_KEYFRAMES_SYM; + else if (equalIgnoringCase(ruleName, "@-webkit-mediaquery")) + yyTok = WEBKIT_MEDIAQUERY_SYM; + // FIXME: Add CSS Variables if we ever decide to turn it back on. +} + UChar* CSSParser::text(int *length) { UChar* start = yytext; @@ -4804,6 +4843,8 @@ UChar* CSSParser::text(int *length) UChar* out = start; UChar* escape = 0; + bool sawEscape = false; + for (int i = 0; i < l; i++) { UChar* current = start + i; if (escape == current - 1) { @@ -4848,6 +4889,7 @@ UChar* CSSParser::text(int *length) } if (!escape && *current == '\\') { escape = current; + sawEscape = true; continue; } *out++ = *current; @@ -4868,6 +4910,12 @@ UChar* CSSParser::text(int *length) } *length = out - start; + + // If we have an unrecognized @-keyword, and if we handled any escapes at all, then + // we should attempt to adjust yyTok to the correct type. + if (yyTok == ATKEYWORD && sawEscape) + recheckAtKeyword(start, *length); + return start; } @@ -4998,7 +5046,7 @@ CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset) CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaList* media) { - if (!media || !m_styleSheet) + if (!media || !m_styleSheet || !m_allowImportRules) return 0; RefPtr<CSSImportRule> rule = CSSImportRule::create(m_styleSheet, url, media); CSSImportRule* result = rule.get(); @@ -5010,6 +5058,7 @@ CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules) { if (!media || !rules || !m_styleSheet) return 0; + m_allowImportRules = m_allowNamespaceDeclarations = m_allowVariablesRules = false; RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, rules); CSSMediaRule* result = rule.get(); m_parsedStyleObjects.append(rule.release()); @@ -5027,6 +5076,7 @@ CSSRuleList* CSSParser::createRuleList() WebKitCSSKeyframesRule* CSSParser::createKeyframesRule() { + m_allowImportRules = m_allowNamespaceDeclarations = m_allowVariablesRules = false; RefPtr<WebKitCSSKeyframesRule> rule = WebKitCSSKeyframesRule::create(m_styleSheet); WebKitCSSKeyframesRule* rulePtr = rule.get(); m_parsedStyleObjects.append(rule.release()); @@ -5035,6 +5085,7 @@ WebKitCSSKeyframesRule* CSSParser::createKeyframesRule() CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors) { + m_allowImportRules = m_allowNamespaceDeclarations = m_allowVariablesRules = false; CSSStyleRule* result = 0; if (selectors) { RefPtr<CSSStyleRule> rule = CSSStyleRule::create(m_styleSheet); @@ -5051,6 +5102,7 @@ CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors) CSSRule* CSSParser::createFontFaceRule() { + m_allowImportRules = m_allowNamespaceDeclarations = m_allowVariablesRules = false; RefPtr<CSSFontFaceRule> rule = CSSFontFaceRule::create(m_styleSheet); for (unsigned i = 0; i < m_numParsedProperties; ++i) { CSSProperty* property = m_parsedProperties[i]; @@ -5068,6 +5120,15 @@ CSSRule* CSSParser::createFontFaceRule() return result; } +void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri) +{ + if (!m_styleSheet || !m_allowNamespaceDeclarations) + return; + m_allowImportRules = false; + m_allowVariablesRules = false; + m_styleSheet->addNamespace(this, prefix, uri); +} + #if !ENABLE(CSS_VARIABLES) CSSRule* CSSParser::createVariablesRule(MediaList*, bool) @@ -5089,6 +5150,9 @@ bool CSSParser::addVariableDeclarationBlock(const CSSParserString&) CSSRule* CSSParser::createVariablesRule(MediaList* mediaList, bool variablesKeyword) { + if (!m_allowVariablesRules) + return 0; + m_allowImportRules = false; RefPtr<CSSVariablesRule> rule = CSSVariablesRule::create(m_styleSheet, mediaList, variablesKeyword); rule->setDeclaration(CSSVariablesDeclaration::create(rule.get(), m_variableNames, m_variableValues)); clearVariables(); |