#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/css/parser/css_selector_parser.h"
#include <algorithm>
#include <memory>
#include "base/auto_reset.h"
#include "base/containers/span.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
#include "third_party/blink/renderer/core/css/css_selector_list.h"
#include "third_party/blink/renderer/core/css/parser/css_nesting_type.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_observer.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_save_point.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_stream.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/deprecation/deprecation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
static void RecordUsageAndDeprecationsOneSelector(
const CSSSelector* selector,
const CSSParserContext* context);
namespace {
bool AtEndIgnoringWhitespace(CSSParserTokenStream& stream) { … }
bool IsHostPseudoSelector(const CSSSelector& selector) { … }
CSSSelector::RelationType GetImplicitShadowCombinatorForMatching(
CSSSelector::PseudoType pseudo_type) { … }
bool NeedsImplicitShadowCombinatorForMatching(const CSSSelector& selector) { … }
void MarkAsEntireComplexSelector(base::span<CSSSelector> selectors) { … }
}
base::span<CSSSelector> CSSSelectorParser::ParseSelector(
CSSParserTokenStream& stream,
const CSSParserContext* context,
CSSNestingType nesting_type,
const StyleRule* parent_rule_for_nesting,
bool is_within_scope,
bool semicolon_aborts_nested_selector,
StyleSheetContents* style_sheet,
HeapVector<CSSSelector>& arena) { … }
base::span<CSSSelector> CSSSelectorParser::ConsumeSelector(
CSSParserTokenStream& stream,
const CSSParserContext* context,
CSSNestingType nesting_type,
const StyleRule* parent_rule_for_nesting,
bool is_within_scope,
bool semicolon_aborts_nested_selector,
StyleSheetContents* style_sheet,
CSSParserObserver* observer,
HeapVector<CSSSelector>& arena) { … }
std::optional<base::span<CSSSelector>> CSSSelectorParser::ParseScopeBoundary(
CSSParserTokenStream& stream,
const CSSParserContext* context,
CSSNestingType nesting_type,
const StyleRule* parent_rule_for_nesting,
bool is_within_scope,
StyleSheetContents* style_sheet,
HeapVector<CSSSelector>& arena) { … }
bool CSSSelectorParser::SupportsComplexSelector(
CSSParserTokenStream& stream,
const CSSParserContext* context) { … }
CSSSelectorParser::CSSSelectorParser(const CSSParserContext* context,
const StyleRule* parent_rule_for_nesting,
bool is_within_scope,
bool semicolon_aborts_nested_selector,
StyleSheetContents* style_sheet,
HeapVector<CSSSelector>& output)
: … { … }
base::span<CSSSelector> CSSSelectorParser::ConsumeComplexSelectorList(
CSSParserTokenStream& stream,
CSSNestingType nesting_type) { … }
static bool AtEndOfComplexSelector(CSSParserTokenStream& stream) { … }
base::span<CSSSelector> CSSSelectorParser::ConsumeComplexSelectorList(
CSSParserTokenStream& stream,
CSSParserObserver* observer,
CSSNestingType nesting_type) { … }
CSSSelectorList* CSSSelectorParser::ConsumeCompoundSelectorList(
CSSParserTokenStream& stream) { … }
CSSSelectorList* CSSSelectorParser::ConsumeNestedSelectorList(
CSSParserTokenStream& stream) { … }
CSSSelectorList* CSSSelectorParser::ConsumeForgivingNestedSelectorList(
CSSParserTokenStream& stream) { … }
std::optional<base::span<CSSSelector>>
CSSSelectorParser::ConsumeForgivingComplexSelectorList(
CSSParserTokenStream& stream,
CSSNestingType nesting_type) { … }
static CSSNestingType ConsumeUntilCommaAndFindNestingType(
CSSParserTokenStream& stream) { … }
void CSSSelectorParser::AddPlaceholderSelectorIfNeeded(
CSSParserTokenStream& stream) { … }
CSSSelectorList* CSSSelectorParser::ConsumeForgivingCompoundSelectorList(
CSSParserTokenStream& stream) { … }
CSSSelectorList* CSSSelectorParser::ConsumeForgivingRelativeSelectorList(
CSSParserTokenStream& stream) { … }
CSSSelectorList* CSSSelectorParser::ConsumeRelativeSelectorList(
CSSParserTokenStream& stream) { … }
namespace {
enum CompoundSelectorFlags { … };
unsigned ExtractCompoundFlags(const CSSSelector& simple_selector,
CSSParserMode parser_mode) { … }
unsigned ExtractCompoundFlags(const base::span<CSSSelector> compound_selector,
CSSParserMode parser_mode) { … }
}
base::span<CSSSelector> CSSSelectorParser::ConsumeRelativeSelector(
CSSParserTokenStream& stream) { … }
static CSSNestingType GetNestingTypeForSelectorList(
const CSSSelector* selector) { … }
static CSSSelector CreateImplicitAnchor(
CSSNestingType nesting_type,
const StyleRule* parent_rule_for_nesting) { … }
static CSSSelector CreateImplicitScopeActivation() { … }
static std::optional<CSSSelector> MaybeCreateImplicitDescendantAnchor(
CSSNestingType nesting_type,
const StyleRule* parent_rule_for_nesting,
const CSSSelector* selector) { … }
base::span<CSSSelector> CSSSelectorParser::ConsumeNestedRelativeSelector(
CSSParserTokenStream& stream,
CSSNestingType nesting_type) { … }
base::span<CSSSelector> CSSSelectorParser::ConsumeComplexSelector(
CSSParserTokenStream& stream,
CSSNestingType nesting_type,
bool first_in_complex_selector_list) { … }
bool CSSSelectorParser::ConsumePartialComplexSelector(
CSSParserTokenStream& stream,
CSSSelector::RelationType& combinator,
unsigned previous_compound_flags,
CSSNestingType nesting_type) { … }
CSSSelector::PseudoType CSSSelectorParser::ParsePseudoType(
const AtomicString& name,
bool has_arguments,
const Document* document) { … }
namespace {
PseudoId ParsePseudoElementLegacy(const String& selector_string,
const Node* parent) { … }
AtomicString ParsePseudoElementArgument(const String& selector_string) { … }
}
PseudoId CSSSelectorParser::ParsePseudoElement(const String& selector_string,
const Node* parent,
AtomicString& argument) { … }
namespace {
bool IsScrollbarPseudoClass(CSSSelector::PseudoType pseudo) { … }
bool IsUserActionPseudoClass(CSSSelector::PseudoType pseudo) { … }
bool IsPseudoClassValidAfterPseudoElement(
CSSSelector::PseudoType pseudo_class,
CSSSelector::PseudoType compound_pseudo_element) { … }
bool IsSimpleSelectorValidAfterPseudoElement(
const CSSSelector& simple_selector,
CSSSelector::PseudoType compound_pseudo_element) { … }
bool IsPseudoClassValidWithinHasArgument(CSSSelector& selector) { … }
static bool SelectorListRequiresScopeActivation(const CSSSelectorList& list);
static bool SimpleSelectorRequiresScopeActivation(const CSSSelector& selector) { … }
static bool SelectorListRequiresScopeActivation(const CSSSelectorList& list) { … }
}
base::span<CSSSelector> CSSSelectorParser::ConsumeCompoundSelector(
CSSParserTokenStream& stream,
CSSNestingType nesting_type) { … }
bool CSSSelectorParser::ConsumeSimpleSelector(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumeName(CSSParserTokenStream& stream,
AtomicString& name,
AtomicString& namespace_prefix) { … }
bool CSSSelectorParser::ConsumeId(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumeClass(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumeAttribute(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumePseudo(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumeNestingParent(CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::PeekIsCombinator(CSSParserTokenStream& stream) { … }
CSSSelector::RelationType CSSSelectorParser::ConsumeCombinator(
CSSParserTokenStream& stream) { … }
CSSSelector::MatchType CSSSelectorParser::ConsumeAttributeMatch(
CSSParserTokenStream& stream) { … }
CSSSelector::AttributeMatchType CSSSelectorParser::ConsumeAttributeFlags(
CSSParserTokenStream& stream) { … }
bool CSSSelectorParser::ConsumeANPlusB(CSSParserTokenStream& stream,
std::pair<int, int>& result) { … }
CSSSelectorList* CSSSelectorParser::ConsumeNthChildOfSelectors(
CSSParserTokenStream& stream) { … }
const AtomicString& CSSSelectorParser::DefaultNamespace() const { … }
const AtomicString& CSSSelectorParser::DetermineNamespace(
const AtomicString& prefix) { … }
void CSSSelectorParser::PrependTypeSelectorIfNeeded(
const AtomicString& namespace_prefix,
bool has_q_name,
const AtomicString& element_name,
wtf_size_t start_index_of_compound_selector) { … }
void CSSSelectorParser::SplitCompoundAtImplicitShadowCrossingCombinator(
base::span<CSSSelector> selectors) { … }
namespace {
struct PseudoElementFeatureMapEntry { … };
WebFeature FeatureForWebKitCustomPseudoElement(const AtomicString& name) { … }
}
static void RecordUsageAndDeprecationsOneSelector(
const CSSSelector* selector,
const CSSParserContext* context) { … }
void CSSSelectorParser::RecordUsageAndDeprecations(
const base::span<CSSSelector> selector_vector) { … }
bool CSSSelectorParser::ContainsUnknownWebkitPseudoElements(
base::span<CSSSelector> selectors) { … }
}