ma1 pushed to branch mullvad-browser-115.16.0esr-13.5-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
eafe617f
by Nika Layzell at 2024-10-01T00:57:18+02:00
-
db726edf
by Paul Zuehlcke at 2024-10-01T00:57:20+02:00
-
be142b0d
by André Bargull at 2024-10-01T00:57:21+02:00
-
bfc54ed4
by Emilio Cobos Álvarez at 2024-10-01T00:57:23+02:00
-
cb01df5c
by Steve Fink at 2024-10-01T00:57:25+02:00
-
84dc8a8a
by Nika Layzell at 2024-10-01T00:57:26+02:00
-
0fe417ba
by Kershaw Chang at 2024-10-01T00:57:28+02:00
22 changed files:
- browser/base/content/test/tabPrompts/browser_confirmFolderUpload.js
- browser/components/prompts/PromptCollection.sys.mjs
- docshell/base/BrowsingContext.cpp
- docshell/base/BrowsingContext.h
- docshell/base/nsDocShell.cpp
- docshell/base/nsDocShell.h
- dom/base/Document.cpp
- dom/base/Document.h
- dom/base/ShadowRoot.cpp
- dom/base/ShadowRoot.h
- dom/filesystem/tests/script_promptHandler.js
- js/public/StructuredClone.h
- js/public/friend/ErrorNumbers.msg
- js/src/jit-test/tests/structured-clone/transferable-cleanup.js
- js/src/jit/IonAnalysis.cpp
- js/src/vm/StructuredClone.cpp
- layout/style/ServoStyleSet.cpp
- layout/style/ServoStyleSet.h
- layout/style/StyleSheet.cpp
- netwerk/ipc/DocumentLoadListener.cpp
- netwerk/protocol/webtransport/WebTransportSessionProxy.cpp
- + testing/web-platform/tests/css/cssom/insertRule-import-trailing-garbage-crash.html
Changes:
| ... | ... | @@ -101,8 +101,29 @@ async function testUploadPrompt(confirmUpload) { |
| 101 | 101 | // Wait for confirmation prompt
|
| 102 | 102 | let prompt = await promptPromise;
|
| 103 | 103 | ok(prompt, "Shown upload confirmation prompt");
|
| 104 | + |
|
| 104 | 105 | is(prompt.ui.button0.label, "Upload", "Accept button label");
|
| 106 | + ok(
|
|
| 107 | + prompt.ui.button0.disabled,
|
|
| 108 | + "Accept button should be disabled by the security delay initially."
|
|
| 109 | + );
|
|
| 110 | + |
|
| 105 | 111 | ok(prompt.ui.button1.hasAttribute("default"), "Cancel is default button");
|
| 112 | + ok(
|
|
| 113 | + !prompt.ui.button1.disabled,
|
|
| 114 | + "Cancel button should not be disabled by the security delay."
|
|
| 115 | + );
|
|
| 116 | + |
|
| 117 | + info("Wait for the security delay to pass.");
|
|
| 118 | + let delayTime = Services.prefs.getIntPref("security.dialog_enable_delay");
|
|
| 119 | + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
|
| 120 | + await new Promise(resolve => setTimeout(resolve, delayTime + 100));
|
|
| 121 | + |
|
| 122 | + ok(
|
|
| 123 | + !prompt.ui.button0.disabled,
|
|
| 124 | + "Accept button should no longer be disabled."
|
|
| 125 | + );
|
|
| 126 | + ok(!prompt.ui.button1.disabled, "Cancel button should remain enabled.");
|
|
| 106 | 127 | |
| 107 | 128 | // Close confirmation prompt
|
| 108 | 129 | await PromptTestUtils.handlePrompt(prompt, {
|
| ... | ... | @@ -156,7 +156,7 @@ export class PromptCollection { |
| 156 | 156 | Services.prompt.MODAL_TYPE_TAB,
|
| 157 | 157 | title,
|
| 158 | 158 | message,
|
| 159 | - buttonFlags,
|
|
| 159 | + buttonFlags | Ci.nsIPrompt.BUTTON_DELAY_ENABLE,
|
|
| 160 | 160 | acceptLabel,
|
| 161 | 161 | null,
|
| 162 | 162 | null,
|
| ... | ... | @@ -572,9 +572,19 @@ mozilla::ipc::IPCResult BrowsingContext::CreateFromIPC( |
| 572 | 572 | context->mRequestContextId = aInit.mRequestContextId;
|
| 573 | 573 | // NOTE: Private browsing ID is set by `SetOriginAttributes`.
|
| 574 | 574 | |
| 575 | + if (const char* failure =
|
|
| 576 | + context->BrowsingContextCoherencyChecks(aOriginProcess)) {
|
|
| 577 | + mozilla::ipc::IProtocol* actor = aOriginProcess;
|
|
| 578 | + if (!actor) {
|
|
| 579 | + actor = ContentChild::GetSingleton();
|
|
| 580 | + }
|
|
| 581 | + return IPC_FAIL(actor, "Incoherent BrowsingContext");
|
|
| 582 | + }
|
|
| 583 | + |
|
| 575 | 584 | Register(context);
|
| 576 | 585 | |
| 577 | - return context->Attach(/* aFromIPC */ true, aOriginProcess);
|
|
| 586 | + context->Attach(/* aFromIPC */ true, aOriginProcess);
|
|
| 587 | + return IPC_OK();
|
|
| 578 | 588 | }
|
| 579 | 589 | |
| 580 | 590 | BrowsingContext::BrowsingContext(WindowContext* aParentWindow,
|
| ... | ... | @@ -786,8 +796,64 @@ void BrowsingContext::Embed() { |
| 786 | 796 | }
|
| 787 | 797 | }
|
| 788 | 798 | |
| 789 | -mozilla::ipc::IPCResult BrowsingContext::Attach(bool aFromIPC,
|
|
| 790 | - ContentParent* aOriginProcess) {
|
|
| 799 | +const char* BrowsingContext::BrowsingContextCoherencyChecks(
|
|
| 800 | + ContentParent* aOriginProcess) {
|
|
| 801 | +#define COHERENCY_ASSERT(condition) \
|
|
| 802 | + if (!(condition)) return "Assertion " #condition " failed";
|
|
| 803 | + |
|
| 804 | + if (mGroup->IsPotentiallyCrossOriginIsolated() !=
|
|
| 805 | + (Top()->GetOpenerPolicy() ==
|
|
| 806 | + nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP)) {
|
|
| 807 | + return "Invalid CrossOriginIsolated state";
|
|
| 808 | + }
|
|
| 809 | + |
|
| 810 | + if (aOriginProcess && !IsContent()) {
|
|
| 811 | + return "Content cannot create chrome BCs";
|
|
| 812 | + }
|
|
| 813 | + |
|
| 814 | + // LoadContext should generally match our opener or parent.
|
|
| 815 | + if (IsContent()) {
|
|
| 816 | + if (RefPtr<BrowsingContext> opener = GetOpener()) {
|
|
| 817 | + COHERENCY_ASSERT(opener->mType == mType);
|
|
| 818 | + COHERENCY_ASSERT(opener->mGroup == mGroup);
|
|
| 819 | + COHERENCY_ASSERT(opener->mUseRemoteTabs == mUseRemoteTabs);
|
|
| 820 | + COHERENCY_ASSERT(opener->mUseRemoteSubframes == mUseRemoteSubframes);
|
|
| 821 | + COHERENCY_ASSERT(opener->mPrivateBrowsingId == mPrivateBrowsingId);
|
|
| 822 | + COHERENCY_ASSERT(
|
|
| 823 | + opener->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
|
| 824 | + }
|
|
| 825 | + }
|
|
| 826 | + if (RefPtr<BrowsingContext> parent = GetParent()) {
|
|
| 827 | + COHERENCY_ASSERT(parent->mType == mType);
|
|
| 828 | + COHERENCY_ASSERT(parent->mGroup == mGroup);
|
|
| 829 | + COHERENCY_ASSERT(parent->mUseRemoteTabs == mUseRemoteTabs);
|
|
| 830 | + COHERENCY_ASSERT(parent->mUseRemoteSubframes == mUseRemoteSubframes);
|
|
| 831 | + COHERENCY_ASSERT(parent->mPrivateBrowsingId == mPrivateBrowsingId);
|
|
| 832 | + COHERENCY_ASSERT(
|
|
| 833 | + parent->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
|
| 834 | + }
|
|
| 835 | + |
|
| 836 | + // UseRemoteSubframes and UseRemoteTabs must match.
|
|
| 837 | + if (mUseRemoteSubframes && !mUseRemoteTabs) {
|
|
| 838 | + return "Cannot set useRemoteSubframes without also setting useRemoteTabs";
|
|
| 839 | + }
|
|
| 840 | + |
|
| 841 | + // Double-check OriginAttributes/Private Browsing
|
|
| 842 | + // Chrome browsing contexts must not have a private browsing OriginAttribute
|
|
| 843 | + // Content browsing contexts must maintain the equality:
|
|
| 844 | + // mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId
|
|
| 845 | + if (IsChrome()) {
|
|
| 846 | + COHERENCY_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
|
|
| 847 | + } else {
|
|
| 848 | + COHERENCY_ASSERT(mOriginAttributes.mPrivateBrowsingId ==
|
|
| 849 | + mPrivateBrowsingId);
|
|
| 850 | + }
|
|
| 851 | +#undef COHERENCY_ASSERT
|
|
| 852 | + |
|
| 853 | + return nullptr;
|
|
| 854 | +}
|
|
| 855 | + |
|
| 856 | +void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
|
|
| 791 | 857 | MOZ_DIAGNOSTIC_ASSERT(!mEverAttached);
|
| 792 | 858 | MOZ_DIAGNOSTIC_ASSERT_IF(aFromIPC, aOriginProcess || XRE_IsContentProcess());
|
| 793 | 859 | mEverAttached = true;
|
| ... | ... | @@ -806,25 +872,15 @@ mozilla::ipc::IPCResult BrowsingContext::Attach(bool aFromIPC, |
| 806 | 872 | MOZ_DIAGNOSTIC_ASSERT(mGroup);
|
| 807 | 873 | MOZ_DIAGNOSTIC_ASSERT(!mIsDiscarded);
|
| 808 | 874 | |
| 809 | - if (mGroup->IsPotentiallyCrossOriginIsolated() !=
|
|
| 810 | - (Top()->GetOpenerPolicy() ==
|
|
| 811 | - nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP)) {
|
|
| 812 | - MOZ_DIAGNOSTIC_ASSERT(aFromIPC);
|
|
| 813 | - if (aFromIPC) {
|
|
| 814 | - auto* actor = aOriginProcess
|
|
| 815 | - ? static_cast<mozilla::ipc::IProtocol*>(aOriginProcess)
|
|
| 816 | - : static_cast<mozilla::ipc::IProtocol*>(
|
|
| 817 | - ContentChild::GetSingleton());
|
|
| 818 | - return IPC_FAIL(
|
|
| 819 | - actor,
|
|
| 820 | - "Invalid CrossOriginIsolated state in BrowsingContext::Attach call");
|
|
| 821 | - } else {
|
|
| 822 | - MOZ_CRASH(
|
|
| 823 | - "Invalid CrossOriginIsolated state in BrowsingContext::Attach call");
|
|
| 875 | +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
|
| 876 | + // We'll already have checked this if `aFromIPC` is set before calling this
|
|
| 877 | + // function.
|
|
| 878 | + if (!aFromIPC) {
|
|
| 879 | + if (const char* failure = BrowsingContextCoherencyChecks(aOriginProcess)) {
|
|
| 880 | + MOZ_CRASH_UNSAFE_PRINTF("Incoherent BrowsingContext: %s", failure);
|
|
| 824 | 881 | }
|
| 825 | 882 | }
|
| 826 | - |
|
| 827 | - AssertCoherentLoadContext();
|
|
| 883 | +#endif
|
|
| 828 | 884 | |
| 829 | 885 | // Add ourselves either to our parent or BrowsingContextGroup's child list.
|
| 830 | 886 | // Important: We shouldn't return IPC_FAIL after this point, since the
|
| ... | ... | @@ -906,7 +962,6 @@ mozilla::ipc::IPCResult BrowsingContext::Attach(bool aFromIPC, |
| 906 | 962 | if (XRE_IsParentProcess()) {
|
| 907 | 963 | Canonical()->CanonicalAttach();
|
| 908 | 964 | }
|
| 909 | - return IPC_OK();
|
|
| 910 | 965 | }
|
| 911 | 966 | |
| 912 | 967 | void BrowsingContext::Detach(bool aFromIPC) {
|
| ... | ... | @@ -1743,40 +1798,6 @@ nsresult BrowsingContext::SetOriginAttributes(const OriginAttributes& aAttrs) { |
| 1743 | 1798 | return NS_OK;
|
| 1744 | 1799 | }
|
| 1745 | 1800 | |
| 1746 | -void BrowsingContext::AssertCoherentLoadContext() {
|
|
| 1747 | -#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
|
| 1748 | - // LoadContext should generally match our opener or parent.
|
|
| 1749 | - if (IsContent()) {
|
|
| 1750 | - if (RefPtr<BrowsingContext> opener = GetOpener()) {
|
|
| 1751 | - MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
|
|
| 1752 | - MOZ_DIAGNOSTIC_ASSERT(opener->mGroup == mGroup);
|
|
| 1753 | - MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteTabs == mUseRemoteTabs);
|
|
| 1754 | - MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteSubframes == mUseRemoteSubframes);
|
|
| 1755 | - MOZ_DIAGNOSTIC_ASSERT(opener->mPrivateBrowsingId == mPrivateBrowsingId);
|
|
| 1756 | - MOZ_DIAGNOSTIC_ASSERT(
|
|
| 1757 | - opener->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
|
| 1758 | - }
|
|
| 1759 | - }
|
|
| 1760 | - if (RefPtr<BrowsingContext> parent = GetParent()) {
|
|
| 1761 | - MOZ_DIAGNOSTIC_ASSERT(parent->mType == mType);
|
|
| 1762 | - MOZ_DIAGNOSTIC_ASSERT(parent->mGroup == mGroup);
|
|
| 1763 | - MOZ_DIAGNOSTIC_ASSERT(parent->mUseRemoteTabs == mUseRemoteTabs);
|
|
| 1764 | - MOZ_DIAGNOSTIC_ASSERT(parent->mUseRemoteSubframes == mUseRemoteSubframes);
|
|
| 1765 | - MOZ_DIAGNOSTIC_ASSERT(parent->mPrivateBrowsingId == mPrivateBrowsingId);
|
|
| 1766 | - MOZ_DIAGNOSTIC_ASSERT(
|
|
| 1767 | - parent->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
|
| 1768 | - }
|
|
| 1769 | - |
|
| 1770 | - // UseRemoteSubframes and UseRemoteTabs must match.
|
|
| 1771 | - MOZ_DIAGNOSTIC_ASSERT(
|
|
| 1772 | - !mUseRemoteSubframes || mUseRemoteTabs,
|
|
| 1773 | - "Cannot set useRemoteSubframes without also setting useRemoteTabs");
|
|
| 1774 | - |
|
| 1775 | - // Double-check OriginAttributes/Private Browsing
|
|
| 1776 | - AssertOriginAttributesMatchPrivateBrowsing();
|
|
| 1777 | -#endif
|
|
| 1778 | -}
|
|
| 1779 | - |
|
| 1780 | 1801 | void BrowsingContext::AssertOriginAttributesMatchPrivateBrowsing() {
|
| 1781 | 1802 | // Chrome browsing contexts must not have a private browsing OriginAttribute
|
| 1782 | 1803 | // Content browsing contexts must maintain the equality:
|
| ... | ... | @@ -971,7 +971,18 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { |
| 971 | 971 | bool aHasPostData);
|
| 972 | 972 | |
| 973 | 973 | private:
|
| 974 | - mozilla::ipc::IPCResult Attach(bool aFromIPC, ContentParent* aOriginProcess);
|
|
| 974 | + // Assert that this BrowsingContext is coherent relative to related
|
|
| 975 | + // BrowsingContexts. This will be run before the BrowsingContext is attached.
|
|
| 976 | + //
|
|
| 977 | + // A non-null string return value indicates that there was a coherency check
|
|
| 978 | + // failure, which will be handled with either a crash or IPC failure.
|
|
| 979 | + //
|
|
| 980 | + // If provided, `aOriginProcess` is the process which is responsible for the
|
|
| 981 | + // creation of this BrowsingContext.
|
|
| 982 | + [[nodiscard]] const char* BrowsingContextCoherencyChecks(
|
|
| 983 | + ContentParent* aOriginProcess);
|
|
| 984 | + |
|
| 985 | + void Attach(bool aFromIPC, ContentParent* aOriginProcess);
|
|
| 975 | 986 | |
| 976 | 987 | // Recomputes whether we can execute scripts in this BrowsingContext based on
|
| 977 | 988 | // the value of AllowJavascript() and whether scripts are allowed in the
|
| ... | ... | @@ -985,10 +996,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { |
| 985 | 996 | |
| 986 | 997 | void AssertOriginAttributesMatchPrivateBrowsing();
|
| 987 | 998 | |
| 988 | - // Assert that the BrowsingContext's LoadContext flags appear coherent
|
|
| 989 | - // relative to related BrowsingContexts.
|
|
| 990 | - void AssertCoherentLoadContext();
|
|
| 991 | - |
|
| 992 | 999 | friend class ::nsOuterWindowProxy;
|
| 993 | 1000 | friend class ::nsGlobalWindowOuter;
|
| 994 | 1001 | friend class WindowContext;
|
| ... | ... | @@ -6254,7 +6254,7 @@ already_AddRefed<nsIURI> nsDocShell::AttemptURIFixup( |
| 6254 | 6254 | |
| 6255 | 6255 | nsresult nsDocShell::FilterStatusForErrorPage(
|
| 6256 | 6256 | nsresult aStatus, nsIChannel* aChannel, uint32_t aLoadType,
|
| 6257 | - bool aIsTopFrame, bool aUseErrorPages, bool aIsInitialDocument,
|
|
| 6257 | + bool aIsTopFrame, bool aUseErrorPages,
|
|
| 6258 | 6258 | bool* aSkippedUnknownProtocolNavigation) {
|
| 6259 | 6259 | // Errors to be shown only on top-level frames
|
| 6260 | 6260 | if ((aStatus == NS_ERROR_UNKNOWN_HOST ||
|
| ... | ... | @@ -6298,18 +6298,10 @@ nsresult nsDocShell::FilterStatusForErrorPage( |
| 6298 | 6298 | |
| 6299 | 6299 | if (aStatus == NS_ERROR_UNKNOWN_PROTOCOL) {
|
| 6300 | 6300 | // For unknown protocols we only display an error if the load is triggered
|
| 6301 | - // by the browser itself, or we're replacing the initial document (and
|
|
| 6302 | - // nothing else). Showing the error for page-triggered navigations causes
|
|
| 6303 | - // annoying behavior for users, see bug 1528305.
|
|
| 6304 | - //
|
|
| 6305 | - // We could, maybe, try to detect if this is in response to some user
|
|
| 6306 | - // interaction (like clicking a link, or something else) and maybe show
|
|
| 6307 | - // the error page in that case. But this allows for ctrl+clicking and such
|
|
| 6308 | - // to see the error page.
|
|
| 6301 | + // by the browser itself. Showing the error for page-triggered navigations
|
|
| 6302 | + // causes annoying behavior for users, see bug 1528305.
|
|
| 6309 | 6303 | nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
|
| 6310 | - if (!info->TriggeringPrincipal()->IsSystemPrincipal() &&
|
|
| 6311 | - StaticPrefs::dom_no_unknown_protocol_error_enabled() &&
|
|
| 6312 | - !aIsInitialDocument) {
|
|
| 6304 | + if (!info->TriggeringPrincipal()->IsSystemPrincipal()) {
|
|
| 6313 | 6305 | if (aSkippedUnknownProtocolNavigation) {
|
| 6314 | 6306 | *aSkippedUnknownProtocolNavigation = true;
|
| 6315 | 6307 | }
|
| ... | ... | @@ -6459,12 +6451,9 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress, |
| 6459 | 6451 | aStatus == NS_ERROR_CONTENT_BLOCKED);
|
| 6460 | 6452 | UnblockEmbedderLoadEventForFailure(fireFrameErrorEvent);
|
| 6461 | 6453 | |
| 6462 | - bool isInitialDocument =
|
|
| 6463 | - !GetExtantDocument() || GetExtantDocument()->IsInitialDocument();
|
|
| 6464 | 6454 | bool skippedUnknownProtocolNavigation = false;
|
| 6465 | 6455 | aStatus = FilterStatusForErrorPage(aStatus, aChannel, mLoadType, isTopFrame,
|
| 6466 | 6456 | mBrowsingContext->GetUseErrorPages(),
|
| 6467 | - isInitialDocument,
|
|
| 6468 | 6457 | &skippedUnknownProtocolNavigation);
|
| 6469 | 6458 | hadErrorStatus = true;
|
| 6470 | 6459 | if (NS_FAILED(aStatus)) {
|
| ... | ... | @@ -464,7 +464,7 @@ class nsDocShell final : public nsDocLoader, |
| 464 | 464 | // navigation.
|
| 465 | 465 | static nsresult FilterStatusForErrorPage(
|
| 466 | 466 | nsresult aStatus, nsIChannel* aChannel, uint32_t aLoadType,
|
| 467 | - bool aIsTopFrame, bool aUseErrorPages, bool aIsInitialDocument,
|
|
| 467 | + bool aIsTopFrame, bool aUseErrorPages,
|
|
| 468 | 468 | bool* aSkippedUnknownProtocolNavigation = nullptr);
|
| 469 | 469 | |
| 470 | 470 | // Notify consumers of a search being loaded through the observer service:
|
| ... | ... | @@ -8266,7 +8266,7 @@ void Document::RuleAdded(StyleSheet& aSheet, css::Rule& aRule) { |
| 8266 | 8266 | }
|
| 8267 | 8267 | }
|
| 8268 | 8268 | |
| 8269 | -void Document::ImportRuleLoaded(dom::CSSImportRule& aRule, StyleSheet& aSheet) {
|
|
| 8269 | +void Document::ImportRuleLoaded(StyleSheet& aSheet) {
|
|
| 8270 | 8270 | if (aSheet.IsApplicable()) {
|
| 8271 | 8271 | ApplicableStylesChanged();
|
| 8272 | 8272 | }
|
| ... | ... | @@ -2135,7 +2135,7 @@ class Document : public nsINode, |
| 2135 | 2135 | void RuleAdded(StyleSheet&, css::Rule&);
|
| 2136 | 2136 | void RuleRemoved(StyleSheet&, css::Rule&);
|
| 2137 | 2137 | void SheetCloned(StyleSheet&) {}
|
| 2138 | - void ImportRuleLoaded(CSSImportRule&, StyleSheet&);
|
|
| 2138 | + void ImportRuleLoaded(StyleSheet&);
|
|
| 2139 | 2139 | |
| 2140 | 2140 | /**
|
| 2141 | 2141 | * Flush notifications for this document and its parent documents
|
| ... | ... | @@ -412,7 +412,7 @@ void ShadowRoot::RuleChanged(StyleSheet& aSheet, css::Rule*, |
| 412 | 412 | ApplicableRulesChanged();
|
| 413 | 413 | }
|
| 414 | 414 | |
| 415 | -void ShadowRoot::ImportRuleLoaded(CSSImportRule&, StyleSheet& aSheet) {
|
|
| 415 | +void ShadowRoot::ImportRuleLoaded(StyleSheet& aSheet) {
|
|
| 416 | 416 | if (mStyleRuleMap) {
|
| 417 | 417 | mStyleRuleMap->SheetAdded(aSheet);
|
| 418 | 418 | }
|
| ... | ... | @@ -86,7 +86,7 @@ class ShadowRoot final : public DocumentFragment, |
| 86 | 86 | void RuleAdded(StyleSheet&, css::Rule&);
|
| 87 | 87 | void RuleRemoved(StyleSheet&, css::Rule&);
|
| 88 | 88 | void RuleChanged(StyleSheet&, css::Rule*, StyleRuleChangeKind);
|
| 89 | - void ImportRuleLoaded(CSSImportRule&, StyleSheet&);
|
|
| 89 | + void ImportRuleLoaded(StyleSheet&);
|
|
| 90 | 90 | void SheetCloned(StyleSheet&);
|
| 91 | 91 | void StyleSheetApplicableStateChanged(StyleSheet&);
|
| 92 | 92 |
| ... | ... | @@ -2,7 +2,45 @@ |
| 2 | 2 | |
| 3 | 3 | let dialogObserverTopic = "common-dialog-loaded";
|
| 4 | 4 | |
| 5 | -function dialogObserver(subj, topic, data) {
|
|
| 5 | +function waitForButtonEnabledState(button) {
|
|
| 6 | + return new Promise(resolve => {
|
|
| 7 | + // Check if the button is already enabled (not disabled)
|
|
| 8 | + if (!button.disabled) {
|
|
| 9 | + resolve();
|
|
| 10 | + return;
|
|
| 11 | + }
|
|
| 12 | + |
|
| 13 | + // Create a MutationObserver instance
|
|
| 14 | + let win = button.ownerGlobal;
|
|
| 15 | + let { MutationObserver } = win;
|
|
| 16 | + const observer = new MutationObserver(mutationsList => {
|
|
| 17 | + for (const mutation of mutationsList) {
|
|
| 18 | + if (
|
|
| 19 | + mutation.type === "attributes" &&
|
|
| 20 | + mutation.attributeName === "disabled"
|
|
| 21 | + ) {
|
|
| 22 | + if (!button.disabled) {
|
|
| 23 | + // Resolve the promise when the button is enabled
|
|
| 24 | + observer.disconnect(); // Stop observing
|
|
| 25 | + resolve();
|
|
| 26 | + }
|
|
| 27 | + }
|
|
| 28 | + }
|
|
| 29 | + });
|
|
| 30 | + |
|
| 31 | + // Start observing the button for changes to the 'disabled' attribute
|
|
| 32 | + observer.observe(button, {
|
|
| 33 | + attributes: true,
|
|
| 34 | + attributeFilter: ["disabled"],
|
|
| 35 | + });
|
|
| 36 | + });
|
|
| 37 | +}
|
|
| 38 | + |
|
| 39 | +async function dialogObserver(subj) {
|
|
| 40 | + let dialog = subj.document.querySelector("dialog");
|
|
| 41 | + let acceptButton = dialog.getButton("accept");
|
|
| 42 | + await waitForButtonEnabledState(acceptButton);
|
|
| 43 | + |
|
| 6 | 44 | subj.document.querySelector("dialog").acceptDialog();
|
| 7 | 45 | sendAsyncMessage("promptAccepted");
|
| 8 | 46 | }
|
| ... | ... | @@ -744,6 +744,7 @@ class JS_PUBLIC_API JSAutoStructuredCloneBuffer { |
| 744 | 744 | #define JS_SCERR_WASM_NO_TRANSFER 6
|
| 745 | 745 | #define JS_SCERR_NOT_CLONABLE 7
|
| 746 | 746 | #define JS_SCERR_NOT_CLONABLE_WITH_COOP_COEP 8
|
| 747 | +#define JS_SCERR_TRANSFERABLE_TWICE 9
|
|
| 747 | 748 | |
| 748 | 749 | JS_PUBLIC_API bool JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1,
|
| 749 | 750 | uint32_t* p2);
|
| ... | ... | @@ -527,6 +527,7 @@ MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION, 0, JSEXN_ERR, "unsupported structured clo |
| 527 | 527 | MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})")
|
| 528 | 528 | MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone")
|
| 529 | 529 | MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone")
|
| 530 | +MSG_DEF(JSMSG_SC_TRANSFERABLE_TWICE, 0, JSEXN_TYPEERR, "structured clone cannot transfer twice")
|
|
| 530 | 531 | MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 0, JSEXN_TYPEERR, "unsupported type for structured data")
|
| 531 | 532 | MSG_DEF(JSMSG_SC_NOT_CLONABLE, 1, JSEXN_TYPEERR, "The {0} object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers will enable this in the future.")
|
| 532 | 533 | MSG_DEF(JSMSG_SC_NOT_CLONABLE_WITH_COOP_COEP, 1, JSEXN_TYPEERR, "The {0} object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers can be used to enable this.")
|
| ... | ... | @@ -160,6 +160,15 @@ function testMultiWithDeserializeReadTransferErrorHelper(g, BASE, desc) { |
| 160 | 160 | } catch (e) {
|
| 161 | 161 | assertEq(e.message.includes("invalid transferable"), true);
|
| 162 | 162 | }
|
| 163 | + |
|
| 164 | + try {
|
|
| 165 | + // This fails without logging anything, since the re-transfer will be caught
|
|
| 166 | + // by looking at its header before calling any callbacks.
|
|
| 167 | + let clone = deserialize(s);
|
|
| 168 | + } catch (e) {
|
|
| 169 | + assertEq(e.message.includes("cannot transfer twice"), true);
|
|
| 170 | + }
|
|
| 171 | + |
|
| 163 | 172 | s = null;
|
| 164 | 173 | gc();
|
| 165 | 174 | printTrace(arguments.callee.name, g, BASE, obj.log, "deserialize");
|
| ... | ... | @@ -170,6 +179,7 @@ function testMultiWithDeserializeReadTransferErrorHelper(g, BASE, desc) { |
| 170 | 179 | // which comes before the main reading. obj transfer data is now owned by its
|
| 171 | 180 | // clone. obj3 transfer data was not successfully handed over to a new object,
|
| 172 | 181 | // so it is still owned by the clone buffer and must be discarded with freeTransfer.
|
| 182 | + // 'F' means the data is freed.
|
|
| 173 | 183 | BASE + 3, "F",
|
| 174 | 184 | ], "deserialize " + desc);
|
| 175 | 185 | obj.log = null;
|
| ... | ... | @@ -29,8 +29,9 @@ using MPhiUseIteratorStack = |
| 29 | 29 | |
| 30 | 30 | // Look for Phi uses with a depth-first search. If any uses are found the stack
|
| 31 | 31 | // of MPhi instructions is returned in the |worklist| argument.
|
| 32 | -static bool DepthFirstSearchUse(MIRGenerator* mir,
|
|
| 33 | - MPhiUseIteratorStack& worklist, MPhi* phi) {
|
|
| 32 | +[[nodiscard]] static bool DepthFirstSearchUse(MIRGenerator* mir,
|
|
| 33 | + MPhiUseIteratorStack& worklist,
|
|
| 34 | + MPhi* phi) {
|
|
| 34 | 35 | // Push a Phi and the next use to iterate over in the worklist.
|
| 35 | 36 | auto push = [&worklist](MPhi* phi, MUseIterator use) -> bool {
|
| 36 | 37 | phi->setInWorklist();
|
| ... | ... | @@ -131,9 +132,9 @@ static bool DepthFirstSearchUse(MIRGenerator* mir, |
| 131 | 132 | return true;
|
| 132 | 133 | }
|
| 133 | 134 | |
| 134 | -static bool FlagPhiInputsAsImplicitlyUsed(MIRGenerator* mir, MBasicBlock* block,
|
|
| 135 | - MBasicBlock* succ,
|
|
| 136 | - MPhiUseIteratorStack& worklist) {
|
|
| 135 | +[[nodiscard]] static bool FlagPhiInputsAsImplicitlyUsed(
|
|
| 136 | + MIRGenerator* mir, MBasicBlock* block, MBasicBlock* succ,
|
|
| 137 | + MPhiUseIteratorStack& worklist) {
|
|
| 137 | 138 | // When removing an edge between 2 blocks, we might remove the ability of
|
| 138 | 139 | // later phases to figure out that the uses of a Phi should be considered as
|
| 139 | 140 | // a use of all its inputs. Thus we need to mark the Phi inputs as being
|
| ... | ... | @@ -265,7 +266,7 @@ static MInstructionIterator FindFirstInstructionAfterBail(MBasicBlock* block) { |
| 265 | 266 | |
| 266 | 267 | // Given an iterator pointing to the first removed instruction, mark
|
| 267 | 268 | // the operands of each removed instruction as having implicit uses.
|
| 268 | -static bool FlagOperandsAsImplicitlyUsedAfter(
|
|
| 269 | +[[nodiscard]] static bool FlagOperandsAsImplicitlyUsedAfter(
|
|
| 269 | 270 | MIRGenerator* mir, MBasicBlock* block, MInstructionIterator firstRemoved) {
|
| 270 | 271 | MOZ_ASSERT(firstRemoved->block() == block);
|
| 271 | 272 | |
| ... | ... | @@ -312,8 +313,8 @@ static bool FlagOperandsAsImplicitlyUsedAfter( |
| 312 | 313 | return true;
|
| 313 | 314 | }
|
| 314 | 315 | |
| 315 | -static bool FlagEntryResumePointOperands(MIRGenerator* mir,
|
|
| 316 | - MBasicBlock* block) {
|
|
| 316 | +[[nodiscard]] static bool FlagEntryResumePointOperands(MIRGenerator* mir,
|
|
| 317 | + MBasicBlock* block) {
|
|
| 317 | 318 | // Flag observable operands of the entry resume point as having implicit uses.
|
| 318 | 319 | MResumePoint* rp = block->entryResumePoint();
|
| 319 | 320 | while (rp) {
|
| ... | ... | @@ -334,8 +335,8 @@ static bool FlagEntryResumePointOperands(MIRGenerator* mir, |
| 334 | 335 | return true;
|
| 335 | 336 | }
|
| 336 | 337 | |
| 337 | -static bool FlagAllOperandsAsImplicitlyUsed(MIRGenerator* mir,
|
|
| 338 | - MBasicBlock* block) {
|
|
| 338 | +[[nodiscard]] static bool FlagAllOperandsAsImplicitlyUsed(MIRGenerator* mir,
|
|
| 339 | + MBasicBlock* block) {
|
|
| 339 | 340 | return FlagEntryResumePointOperands(mir, block) &&
|
| 340 | 341 | FlagOperandsAsImplicitlyUsedAfter(mir, block, block->begin());
|
| 341 | 342 | }
|
| ... | ... | @@ -420,12 +421,16 @@ bool jit::PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph) { |
| 420 | 421 | if (!block->isMarked()) {
|
| 421 | 422 | // If we are removing the block entirely, mark the operands of every
|
| 422 | 423 | // instruction as being implicitly used.
|
| 423 | - FlagAllOperandsAsImplicitlyUsed(mir, block);
|
|
| 424 | + if (!FlagAllOperandsAsImplicitlyUsed(mir, block)) {
|
|
| 425 | + return false;
|
|
| 426 | + }
|
|
| 424 | 427 | } else if (block->alwaysBails()) {
|
| 425 | 428 | // If we are only trimming instructions after a bail, only mark operands
|
| 426 | 429 | // of removed instructions.
|
| 427 | 430 | MInstructionIterator firstRemoved = FindFirstInstructionAfterBail(block);
|
| 428 | - FlagOperandsAsImplicitlyUsedAfter(mir, block, firstRemoved);
|
|
| 431 | + if (!FlagOperandsAsImplicitlyUsedAfter(mir, block, firstRemoved)) {
|
|
| 432 | + return false;
|
|
| 433 | + }
|
|
| 429 | 434 | }
|
| 430 | 435 | }
|
| 431 | 436 | |
| ... | ... | @@ -503,7 +508,8 @@ bool jit::PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph) { |
| 503 | 508 | return true;
|
| 504 | 509 | }
|
| 505 | 510 | |
| 506 | -static bool SplitCriticalEdgesForBlock(MIRGraph& graph, MBasicBlock* block) {
|
|
| 511 | +[[nodiscard]] static bool SplitCriticalEdgesForBlock(MIRGraph& graph,
|
|
| 512 | + MBasicBlock* block) {
|
|
| 507 | 513 | if (block->numSuccessors() < 2) {
|
| 508 | 514 | return true;
|
| 509 | 515 | }
|
| ... | ... | @@ -767,8 +773,8 @@ static bool IsDiamondPattern(MBasicBlock* initialBlock) { |
| 767 | 773 | return true;
|
| 768 | 774 | }
|
| 769 | 775 | |
| 770 | -static bool MaybeFoldDiamondConditionBlock(MIRGraph& graph,
|
|
| 771 | - MBasicBlock* initialBlock) {
|
|
| 776 | +[[nodiscard]] static bool MaybeFoldDiamondConditionBlock(
|
|
| 777 | + MIRGraph& graph, MBasicBlock* initialBlock) {
|
|
| 772 | 778 | MOZ_ASSERT(IsDiamondPattern(initialBlock));
|
| 773 | 779 | |
| 774 | 780 | // Optimize the MIR graph to improve the code generated for conditional
|
| ... | ... | @@ -936,8 +942,8 @@ static bool IsTrianglePattern(MBasicBlock* initialBlock) { |
| 936 | 942 | return false;
|
| 937 | 943 | }
|
| 938 | 944 | |
| 939 | -static bool MaybeFoldTriangleConditionBlock(MIRGraph& graph,
|
|
| 940 | - MBasicBlock* initialBlock) {
|
|
| 945 | +[[nodiscard]] static bool MaybeFoldTriangleConditionBlock(
|
|
| 946 | + MIRGraph& graph, MBasicBlock* initialBlock) {
|
|
| 941 | 947 | MOZ_ASSERT(IsTrianglePattern(initialBlock));
|
| 942 | 948 | |
| 943 | 949 | // Optimize the MIR graph to improve the code generated for boolean
|
| ... | ... | @@ -1089,8 +1095,8 @@ static bool MaybeFoldTriangleConditionBlock(MIRGraph& graph, |
| 1089 | 1095 | return true;
|
| 1090 | 1096 | }
|
| 1091 | 1097 | |
| 1092 | -static bool MaybeFoldConditionBlock(MIRGraph& graph,
|
|
| 1093 | - MBasicBlock* initialBlock) {
|
|
| 1098 | +[[nodiscard]] static bool MaybeFoldConditionBlock(MIRGraph& graph,
|
|
| 1099 | + MBasicBlock* initialBlock) {
|
|
| 1094 | 1100 | if (IsDiamondPattern(initialBlock)) {
|
| 1095 | 1101 | return MaybeFoldDiamondConditionBlock(graph, initialBlock);
|
| 1096 | 1102 | }
|
| ... | ... | @@ -1100,7 +1106,8 @@ static bool MaybeFoldConditionBlock(MIRGraph& graph, |
| 1100 | 1106 | return true;
|
| 1101 | 1107 | }
|
| 1102 | 1108 | |
| 1103 | -static bool MaybeFoldTestBlock(MIRGraph& graph, MBasicBlock* initialBlock) {
|
|
| 1109 | +[[nodiscard]] static bool MaybeFoldTestBlock(MIRGraph& graph,
|
|
| 1110 | + MBasicBlock* initialBlock) {
|
|
| 1104 | 1111 | // Handle test expressions on more than two inputs. For example
|
| 1105 | 1112 | // |if ((x > 10) && (y > 20) && (z > 30)) { ... }|, which results in the below
|
| 1106 | 1113 | // pattern.
|
| ... | ... | @@ -2752,7 +2759,9 @@ bool jit::RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, |
| 2752 | 2759 | continue;
|
| 2753 | 2760 | }
|
| 2754 | 2761 | |
| 2755 | - FlagAllOperandsAsImplicitlyUsed(mir, block);
|
|
| 2762 | + if (!FlagAllOperandsAsImplicitlyUsed(mir, block)) {
|
|
| 2763 | + return false;
|
|
| 2764 | + }
|
|
| 2756 | 2765 | }
|
| 2757 | 2766 | |
| 2758 | 2767 | // Find unmarked blocks and remove them.
|
| ... | ... | @@ -4003,8 +4012,8 @@ bool jit::EliminateRedundantShapeGuards(MIRGraph& graph) { |
| 4003 | 4012 | return true;
|
| 4004 | 4013 | }
|
| 4005 | 4014 | |
| 4006 | -static bool TryEliminateGCBarriersForAllocation(TempAllocator& alloc,
|
|
| 4007 | - MInstruction* allocation) {
|
|
| 4015 | +[[nodiscard]] static bool TryEliminateGCBarriersForAllocation(
|
|
| 4016 | + TempAllocator& alloc, MInstruction* allocation) {
|
|
| 4008 | 4017 | MOZ_ASSERT(allocation->type() == MIRType::Object);
|
| 4009 | 4018 | |
| 4010 | 4019 | JitSpew(JitSpew_RedundantGCBarriers, "Analyzing allocation %s",
|
| ... | ... | @@ -172,17 +172,25 @@ enum StructuredDataType : uint32_t { |
| 172 | 172 | |
| 173 | 173 | /*
|
| 174 | 174 | * Format of transfer map:
|
| 175 | - * <SCTAG_TRANSFER_MAP_HEADER, TransferableMapHeader(UNREAD|TRANSFERRED)>
|
|
| 176 | - * numTransferables (64 bits)
|
|
| 177 | - * array of:
|
|
| 178 | - * <SCTAG_TRANSFER_MAP_*, TransferableOwnership>
|
|
| 179 | - * pointer (64 bits)
|
|
| 180 | - * extraData (64 bits), eg byte length for ArrayBuffers
|
|
| 175 | + * - <SCTAG_TRANSFER_MAP_HEADER, UNREAD|TRANSFERRING|TRANSFERRED>
|
|
| 176 | + * - numTransferables (64 bits)
|
|
| 177 | + * - array of:
|
|
| 178 | + * - <SCTAG_TRANSFER_MAP_*, TransferableOwnership> pointer (64
|
|
| 179 | + * bits)
|
|
| 180 | + * - extraData (64 bits), eg byte length for ArrayBuffers
|
|
| 181 | + * - any data written for custom transferables
|
|
| 181 | 182 | */
|
| 182 | 183 | |
| 183 | 184 | // Data associated with an SCTAG_TRANSFER_MAP_HEADER that tells whether the
|
| 184 | -// contents have been read out yet or not.
|
|
| 185 | -enum TransferableMapHeader { SCTAG_TM_UNREAD = 0, SCTAG_TM_TRANSFERRED };
|
|
| 185 | +// contents have been read out yet or not. TRANSFERRING is for the case where we
|
|
| 186 | +// have started but not completed reading, which due to errors could mean that
|
|
| 187 | +// there are things still owned by the clone buffer that need to be released, so
|
|
| 188 | +// discarding should not just be skipped.
|
|
| 189 | +enum TransferableMapHeader {
|
|
| 190 | + SCTAG_TM_UNREAD = 0,
|
|
| 191 | + SCTAG_TM_TRANSFERRING,
|
|
| 192 | + SCTAG_TM_TRANSFERRED
|
|
| 193 | +};
|
|
| 186 | 194 | |
| 187 | 195 | static inline uint64_t PairToUInt64(uint32_t tag, uint32_t data) {
|
| 188 | 196 | return uint64_t(data) | (uint64_t(tag) << 32);
|
| ... | ... | @@ -693,6 +701,10 @@ static void ReportDataCloneError(JSContext* cx, |
| 693 | 701 | errorNumber = JSMSG_SC_SHMEM_TRANSFERABLE;
|
| 694 | 702 | break;
|
| 695 | 703 | |
| 704 | + case JS_SCERR_TRANSFERABLE_TWICE:
|
|
| 705 | + errorNumber = JSMSG_SC_TRANSFERABLE_TWICE;
|
|
| 706 | + break;
|
|
| 707 | + |
|
| 696 | 708 | case JS_SCERR_TYPED_ARRAY_DETACHED:
|
| 697 | 709 | errorNumber = JSMSG_TYPED_ARRAY_DETACHED;
|
| 698 | 710 | break;
|
| ... | ... | @@ -3209,11 +3221,21 @@ bool JSStructuredCloneReader::readTransferMap() { |
| 3209 | 3221 | return in.reportTruncated();
|
| 3210 | 3222 | }
|
| 3211 | 3223 | |
| 3224 | + auto transferState = static_cast<TransferableMapHeader>(data);
|
|
| 3225 | + |
|
| 3212 | 3226 | if (tag != SCTAG_TRANSFER_MAP_HEADER ||
|
| 3213 | - TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED) {
|
|
| 3227 | + transferState == SCTAG_TM_TRANSFERRED) {
|
|
| 3214 | 3228 | return true;
|
| 3215 | 3229 | }
|
| 3216 | 3230 | |
| 3231 | + if (transferState == SCTAG_TM_TRANSFERRING) {
|
|
| 3232 | + ReportDataCloneError(cx, callbacks, JS_SCERR_TRANSFERABLE_TWICE, closure);
|
|
| 3233 | + return false;
|
|
| 3234 | + }
|
|
| 3235 | + |
|
| 3236 | + headerPos.write(
|
|
| 3237 | + PairToUInt64(SCTAG_TRANSFER_MAP_HEADER, SCTAG_TM_TRANSFERRING));
|
|
| 3238 | + |
|
| 3217 | 3239 | uint64_t numTransferables;
|
| 3218 | 3240 | MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
|
| 3219 | 3241 | if (!in.read(&numTransferables)) {
|
| ... | ... | @@ -3329,7 +3351,7 @@ bool JSStructuredCloneReader::readTransferMap() { |
| 3329 | 3351 | #ifdef DEBUG
|
| 3330 | 3352 | SCInput::getPair(headerPos.peek(), &tag, &data);
|
| 3331 | 3353 | MOZ_ASSERT(tag == SCTAG_TRANSFER_MAP_HEADER);
|
| 3332 | - MOZ_ASSERT(TransferableMapHeader(data) != SCTAG_TM_TRANSFERRED);
|
|
| 3354 | + MOZ_ASSERT(TransferableMapHeader(data) == SCTAG_TM_TRANSFERRING);
|
|
| 3333 | 3355 | #endif
|
| 3334 | 3356 | headerPos.write(
|
| 3335 | 3357 | PairToUInt64(SCTAG_TRANSFER_MAP_HEADER, SCTAG_TM_TRANSFERRED));
|
| ... | ... | @@ -954,7 +954,7 @@ static OriginFlags ToOriginFlags(StyleOrigin aOrigin) { |
| 954 | 954 | }
|
| 955 | 955 | }
|
| 956 | 956 | |
| 957 | -void ServoStyleSet::ImportRuleLoaded(dom::CSSImportRule&, StyleSheet& aSheet) {
|
|
| 957 | +void ServoStyleSet::ImportRuleLoaded(StyleSheet& aSheet) {
|
|
| 958 | 958 | if (mStyleRuleMap) {
|
| 959 | 959 | mStyleRuleMap->SheetAdded(aSheet);
|
| 960 | 960 | }
|
| ... | ... | @@ -133,7 +133,7 @@ class ServoStyleSet { |
| 133 | 133 | void RuleRemoved(StyleSheet&, css::Rule&);
|
| 134 | 134 | void RuleChanged(StyleSheet&, css::Rule*, StyleRuleChangeKind);
|
| 135 | 135 | void SheetCloned(StyleSheet&);
|
| 136 | - void ImportRuleLoaded(dom::CSSImportRule&, StyleSheet&);
|
|
| 136 | + void ImportRuleLoaded(StyleSheet&);
|
|
| 137 | 137 | |
| 138 | 138 | // Runs style invalidation due to document state changes.
|
| 139 | 139 | void InvalidateStyleForDocumentStateChanges(
|
| ... | ... | @@ -836,15 +836,19 @@ StyleSheet::StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred, |
| 836 | 836 | if (!aSheet->GetParentSheet()) {
|
| 837 | 837 | return NS_OK; // ignore if sheet has been detached already
|
| 838 | 838 | }
|
| 839 | - MOZ_ASSERT(this == aSheet->GetParentSheet(),
|
|
| 840 | - "We are being notified of a sheet load for a sheet that is not "
|
|
| 841 | - "our child!");
|
|
| 839 | + MOZ_DIAGNOSTIC_ASSERT(this == aSheet->GetParentSheet(),
|
|
| 840 | + "We are being notified of a sheet load for a sheet "
|
|
| 841 | + "that is not our child!");
|
|
| 842 | 842 | if (NS_FAILED(aStatus)) {
|
| 843 | 843 | return NS_OK;
|
| 844 | 844 | }
|
| 845 | - |
|
| 846 | - MOZ_ASSERT(aSheet->GetOwnerRule());
|
|
| 847 | - NOTIFY(ImportRuleLoaded, (*aSheet->GetOwnerRule(), *aSheet));
|
|
| 845 | + // The assert below should hold if we stop triggering import loads for invalid
|
|
| 846 | + // insertRule() calls, see bug 1914106.
|
|
| 847 | + // MOZ_ASSERT(aSheet->GetOwnerRule());
|
|
| 848 | + if (!aSheet->GetOwnerRule()) {
|
|
| 849 | + return NS_OK;
|
|
| 850 | + }
|
|
| 851 | + NOTIFY(ImportRuleLoaded, (*aSheet));
|
|
| 848 | 852 | return NS_OK;
|
| 849 | 853 | }
|
| 850 | 854 |
| ... | ... | @@ -2316,15 +2316,9 @@ bool DocumentLoadListener::DocShellWillDisplayContent(nsresult aStatus) { |
| 2316 | 2316 | |
| 2317 | 2317 | auto* loadingContext = GetLoadingBrowsingContext();
|
| 2318 | 2318 | |
| 2319 | - bool isInitialDocument = true;
|
|
| 2320 | - if (WindowGlobalParent* currentWindow =
|
|
| 2321 | - loadingContext->GetCurrentWindowGlobal()) {
|
|
| 2322 | - isInitialDocument = currentWindow->IsInitialDocument();
|
|
| 2323 | - }
|
|
| 2324 | - |
|
| 2325 | 2319 | nsresult rv = nsDocShell::FilterStatusForErrorPage(
|
| 2326 | 2320 | aStatus, mChannel, mLoadStateLoadType, loadingContext->IsTop(),
|
| 2327 | - loadingContext->GetUseErrorPages(), isInitialDocument, nullptr);
|
|
| 2321 | + loadingContext->GetUseErrorPages(), nullptr);
|
|
| 2328 | 2322 | |
| 2329 | 2323 | if (NS_SUCCEEDED(rv)) {
|
| 2330 | 2324 | MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose,
|
| ... | ... | @@ -1042,15 +1042,6 @@ void WebTransportSessionProxy::NotifyDatagramReceived( |
| 1042 | 1042 | MutexAutoLock lock(mMutex);
|
| 1043 | 1043 | MOZ_ASSERT(mTarget->IsOnCurrentThread());
|
| 1044 | 1044 | |
| 1045 | - if (!mStopRequestCalled) {
|
|
| 1046 | - CopyableTArray<uint8_t> copied(aData);
|
|
| 1047 | - mPendingEvents.AppendElement(
|
|
| 1048 | - [self = RefPtr{this}, data = std::move(copied)]() mutable {
|
|
| 1049 | - self->NotifyDatagramReceived(std::move(data));
|
|
| 1050 | - });
|
|
| 1051 | - return;
|
|
| 1052 | - }
|
|
| 1053 | - |
|
| 1054 | 1045 | if (mState != WebTransportSessionProxyState::ACTIVE || !mListener) {
|
| 1055 | 1046 | return;
|
| 1056 | 1047 | }
|
| ... | ... | @@ -1066,6 +1057,15 @@ NS_IMETHODIMP WebTransportSessionProxy::OnDatagramReceivedInternal( |
| 1066 | 1057 | |
| 1067 | 1058 | {
|
| 1068 | 1059 | MutexAutoLock lock(mMutex);
|
| 1060 | + if (!mStopRequestCalled) {
|
|
| 1061 | + CopyableTArray<uint8_t> copied(aData);
|
|
| 1062 | + mPendingEvents.AppendElement(
|
|
| 1063 | + [self = RefPtr{this}, data = std::move(copied)]() mutable {
|
|
| 1064 | + self->OnDatagramReceivedInternal(std::move(data));
|
|
| 1065 | + });
|
|
| 1066 | + return NS_OK;
|
|
| 1067 | + }
|
|
| 1068 | + |
|
| 1069 | 1069 | if (!mTarget->IsOnCurrentThread()) {
|
| 1070 | 1070 | return mTarget->Dispatch(NS_NewRunnableFunction(
|
| 1071 | 1071 | "WebTransportSessionProxy::OnDatagramReceived",
|
| 1 | +<!doctype html>
|
|
| 2 | +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1914106">
|
|
| 3 | +<style></style>
|
|
| 4 | +<script>
|
|
| 5 | +document.querySelector("style").sheet.insertRule("@import url('data:text/css,:root{background:red}');html,body{/* random garbage */}");
|
|
| 6 | +</script> |