summaryrefslogtreecommitdiffstats
path: root/WebCore/css/CSSParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/css/CSSParser.cpp')
-rw-r--r--WebCore/css/CSSParser.cpp76
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();