static PassRefPtrWillBeRawPtr<CSSValue> parseSimpleLengthValue(CSSPropertyID propertyId, const String& string, CSSParserMode cssParserMode) { ASSERT(!string.isEmpty()); bool acceptsNegativeNumbers = false; // In @viewport, width and height are shorthands, not simple length values. if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers)) return nullptr; unsigned length = string.length(); double number; CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::CSS_NUMBER; if (string.is8Bit()) { if (!parseSimpleLength(string.characters8(), length, unit, number)) return nullptr; } else { if (!parseSimpleLength(string.characters16(), length, unit, number)) return nullptr; } if (unit == CSSPrimitiveValue::CSS_NUMBER) { bool quirksMode = isQuirksModeBehavior(cssParserMode); if (number && !quirksMode) return nullptr; unit = CSSPrimitiveValue::CSS_PX; } if (number < 0 && !acceptsNegativeNumbers) return nullptr; return cssValuePool().createValue(number, unit); }
void StyleSheetContents::parseAuthorStyleSheet(const CSSStyleSheetResource* cachedStyleSheet, const SecurityOrigin* securityOrigin) { TRACE_EVENT0("webkit", "StyleSheetContents::parseAuthorStyleSheet"); bool quirksMode = isQuirksModeBehavior(m_parserContext.mode()); bool enforceMIMEType = !quirksMode; bool hasValidMIMEType = false; String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType); CSSParserContext context(parserContext(), UseCounter::getFrom(this)); BisonCSSParser p(context); p.parseSheet(this, sheetText, TextPosition::minimumPosition(), 0, true); // If we're loading a stylesheet cross-origin, and the MIME type is not standard, require the CSS // to at least start with a syntactically valid CSS rule. // This prevents an attacker playing games by injecting CSS strings into HTML, XML, JSON, etc. etc. if (!hasValidMIMEType && !hasSyntacticallyValidCSSHeader()) { bool isCrossOriginCSS = !securityOrigin || !securityOrigin->canRequest(baseURL()); if (isCrossOriginCSS) { clearRules(); return; } } }
static PassRefPtrWillBeRawPtr<CSSValue> parseColorValue(CSSPropertyID propertyId, const String& string, CSSParserMode cssParserMode) { ASSERT(!string.isEmpty()); bool quirksMode = isQuirksModeBehavior(cssParserMode); if (!isColorPropertyID(propertyId)) return nullptr; CSSParserString cssString; cssString.init(string); CSSValueID valueID = cssValueKeywordID(cssString); bool validPrimitive = false; if (valueID == CSSValueWebkitText) { validPrimitive = true; } else if (valueID == CSSValueCurrentcolor) { validPrimitive = true; } else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu || (quirksMode && valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText)) { validPrimitive = true; } if (validPrimitive) return cssValuePool().createIdentifierValue(valueID); RGBA32 color; if (!CSSPropertyParser::fastParseColor(color, string, !quirksMode && string[0] != '#')) return nullptr; return cssValuePool().createColorValue(color); }
CSSValue* CSSParserFastPaths::parseColor(const String& string, CSSParserMode parserMode) { ASSERT(!string.isEmpty()); CSSValueID valueID = cssValueKeywordID(string); if (StyleColor::isColorKeyword(valueID)) { if (!isValueAllowedInMode(valueID, parserMode)) return nullptr; return CSSIdentifierValue::create(valueID); } RGBA32 color; bool quirksMode = isQuirksModeBehavior(parserMode); // Fast path for hex colors and rgb()/rgba() colors bool parseResult; if (string.is8Bit()) parseResult = fastParseColorInternal(color, string.characters8(), string.length(), quirksMode); else parseResult = fastParseColorInternal(color, string.characters16(), string.length(), quirksMode); if (!parseResult) return nullptr; return CSSColorValue::create(color); }
std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeId( CSSParserTokenRange& range) { ASSERT(range.peek().type() == HashToken); if (range.peek().getHashTokenType() != HashTokenId) return nullptr; std::unique_ptr<CSSParserSelector> selector = CSSParserSelector::create(); selector->setMatch(CSSSelector::Id); AtomicString value = range.consume().value().toAtomicString(); selector->setValue(value, isQuirksModeBehavior(m_context.matchMode())); return selector; }
PassRefPtrWillBeRawPtr<CSSValue> CSSParserFastPaths::maybeParseValue(CSSPropertyID propertyID, const String& string, CSSParserMode parserMode) { if (RefPtrWillBeRawPtr<CSSValue> length = parseSimpleLengthValue(propertyID, string, parserMode)) return length.release(); if (isColorPropertyID(propertyID)) return parseColor(string, isQuirksModeBehavior(parserMode)); if (RefPtrWillBeRawPtr<CSSValue> keyword = parseKeywordValue(propertyID, string)) return keyword.release(); if (RefPtrWillBeRawPtr<CSSValue> transform = parseSimpleTransform(propertyID, string)) return transform.release(); return nullptr; }
std::unique_ptr<CSSParserSelector> CSSSelectorParser::consumeClass( CSSParserTokenRange& range) { ASSERT(range.peek().type() == DelimiterToken); ASSERT(range.peek().delimiter() == '.'); range.consume(); if (range.peek().type() != IdentToken) return nullptr; std::unique_ptr<CSSParserSelector> selector = CSSParserSelector::create(); selector->setMatch(CSSSelector::Class); AtomicString value = range.consume().value().toAtomicString(); selector->setValue(value, isQuirksModeBehavior(m_context.matchMode())); return selector; }
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeId(CSSParserTokenRange& range) { ASSERT(range.peek().type() == HashToken); if (range.peek().hashTokenType() != HashTokenId) return nullptr; OwnPtr<CSSParserSelector> selector = CSSParserSelector::create(); selector->setMatch(CSSSelector::Id); const AtomicString& value = range.consume().value(); if (isQuirksModeBehavior(m_context.mode())) selector->setValue(value.lower()); else selector->setValue(value); return selector.release(); }
PassOwnPtr<CSSParserSelector> CSSSelectorParser::consumeClass(CSSParserTokenRange& range) { ASSERT(range.peek().type() == DelimiterToken); ASSERT(range.peek().delimiter() == '.'); range.consume(); if (range.peek().type() != IdentToken) return nullptr; OwnPtr<CSSParserSelector> selector = CSSParserSelector::create(); selector->setMatch(CSSSelector::Class); const AtomicString& value = range.consume().value(); if (isQuirksModeBehavior(m_context.mode())) selector->setValue(value.lower()); else selector->setValue(value); return selector.release(); }
void StyleSheetContents::parseAuthorStyleSheet( const CSSStyleSheetResource* cachedStyleSheet, const SecurityOrigin* securityOrigin) { TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", InspectorParseAuthorStyleSheetEvent::data(cachedStyleSheet)); SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Style.AuthorStyleSheet.ParseTime"); bool isSameOriginRequest = securityOrigin && securityOrigin->canRequest(baseURL()); // When the response was fetched via the Service Worker, the original URL may // not be same as the base URL. // TODO(horo): When we will use the original URL as the base URL, we can // remove this check. crbug.com/553535 if (cachedStyleSheet->response().wasFetchedViaServiceWorker()) { const KURL originalURL( cachedStyleSheet->response().originalURLViaServiceWorker()); // |originalURL| is empty when the response is created in the SW. if (!originalURL.isEmpty() && !securityOrigin->canRequest(originalURL)) isSameOriginRequest = false; } CSSStyleSheetResource::MIMETypeCheck mimeTypeCheck = isQuirksModeBehavior(m_parserContext.mode()) && isSameOriginRequest ? CSSStyleSheetResource::MIMETypeCheck::Lax : CSSStyleSheetResource::MIMETypeCheck::Strict; String sheetText = cachedStyleSheet->sheetText(mimeTypeCheck); const ResourceResponse& response = cachedStyleSheet->response(); m_sourceMapURL = response.httpHeaderField(HTTPNames::SourceMap); if (m_sourceMapURL.isEmpty()) { // Try to get deprecated header. m_sourceMapURL = response.httpHeaderField(HTTPNames::X_SourceMap); } CSSParserContext context(parserContext(), UseCounter::getFrom(this)); CSSParser::parseSheet(context, this, sheetText, RuntimeEnabledFeatures::lazyParseCSSEnabled()); }