diff --git a/docshell/test/navigation/frame_recursive_dynamic.html b/docshell/test/navigation/frame_recursive_dynamic.html new file mode 100644 index 00000000000000..8a9157f012f9a7 --- /dev/null +++ b/docshell/test/navigation/frame_recursive_dynamic.html @@ -0,0 +1,8 @@ + diff --git a/docshell/test/navigation/mochitest.toml b/docshell/test/navigation/mochitest.toml index 811ad7c89ddbb0..2176e4f82b5b64 100644 --- a/docshell/test/navigation/mochitest.toml +++ b/docshell/test/navigation/mochitest.toml @@ -86,6 +86,7 @@ support-files = [ "frame_5_out_of_6.html", "frame_6_out_of_6.html", "frame_recursive.html", + "frame_recursive_dynamic.html", "object_recursive_load.html", "file_nested_srcdoc.html", ] diff --git a/docshell/test/navigation/test_recursive_frames.html b/docshell/test/navigation/test_recursive_frames.html index 3ccc09dd14c4ea..60c135c00c9a9f 100644 --- a/docshell/test/navigation/test_recursive_frames.html +++ b/docshell/test/navigation/test_recursive_frames.html @@ -97,10 +97,20 @@ "about:srcdoc", ], }, + { // too many recursive dynamically created iframes + frameId: "dynamicrecursive", + expectedLocations: [ + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com/tests/docshell/test/navigation/frame_recursive_dynamic.html", + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com/tests/docshell/test/navigation/frame_recursive_dynamic.html", + "about:blank" + ], + }, ]; async function checkRecursiveLoad(level) { - let el = content.document.getElementById("static"); + let el = content.document.getElementById("static") || content.document.getElementById("dynamic"); let documentURI = await SpecialPowers.spawn( el, [], @@ -152,7 +162,6 @@ ); } }); -
@@ -160,8 +169,9 @@ - + +
diff --git a/dom/tests/browser/browser_hasbeforeunload.js b/dom/tests/browser/browser_hasbeforeunload.js index de86a1ea7a1cc8..0344ae9761cd93 100644 --- a/dom/tests/browser/browser_hasbeforeunload.js +++ b/dom/tests/browser/browser_hasbeforeunload.js @@ -154,7 +154,11 @@ function navigateSubframe(browser, url, frameDepth = 0) { name: "Navigate", url, }); - let subframeLoad = BrowserTestUtils.browserLoaded(browser, true); + let subframeLoad = BrowserTestUtils.browserLoaded( + browser, + true, + new URL(url).href + ); return Promise.all([navigatePromise, subframeLoad]); } @@ -368,7 +372,7 @@ async function prepareSubframes(browser, options) { [{ options, PAGE_URL }], async function (args) { let { options: allSubframeOptions, PAGE_URL: contentPageURL } = args; - function loadBeforeUnloadHelper(doc, subframeOptions) { + function loadBeforeUnloadHelper(doc, url, subframeOptions) { let subframe = doc.getElementById("subframe"); subframe.remove(); if (subframeOptions.sandboxAttributes === null) { @@ -377,15 +381,23 @@ async function prepareSubframes(browser, options) { subframe.setAttribute("sandbox", subframeOptions.sandboxAttributes); } doc.body.appendChild(subframe); - subframe.contentWindow.location = contentPageURL; + subframe.contentWindow.location = url; return ContentTaskUtils.waitForEvent(subframe, "load").then(() => { return subframe.contentDocument; }); } let currentDoc = content.document; + let depth = 1; for (let subframeOptions of allSubframeOptions) { - currentDoc = await loadBeforeUnloadHelper(currentDoc, subframeOptions); + // Circumvent recursive load checks. + let url = new URL(contentPageURL); + url.search = `depth=${depth++}`; + currentDoc = await loadBeforeUnloadHelper( + currentDoc, + url.href, + subframeOptions + ); } } ); diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 8e13711a33cfec..3471b7e5cfe2b8 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -655,12 +655,10 @@ auto DocumentLoadListener::Open(nsDocShellLoadState* aLoadState, mHTTPSFirstDowngradeData = aLoadState->GetHttpsFirstDowngradeData().forget(); // Check for infinite recursive object or iframe loads - if (aLoadState->OriginalFrameSrc() || !mIsDocumentLoad) { - if (!CheckRecursiveLoad(loadingContext, aLoadState, mIsDocumentLoad)) { - *aRv = NS_ERROR_RECURSIVE_DOCUMENT_LOAD; - mParentChannelListener = nullptr; - return nullptr; - } + if (!CheckRecursiveLoad(loadingContext, aLoadState, mIsDocumentLoad)) { + *aRv = NS_ERROR_RECURSIVE_DOCUMENT_LOAD; + mParentChannelListener = nullptr; + return nullptr; } auto* documentContext = GetDocumentBrowsingContext();