Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2023-02-23 21:16:30 +08:00
commit ba020f4a76
5 changed files with 77 additions and 42 deletions

View file

@ -839,7 +839,7 @@ intl_FormatNumberToParts(JSContext* cx, UNumberFormat* nf, double x, MutableHand
partIndex++; partIndex++;
} while (true); } while (true);
MOZ_ASSERT(lastEndIndex == chars.length(), MOZ_ASSERT(lastEndIndex == overallResult->length(),
"result array must partition the entire string"); "result array must partition the entire string");
result.setObject(*partsArray); result.setObject(*partsArray);

View file

@ -764,7 +764,8 @@ protected:
bool aIsNegated, bool aIsNegated,
nsIAtom** aPseudoElement, nsIAtom** aPseudoElement,
nsAtomList** aPseudoElementArgs, nsAtomList** aPseudoElementArgs,
CSSPseudoElementType* aPseudoElementType); CSSPseudoElementType* aPseudoElementType,
bool aDisallowCombinators);
nsSelectorParsingStatus ParseAttributeSelector(int32_t& aDataMask, nsSelectorParsingStatus ParseAttributeSelector(int32_t& aDataMask,
nsCSSSelector& aSelector); nsCSSSelector& aSelector);
@ -781,7 +782,7 @@ protected:
nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, nsSelectorParsingStatus ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector,
CSSPseudoClassType aType, CSSPseudoClassType aType,
bool aIsForgiving); bool aDisallowCombinators);
nsSelectorParsingStatus ParseNegatedSimpleSelector(int32_t& aDataMask, nsSelectorParsingStatus ParseNegatedSimpleSelector(int32_t& aDataMask,
nsCSSSelector& aSelector); nsCSSSelector& aSelector);
@ -790,12 +791,15 @@ protected:
// aStopChar. Otherwise, it's done when we hit EOF. // aStopChar. Otherwise, it's done when we hit EOF.
bool ParseSelectorList(nsCSSSelectorList*& aListHead, bool ParseSelectorList(nsCSSSelectorList*& aListHead,
char16_t aStopChar, char16_t aStopChar,
bool aIsForgiving); bool aIsForgiving,
bool aDisallowCombinators);
bool ParseSelectorGroup(nsCSSSelectorList*& aListHead, bool ParseSelectorGroup(nsCSSSelectorList*& aListHead,
bool aIsForgiving); bool aIsForgiving,
bool aDisallowCombinators);
bool ParseSelector(nsCSSSelectorList* aList, bool ParseSelector(nsCSSSelectorList* aList,
char16_t aPrevCombinator, char16_t aPrevCombinator,
bool aIsForgiving); bool aIsForgiving,
bool aDisallowCombinators);
enum { enum {
eParseDeclaration_InBraces = 1 << 0, eParseDeclaration_InBraces = 1 << 0,
@ -2334,7 +2338,7 @@ CSSParserImpl::ParseSelectorString(const nsSubstring& aSelectorString,
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
InitScanner(scanner, reporter, aURI, aURI, nullptr); 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 // We deliberately do not call OUTPUT_ERROR here, because all our
// callers map a failure return to a JS exception, and if that JS // callers map a failure return to a JS exception, and if that JS
@ -5416,7 +5420,7 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
nsCSSSelectorList* slist = nullptr; nsCSSSelectorList* slist = nullptr;
uint32_t linenum, colnum; uint32_t linenum, colnum;
if (!GetNextTokenLocation(true, &linenum, &colnum) || if (!GetNextTokenLocation(true, &linenum, &colnum) ||
!ParseSelectorList(slist, char16_t('{'), false)) { !ParseSelectorList(slist, char16_t('{'), false, false)) {
REPORT_UNEXPECTED(PEBadSelectorRSIgnored); REPORT_UNEXPECTED(PEBadSelectorRSIgnored);
OUTPUT_ERROR(); OUTPUT_ERROR();
SkipRuleSet(aInsideBraces); SkipRuleSet(aInsideBraces);
@ -5453,10 +5457,11 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
bool bool
CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead, CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead,
char16_t aStopChar, char16_t aStopChar,
bool aIsForgiving) bool aIsForgiving,
bool aDisallowCombinators)
{ {
nsCSSSelectorList* list = nullptr; nsCSSSelectorList* list = nullptr;
if (! ParseSelectorGroup(list, aIsForgiving)) { if (! ParseSelectorGroup(list, aIsForgiving, aDisallowCombinators)) {
if (aIsForgiving) { if (aIsForgiving) {
// Initialize to an empty list if the first selector group was invalid // Initialize to an empty list if the first selector group was invalid
// and we're a forgiving selector list. // and we're a forgiving selector list.
@ -5487,7 +5492,7 @@ CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead,
if (',' == tk->mSymbol) { if (',' == tk->mSymbol) {
nsCSSSelectorList* newList = nullptr; nsCSSSelectorList* newList = nullptr;
// Another selector group must follow // Another selector group must follow
if (! ParseSelectorGroup(newList, aIsForgiving)) { if (! ParseSelectorGroup(newList, aIsForgiving, aDisallowCombinators)) {
// Ignore invalid selectors if we're a forgiving selector list. // Ignore invalid selectors if we're a forgiving selector list.
if (aIsForgiving) { if (aIsForgiving) {
continue; continue;
@ -5535,13 +5540,13 @@ static bool IsUniversalSelector(const nsCSSSelector& aSelector)
} }
bool bool
CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving) CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving, bool aDisallowCombinators)
{ {
char16_t combinator = 0; char16_t combinator = 0;
nsAutoPtr<nsCSSSelectorList> list(new nsCSSSelectorList()); nsAutoPtr<nsCSSSelectorList> list(new nsCSSSelectorList());
for (;;) { for (;;) {
if (!ParseSelector(list, combinator, aIsForgiving)) { if (!ParseSelector(list, combinator, aIsForgiving, aDisallowCombinators)) {
return false; return false;
} }
@ -5576,6 +5581,10 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList, bool aIsForgiving)
REPORT_UNEXPECTED_TOKEN(PESelectorListExtra); REPORT_UNEXPECTED_TOKEN(PESelectorListExtra);
return false; return false;
} }
if (aIsForgiving && aDisallowCombinators) {
return false;
}
} }
aList = list.forget(); aList = list.forget();
@ -6000,7 +6009,8 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
bool aIsNegated, bool aIsNegated,
nsIAtom** aPseudoElement, nsIAtom** aPseudoElement,
nsAtomList** aPseudoElementArgs, nsAtomList** aPseudoElementArgs,
CSSPseudoElementType* aPseudoElementType) CSSPseudoElementType* aPseudoElementType,
bool aDisallowCombinators)
{ {
NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs), NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs),
"expected location to store pseudo element"); "expected location to store pseudo element");
@ -6174,11 +6184,9 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
else { else {
MOZ_ASSERT(nsCSSPseudoClasses::HasSelectorListArg(pseudoClassType), MOZ_ASSERT(nsCSSPseudoClasses::HasSelectorListArg(pseudoClassType),
"unexpected pseudo with function token"); "unexpected pseudo with function token");
bool isForgiving =
nsCSSPseudoClasses::HasForgivingSelectorListArg(pseudoClassType);
parsingStatus = ParsePseudoClassWithSelectorListArg(aSelector, parsingStatus = ParsePseudoClassWithSelectorListArg(aSelector,
pseudoClassType, pseudoClassType,
isForgiving); aDisallowCombinators);
} }
if (eSelectorParsingStatus_Continue != parsingStatus) { if (eSelectorParsingStatus_Continue != parsingStatus) {
if (eSelectorParsingStatus_Error == parsingStatus) { if (eSelectorParsingStatus_Error == parsingStatus) {
@ -6310,7 +6318,8 @@ CSSParserImpl::ParseNegatedSimpleSelector(int32_t& aDataMask,
} }
else if (mToken.IsSymbol(':')) { // :pseudo else if (mToken.IsSymbol(':')) { // :pseudo
parsingStatus = ParsePseudoSelector(aDataMask, *newSel, true, parsingStatus = ParsePseudoSelector(aDataMask, *newSel, true,
nullptr, nullptr, nullptr); nullptr, nullptr, nullptr,
false);
} }
else if (mToken.IsSymbol('[')) { // [attribute else if (mToken.IsSymbol('[')) { // [attribute
parsingStatus = ParseAttributeSelector(aDataMask, *newSel); parsingStatus = ParseAttributeSelector(aDataMask, *newSel);
@ -6553,28 +6562,39 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::nsSelectorParsingStatus
CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector, CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector,
CSSPseudoClassType aType, CSSPseudoClassType aType,
bool aIsForgiving) bool aDisallowCombinators)
{ {
bool isForgiving =
nsCSSPseudoClasses::HasForgivingSelectorListArg(aType);
bool isSingleSelector =
nsCSSPseudoClasses::HasSingleSelectorArg(aType);
if (isSingleSelector && !aDisallowCombinators) {
aDisallowCombinators = true;
}
nsAutoPtr<nsCSSSelectorList> slist; nsAutoPtr<nsCSSSelectorList> slist;
if (! ParseSelectorList(*getter_Transfers(slist), char16_t(')'), aIsForgiving)) { if (! ParseSelectorList(*getter_Transfers(slist),
char16_t(')'),
isForgiving,
aDisallowCombinators)) {
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
} }
if (nsCSSPseudoClasses::HasSingleSelectorArg(aType) && if (isSingleSelector && slist->mNext) {
slist->mNext) {
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
} }
for (nsCSSSelectorList *l = slist; l; l = l->mNext) { for (nsCSSSelectorList *l = slist; l; l = l->mNext) {
nsCSSSelector *s = l->mSelectors; nsCSSSelector *s = l->mSelectors;
if (s == nullptr) { if (s == nullptr) {
MOZ_ASSERT(aIsForgiving, MOZ_ASSERT(isForgiving,
"unexpected empty selector in unforgiving selector list"); "unexpected empty selector in unforgiving selector list");
break; break;
} }
// Check that none of the selectors in the list have combinators or // Check that none of the selectors in the list have combinators or
// pseudo-elements. // pseudo-elements.
if ((!aIsForgiving && s->mNext) || s->IsPseudoElement()) { if ((!isForgiving && s->mNext) || s->IsPseudoElement()) {
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
} }
} }
@ -6599,7 +6619,8 @@ CSSParserImpl::ParsePseudoClassWithSelectorListArg(nsCSSSelector& aSelector,
bool bool
CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, CSSParserImpl::ParseSelector(nsCSSSelectorList* aList,
char16_t aPrevCombinator, char16_t aPrevCombinator,
bool aIsForgiving) bool aIsForgiving,
bool aDisallowCombinators)
{ {
if (! GetToken(true)) { if (! GetToken(true)) {
REPORT_UNEXPECTED_EOF(PESelectorEOF); REPORT_UNEXPECTED_EOF(PESelectorEOF);
@ -6620,7 +6641,8 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList,
parsingStatus = ParsePseudoSelector(dataMask, *selector, false, parsingStatus = ParsePseudoSelector(dataMask, *selector, false,
getter_AddRefs(pseudoElement), getter_AddRefs(pseudoElement),
getter_Transfers(pseudoElementArgs), getter_Transfers(pseudoElementArgs),
&pseudoElementType); &pseudoElementType,
aDisallowCombinators);
if (pseudoElement && if (pseudoElement &&
pseudoElementType != CSSPseudoElementType::AnonBox) { pseudoElementType != CSSPseudoElementType::AnonBox) {
// Pseudo-elements other than anonymous boxes are represented with // Pseudo-elements other than anonymous boxes are represented with

View file

@ -109,6 +109,30 @@ nsCSSPseudoClasses::HasSingleSelectorArg(Type aType)
aType == Type::hostContext; 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 void
nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString) nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString)
{ {

View file

@ -59,21 +59,9 @@ public:
static bool HasStringArg(Type aType); static bool HasStringArg(Type aType);
static bool HasNthPairArg(Type aType); static bool HasNthPairArg(Type aType);
static bool HasSingleSelectorArg(Type aType); static bool HasSingleSelectorArg(Type aType);
static bool HasForgivingSelectorListArg(Type aType) { static bool HasForgivingSelectorListArg(Type aType);
return aType == Type::is || static bool HasSelectorListArg(Type aType);
aType == Type::matches || static bool HasOptionalSelectorListArg(Type aType);
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 IsUserActionPseudoClass(Type aType); static bool IsUserActionPseudoClass(Type aType);
// Should only be used on types other than Count and NotPseudoClass // Should only be used on types other than Count and NotPseudoClass

View file

@ -2713,7 +2713,8 @@ static bool SelectorListMatches(Element* aElement,
aNodeMatchContext, aNodeMatchContext,
aTreeMatchContext, aTreeMatchContext,
SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT, SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT,
aIsForgiving); aIsForgiving,
aPreventComplexSelectors);
} }
static inline static inline