From 03a33857029373e9e7353f42c22c753ab176dfdd Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Tue, 21 Feb 2023 20:05:51 +0800 Subject: [PATCH 1/5] No issue - Move Has* function definition out of the header file for consistency --- layout/style/nsCSSPseudoClasses.cpp | 24 ++++++++++++++++++++++++ layout/style/nsCSSPseudoClasses.h | 18 +++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/layout/style/nsCSSPseudoClasses.cpp b/layout/style/nsCSSPseudoClasses.cpp index 928326e399..23517ef52c 100644 --- a/layout/style/nsCSSPseudoClasses.cpp +++ b/layout/style/nsCSSPseudoClasses.cpp @@ -109,6 +109,30 @@ nsCSSPseudoClasses::HasSingleSelectorArg(Type aType) aType == Type::hostContext; } +bool +nsCSSPseudoClasses::HasForgivingSelectorListArg(Type aType) +{ + return aType == Type::is || + aType == Type::matches || + aType == Type::any || + aType == Type::where; +} + +bool +nsCSSPseudoClasses::HasSelectorListArg(Type aType) +{ + return HasForgivingSelectorListArg(aType) || + aType == Type::mozAny || + aType == Type::host || + aType == Type::hostContext; +} + +bool +nsCSSPseudoClasses::HasOptionalSelectorListArg(Type aType) +{ + return aType == Type::host; +} + void nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString) { diff --git a/layout/style/nsCSSPseudoClasses.h b/layout/style/nsCSSPseudoClasses.h index 76fcef3f78..99c05b019f 100644 --- a/layout/style/nsCSSPseudoClasses.h +++ b/layout/style/nsCSSPseudoClasses.h @@ -59,21 +59,9 @@ public: static bool HasStringArg(Type aType); static bool HasNthPairArg(Type aType); static bool HasSingleSelectorArg(Type aType); - static bool HasForgivingSelectorListArg(Type aType) { - return aType == Type::is || - aType == Type::matches || - aType == Type::any || - aType == Type::where; - } - static bool HasSelectorListArg(Type aType) { - return HasForgivingSelectorListArg(aType) || - aType == Type::mozAny || - aType == Type::host || - aType == Type::hostContext; - } - static bool HasOptionalSelectorListArg(Type aType) { - return aType == Type::host; - } + static bool HasForgivingSelectorListArg(Type aType); + static bool HasSelectorListArg(Type aType); + static bool HasOptionalSelectorListArg(Type aType); static bool IsUserActionPseudoClass(Type aType); // Should only be used on types other than Count and NotPseudoClass From 53f5905381c01fa4f980b23980980efbdc815922 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Tue, 21 Feb 2023 19:54:31 +0800 Subject: [PATCH 2/5] Issue #2078 - Follow-up: Move isForgiving check to ParsePseudoClassWithSelectorListArg --- layout/style/nsCSSParser.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index ba97bbd3d7..78e9053cfd 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -780,8 +780,7 @@ protected: CSSPseudoClassType aType); nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType, - bool aIsForgiving); + CSSPseudoClassType aType); nsSelectorParsingStatus ParseNegatedSimpleSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -6166,11 +6165,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, else { MOZ_ASSERT(nsCSSPseudoClasses::HasSelectorListArg(pseudoClassType), "unexpected pseudo with function token"); - bool isForgiving = - nsCSSPseudoClasses::HasForgivingSelectorListArg(pseudoClassType); parsingStatus = ParsePseudoClassWithSelectorListArg(aSelector, - pseudoClassType, - isForgiving); + pseudoClassType); } if (eSelectorParsingStatus_Continue != parsingStatus) { if (eSelectorParsingStatus_Error == parsingStatus) { @@ -6544,11 +6540,13 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, // CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType, - bool aIsForgiving) + CSSPseudoClassType aType) { + bool isForgiving = + nsCSSPseudoClasses::HasForgivingSelectorListArg(aType); + nsAutoPtr slist; - if (! ParseSelectorList(*getter_Transfers(slist), char16_t(')'), aIsForgiving)) { + if (! ParseSelectorList(*getter_Transfers(slist), char16_t(')'), isForgiving)) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } @@ -6560,13 +6558,13 @@ CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, for (nsCSSSelectorList *l = slist; l; l = l->mNext) { nsCSSSelector *s = l->mSelectors; if (s == nullptr) { - MOZ_ASSERT(aIsForgiving, + MOZ_ASSERT(isForgiving, "unexpected empty selector in unforgiving selector list"); break; } // Check that none of the selectors in the list have combinators or // pseudo-elements. - if ((!aIsForgiving && s->mNext) || s->IsPseudoElement()) { + if ((!isForgiving && s->mNext) || s->IsPseudoElement()) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } } From 83484a34f5b7bd37fa2aa33756dc784ce385c6b4 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Tue, 21 Feb 2023 21:18:58 +0800 Subject: [PATCH 3/5] Issue #2078 - Follow-up: aPreventComplexSelectors should be passed --- layout/style/nsCSSRuleProcessor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index de4ee0fc3b..73209a951a 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2713,7 +2713,8 @@ static bool SelectorListMatches(Element* aElement, aNodeMatchContext, aTreeMatchContext, SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT, - aIsForgiving); + aIsForgiving, + aPreventComplexSelectors); } static inline From 439c671b264c2d927c99751ca6dbb2283ccb1054 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Tue, 21 Feb 2023 22:06:49 +0800 Subject: [PATCH 4/5] Issue #2078 - Follow-up: Propagate combinator restriction to :is()/:where() Based on spec discussion: https://github.com/w3c/csswg-drafts/issues/5093 --- layout/style/nsCSSParser.cpp | 66 ++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 78e9053cfd..ba8eedaf03 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -764,7 +764,8 @@ protected: bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - CSSPseudoElementType* aPseudoElementType); + CSSPseudoElementType* aPseudoElementType, + bool aDisallowCombinators); nsSelectorParsingStatus ParseAttributeSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -780,7 +781,8 @@ protected: CSSPseudoClassType aType); nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType); + CSSPseudoClassType aType, + bool aDisallowCombinators); nsSelectorParsingStatus ParseNegatedSimpleSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -789,12 +791,15 @@ protected: // aStopChar. Otherwise, it's done when we hit EOF. bool ParseSelectorList(nsCSSSelectorList*& aListHead, char16_t aStopChar, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); bool ParseSelectorGroup(nsCSSSelectorList*& aListHead, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); bool ParseSelector(nsCSSSelectorList* aList, char16_t aPrevCombinator, - bool aIsForgiving); + bool aIsForgiving, + bool aDisallowCombinators); enum { eParseDeclaration_InBraces = 1 << 0, @@ -2325,7 +2330,7 @@ CSSParserImpl::ParseSelectorString(const nsSubstring& aSelectorString, css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); InitScanner(scanner, reporter, aURI, aURI, nullptr); - bool success = ParseSelectorList(*aSelectorList, char16_t(0), false); + bool success = ParseSelectorList(*aSelectorList, char16_t(0), false, false); // We deliberately do not call OUTPUT_ERROR here, because all our // callers map a failure return to a JS exception, and if that JS @@ -5407,7 +5412,7 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData, nsCSSSelectorList* slist = nullptr; uint32_t linenum, colnum; if (!GetNextTokenLocation(true, &linenum, &colnum) || - !ParseSelectorList(slist, char16_t('{'), false)) { + !ParseSelectorList(slist, char16_t('{'), false, false)) { REPORT_UNEXPECTED(PEBadSelectorRSIgnored); OUTPUT_ERROR(); SkipRuleSet(aInsideBraces); @@ -5444,10 +5449,11 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData, bool CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead, char16_t aStopChar, - bool aIsForgiving) + bool aIsForgiving, + bool aDisallowCombinators) { nsCSSSelectorList* list = nullptr; - if (! ParseSelectorGroup(list, aIsForgiving)) { + if (! ParseSelectorGroup(list, aIsForgiving, aDisallowCombinators)) { if (aIsForgiving) { // Initialize to an empty list if the first selector group was invalid // and we're a forgiving selector list. @@ -5478,7 +5484,7 @@ CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead, if (',' == tk->mSymbol) { nsCSSSelectorList* newList = nullptr; // Another selector group must follow - if (! ParseSelectorGroup(newList, aIsForgiving)) { + if (! ParseSelectorGroup(newList, aIsForgiving, aDisallowCombinators)) { // Ignore invalid selectors if we're a forgiving selector list. if (aIsForgiving) { continue; @@ -5526,13 +5532,13 @@ static bool IsUniversalSelector(const nsCSSSelector& aSelector) } bool -CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving) +CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving, bool aDisallowCombinators) { char16_t combinator = 0; nsAutoPtr list(new nsCSSSelectorList()); for (;;) { - if (!ParseSelector(list, combinator, aIsForgiving)) { + if (!ParseSelector(list, combinator, aIsForgiving, aDisallowCombinators)) { return false; } @@ -5567,6 +5573,10 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving) REPORT_UNEXPECTED_TOKEN(PESelectorListExtra); return false; } + + if (aIsForgiving && aDisallowCombinators) { + return false; + } } aList = list.forget(); @@ -5991,7 +6001,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - CSSPseudoElementType* aPseudoElementType) + CSSPseudoElementType* aPseudoElementType, + bool aDisallowCombinators) { NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs), "expected location to store pseudo element"); @@ -6166,7 +6177,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, MOZ_ASSERT(nsCSSPseudoClasses::HasSelectorListArg(pseudoClassType), "unexpected pseudo with function token"); parsingStatus = ParsePseudoClassWithSelectorListArg(aSelector, - pseudoClassType); + pseudoClassType, + aDisallowCombinators); } if (eSelectorParsingStatus_Continue != parsingStatus) { if (eSelectorParsingStatus_Error == parsingStatus) { @@ -6298,7 +6310,8 @@ CSSParserImpl::ParseNegatedSimpleSelector(int32_t& aDataMask, } else if (mToken.IsSymbol(':')) { // :pseudo parsingStatus = ParsePseudoSelector(aDataMask, *newSel, true, - nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, + false); } else if (mToken.IsSymbol('[')) { // [attribute parsingStatus = ParseAttributeSelector(aDataMask, *newSel); @@ -6540,18 +6553,27 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, // CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, - CSSPseudoClassType aType) + CSSPseudoClassType aType, + bool aDisallowCombinators) { bool isForgiving = nsCSSPseudoClasses::HasForgivingSelectorListArg(aType); + bool isSingleSelector = + nsCSSPseudoClasses::HasSingleSelectorArg(aType); + + if (isSingleSelector && !aDisallowCombinators) { + aDisallowCombinators = true; + } nsAutoPtr slist; - if (! ParseSelectorList(*getter_Transfers(slist), char16_t(')'), isForgiving)) { + if (! ParseSelectorList(*getter_Transfers(slist), + char16_t(')'), + isForgiving, + aDisallowCombinators)) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } - if (nsCSSPseudoClasses::HasSingleSelectorArg(aType) && - slist->mNext) { + if (isSingleSelector && slist->mNext) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } @@ -6589,7 +6611,8 @@ CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, bool CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, char16_t aPrevCombinator, - bool aIsForgiving) + bool aIsForgiving, + bool aDisallowCombinators) { if (! GetToken(true)) { REPORT_UNEXPECTED_EOF(PESelectorEOF); @@ -6610,7 +6633,8 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, parsingStatus = ParsePseudoSelector(dataMask, *selector, false, getter_AddRefs(pseudoElement), getter_Transfers(pseudoElementArgs), - &pseudoElementType); + &pseudoElementType, + aDisallowCombinators); if (pseudoElement && pseudoElementType != CSSPseudoElementType::AnonBox) { // Pseudo-elements other than anonymous boxes are represented with From fa014f9e952df6e3bc4916e94ef28c825d8db75f Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 22 Feb 2023 22:31:24 +0100 Subject: [PATCH 5/5] Issue #2046 - Follow-up: Fix debug assert using old chars definition. --- js/src/builtin/intl/NumberFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/builtin/intl/NumberFormat.cpp b/js/src/builtin/intl/NumberFormat.cpp index 4fc08a0920..1fe6b8299f 100644 --- a/js/src/builtin/intl/NumberFormat.cpp +++ b/js/src/builtin/intl/NumberFormat.cpp @@ -839,7 +839,7 @@ intl_FormatNumberToParts(JSContext* cx, UNumberFormat* nf, double x, MutableHand partIndex++; } while (true); - MOZ_ASSERT(lastEndIndex == chars.length(), + MOZ_ASSERT(lastEndIndex == overallResult->length(), "result array must partition the entire string"); result.setObject(*partsArray);