Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  browser_bug2011921.js

  Sprache: JAVA
 

"use strict";

// Bug 2011921 - Crash in BrowsingContextWebProgress::ContextReplaced
//
// When MaybeCheckUnloadingIsCanceled takes the async path for a BFCache
// navigation (because the current page has a beforeunload handler and the
// Navigation API is enabled), and another navigation replaces the browsing
// context before the callback fires, the callback calls FinishRestore →
// ReplacedBy on the already-replaced context whose mWebProgress is null.
//
// The race: two rapid back navigations both enter LoadURIs. The first takes
// the async MaybeCheckUnloadingIsCanceled path. The second may complete
// its BFCache restore (calling ReplacedBy and moving mWebProgress) before
// the first callback fires. When the first callback fires, it reaches
// FinishRestore at the unguarded direct call in MaybeLoadBFCache (which
// lacks the IsReplaced() check present in the PermitUnload callback), and
// dereferences the null mWebProgress.

const TEST_PATH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

add_task(async function test_rapid_back_with_beforeunload_bfcache() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["fission.bfcacheInParent"true],
      // Navigation API must be enabled for MaybeCheckUnloadingIsCanceled.
      ["dom.navigation.webidl.enabled"true],
      // Keep the default (true) for this pref so that beforeunload dialogs
      // are suppressed in automated tests (no user interaction), while the
      // beforeunload handler is still registered and NeedsBeforeUnload()
      // returns true.
      ["dom.require_user_interaction_for_beforeunload"true],
    ],
  });

  // Run multiple iterations to increase the probability of hitting the race
  // window. The race depends on IPC message ordering between the beforeunload
  // check round-trip and the second navigation's HistoryGo arrival.
  const ITERATIONS = 10;

  for (let i = 0; i < ITERATIONS; i++) {
    info(`--- Iteration ${i + 1}/${ITERATIONS} ---`);

    let tab = await BrowserTestUtils.openNewForegroundTab(
      gBrowser,
      TEST_PATH + "dummy_page.html?page1"
    );
    let browser = tab.linkedBrowser;

    // Navigate to page2 (page1 goes to BFCache).
    BrowserTestUtils.startLoadingURIString(
      browser,
      TEST_PATH + "dummy_page.html?page2"
    );
    await BrowserTestUtils.browserLoaded(browser);

    // Navigate to page3 (page2 goes to BFCache).
    BrowserTestUtils.startLoadingURIString(
      browser,
      TEST_PATH + "dummy_page.html?page3"
    );
    await BrowserTestUtils.browserLoaded(browser);

    // Register a beforeunload handler on the current page. This makes
    // NeedsBeforeUnload() return true on the WindowGlobalParent, which causes
    // MaybeCheckUnloadingIsCanceled to take the async path when navigating
    // away. With dom.require_user_interaction_for_beforeunload = true and no
    // user interaction, no dialog is shown but the async IPC round-trip still
    // occurs.
    await SpecialPowers.spawn(browser, [], () => {
      content.addEventListener("beforeunload", e => {
        e.preventDefault();
      });
    });

    // Strategy: trigger two back navigations from the content process,
    // separated by one event loop turn so they get different history epochs
    // (the ChildSHistory epoch increments via a dispatched runnable between
    // event turns). Both navigations proceed to the parent's HistoryGo →
    // LoadURIs. The first enters the async MaybeCheckUnloadingIsCanceled
    // path. The second arrives while the first is pending.
    SpecialPowers.spawn(browser, [], () => {
      content.history.back();
      content.setTimeout(() => {
        content.history.back();
      }, 0);
    });

    // Wait for async callbacks and IPC round-trips to settle.
    // The crash, if triggered, happens during this window.
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    await new Promise(resolve => setTimeout(resolve, 1000));

    // Try a different strategy too: trigger goBack from the parent process
    // while a content-initiated back navigation may still be in flight.
    // First, set up fresh history again.
    BrowserTestUtils.startLoadingURIString(
      browser,
      TEST_PATH + "dummy_page.html?page4"
    );
    await BrowserTestUtils.browserLoaded(browser);

    BrowserTestUtils.startLoadingURIString(
      browser,
      TEST_PATH + "dummy_page.html?page5"
    );
    await BrowserTestUtils.browserLoaded(browser);

    await SpecialPowers.spawn(browser, [], () => {
      content.addEventListener("beforeunload", e => {
        e.preventDefault();
      });
    });

    // Trigger back from content and parent nearly simultaneously.
    // These use different IPC paths, potentially avoiding epoch dedup.
    SpecialPowers.spawn(browser, [], () => {
      content.history.back();
    });
    browser.goBack();

    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    await new Promise(resolve => setTimeout(resolve, 1000));

    BrowserTestUtils.removeTab(tab);
  }

  ok(true"Completed all iterations without crashing (bug 2011921)");
});

Messung V0.5 in Prozent
C=91 H=97 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002