Commits:
-
9ce14cc7
by Nika Layzell at 2024-10-01T00:53:35+02:00
Bug 1881037 - Part 1: Stop showing unknown protocol error pages for web-triggered loads, r=smaug,necko-reviewers,kershaw, a=dsmith
Differential Revision: https://phabricator.services.mozilla.com/D217495
-
63cf9662
by Paul Zuehlcke at 2024-10-01T00:53:37+02:00
Bug 1916659, a=diannaS
Original Revision: https://phabricator.services.mozilla.com/D222629
Differential Revision: https://phabricator.services.mozilla.com/D222934
-
32373e41
by André Bargull at 2024-10-01T00:53:38+02:00
Bug 1915249: Add more nodiscard. a=RyanVM
Original Revision: https://phabricator.services.mozilla.com/D220311
Differential Revision: https://phabricator.services.mozilla.com/D221663
-
e6dfa497
by Emilio Cobos Álvarez at 2024-10-01T00:53:40+02:00
Bug 1914106 - Deal with insertRule edge-case. r=jwatt a=RyanVM
When there's trailing garbage after an @import rule we throw, but we
still trigger the load (that's not great but not trivial to change).
Deal with that case before calling ImportRuleLoaded().
Differential Revision: https://phabricator.services.mozilla.com/D219783
-
35286ac0
by Steve Fink at 2024-10-01T00:53:42+02:00
Bug 1912471 - Disallow deserializing structured clone buffers with transferables more than once r=iain, a=dsmith
Differential Revision: https://phabricator.services.mozilla.com/D220644
-
bf0a17a2
by Nika Layzell at 2024-10-01T00:53:43+02:00
Bug 1911745 - Unify BrowsingContext flag coherency checks, r=mccr8
Previously these checks were largely diagnostic tools for finding bugs
in other code as it evolves. This unifies the checks a bit more and
makes them stronger for BrowsingContexts created over IPC, providing a
place for more coherency checks to be added in the future.
Differential Revision: https://phabricator.services.mozilla.com/D218860
-
bf6b766b
by Kershaw Chang at 2024-10-01T00:53:46+02:00
Bug 1907726 - Make sure WebTransportSessionProxy::NotifyDatagramReceived is called after OnStopRequest, a=RyanVM
The crash occurs because WebTransportSessionProxy::OnDatagramReceivedInternal is called before WebTransportSessionProxy::OnStopRequest.
When this happens, WebTransportSessionProxy::mTarget is the main thread, so a task is dispatched to the main thread. This causes WebTransportSessionProxy::NotifyDatagramReceived to be called on the main thread.
If WebTransportSessionProxy::NotifyDatagramReceived is invoked while WebTransportSessionProxy::mStopRequestCalled is true, it can lead to OnDatagramReceived being called on the main thread (instead of the socket thread), resulting in a crash.
Original Revision: https://phabricator.services.mozilla.com/D220013
Differential Revision: https://phabricator.services.mozilla.com/D221661
22 changed files:
Changes:
browser/base/content/test/tabPrompts/browser_confirmFolderUpload.js
... |
... |
@@ -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, {
|
browser/components/prompts/PromptCollection.sys.mjs
... |
... |
@@ -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,
|
docshell/base/BrowsingContext.cpp
... |
... |
@@ -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:
|
docshell/base/BrowsingContext.h
... |
... |
@@ -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;
|
docshell/base/nsDocShell.cpp
... |
... |
@@ -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)) {
|
docshell/base/nsDocShell.h
... |
... |
@@ -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:
|
dom/base/Document.cpp
... |
... |
@@ -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
|
}
|
dom/base/Document.h
... |
... |
@@ -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
|
dom/base/ShadowRoot.cpp
... |
... |
@@ -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
|
}
|
dom/base/ShadowRoot.h
... |
... |
@@ -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
|
|
dom/filesystem/tests/script_promptHandler.js
... |
... |
@@ -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
|
}
|
js/public/StructuredClone.h
... |
... |
@@ -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);
|
js/public/friend/ErrorNumbers.msg
... |
... |
@@ -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.")
|
js/src/jit-test/tests/structured-clone/transferable-cleanup.js
... |
... |
@@ -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;
|
js/src/jit/IonAnalysis.cpp
... |
... |
@@ -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",
|
js/src/vm/StructuredClone.cpp
... |
... |
@@ -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));
|
layout/style/ServoStyleSet.cpp
... |
... |
@@ -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
|
}
|
layout/style/ServoStyleSet.h
... |
... |
@@ -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(
|
layout/style/StyleSheet.cpp
... |
... |
@@ -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
|
|
netwerk/ipc/DocumentLoadListener.cpp
... |
... |
@@ -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,
|
netwerk/protocol/webtransport/WebTransportSessionProxy.cpp
... |
... |
@@ -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",
|
testing/web-platform/tests/css/cssom/insertRule-import-trailing-garbage-crash.html
|
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> |
|