ma1 pushed to branch tor-browser-115.16.0esr-13.5-1 at The Tor Project / Applications / Tor Browser

Commits:

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
    ... ... @@ -6307,7 +6307,7 @@ already_AddRefed<nsIURI> nsDocShell::AttemptURIFixup(
    6307 6307
     
    
    6308 6308
     nsresult nsDocShell::FilterStatusForErrorPage(
    
    6309 6309
         nsresult aStatus, nsIChannel* aChannel, uint32_t aLoadType,
    
    6310
    -    bool aIsTopFrame, bool aUseErrorPages, bool aIsInitialDocument,
    
    6310
    +    bool aIsTopFrame, bool aUseErrorPages,
    
    6311 6311
         bool* aSkippedUnknownProtocolNavigation) {
    
    6312 6312
       // Errors to be shown only on top-level frames
    
    6313 6313
       if ((aStatus == NS_ERROR_UNKNOWN_HOST ||
    
    ... ... @@ -6352,18 +6352,10 @@ nsresult nsDocShell::FilterStatusForErrorPage(
    6352 6352
     
    
    6353 6353
       if (aStatus == NS_ERROR_UNKNOWN_PROTOCOL) {
    
    6354 6354
         // For unknown protocols we only display an error if the load is triggered
    
    6355
    -    // by the browser itself, or we're replacing the initial document (and
    
    6356
    -    // nothing else). Showing the error for page-triggered navigations causes
    
    6357
    -    // annoying behavior for users, see bug 1528305.
    
    6358
    -    //
    
    6359
    -    // We could, maybe, try to detect if this is in response to some user
    
    6360
    -    // interaction (like clicking a link, or something else) and maybe show
    
    6361
    -    // the error page in that case. But this allows for ctrl+clicking and such
    
    6362
    -    // to see the error page.
    
    6355
    +    // by the browser itself. Showing the error for page-triggered navigations
    
    6356
    +    // causes annoying behavior for users, see bug 1528305.
    
    6363 6357
         nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
    
    6364
    -    if (!info->TriggeringPrincipal()->IsSystemPrincipal() &&
    
    6365
    -        StaticPrefs::dom_no_unknown_protocol_error_enabled() &&
    
    6366
    -        !aIsInitialDocument) {
    
    6358
    +    if (!info->TriggeringPrincipal()->IsSystemPrincipal()) {
    
    6367 6359
           if (aSkippedUnknownProtocolNavigation) {
    
    6368 6360
             *aSkippedUnknownProtocolNavigation = true;
    
    6369 6361
           }
    
    ... ... @@ -6513,12 +6505,9 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
    6513 6505
                                     aStatus == NS_ERROR_CONTENT_BLOCKED);
    
    6514 6506
         UnblockEmbedderLoadEventForFailure(fireFrameErrorEvent);
    
    6515 6507
     
    
    6516
    -    bool isInitialDocument =
    
    6517
    -        !GetExtantDocument() || GetExtantDocument()->IsInitialDocument();
    
    6518 6508
         bool skippedUnknownProtocolNavigation = false;
    
    6519 6509
         aStatus = FilterStatusForErrorPage(aStatus, aChannel, mLoadType, isTopFrame,
    
    6520 6510
                                            mBrowsingContext->GetUseErrorPages(),
    
    6521
    -                                       isInitialDocument,
    
    6522 6511
                                            &skippedUnknownProtocolNavigation);
    
    6523 6512
         hadErrorStatus = true;
    
    6524 6513
         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
    ... ... @@ -8326,7 +8326,7 @@ void Document::RuleAdded(StyleSheet& aSheet, css::Rule& aRule) {
    8326 8326
       }
    
    8327 8327
     }
    
    8328 8328
     
    
    8329
    -void Document::ImportRuleLoaded(dom::CSSImportRule& aRule, StyleSheet& aSheet) {
    
    8329
    +void Document::ImportRuleLoaded(StyleSheet& aSheet) {
    
    8330 8330
       if (aSheet.IsApplicable()) {
    
    8331 8331
         ApplicableStylesChanged();
    
    8332 8332
       }
    

  • 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>