diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index a58dd5e85d0..8ba7ed30bf4 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -67,12 +67,20 @@ #include "nsHTMLAtoms.h" #include "nsINameSpaceManager.h" +// Bug 136580: Limit to the number of nested content frames that can have the +// same URL. This is to stop content that is recursively loading +// itself. +#define MAX_SAME_URL_CONTENT_FRAMES 3 // Bug 8065: Limit content frame depth to some reasonable level. This // does not count chrome frames when determining depth, nor does it // prevent chrome recursion. #define MAX_DEPTH_CONTENT_FRAMES 8 +// Bug 136580: Limit to the number of nested content frames that can have the +// same URL. This is to stop content that is recursively loading +// itself. +#define MAX_SAME_URL_CONTENT_FRAMES 3 class nsFrameLoader : public nsIFrameLoader { @@ -224,6 +232,41 @@ nsFrameLoader::LoadFrame() return rv; // We're not } + + // Bug 136580: Check for recursive frame loading + PRInt32 matchCount = 0; + nsCOMPtr treeItem = do_QueryInterface(mDocShell); + nsCOMPtr parentAsItem; + treeItem->GetParent(getter_AddRefs(parentAsItem)); + while (parentAsItem) { + // Only interested in checking for recursion in content + PRInt32 parentType; + parentAsItem->GetItemType(&parentType); + if (parentType != nsIDocShellTreeItem::typeContent) { + break; // Not content + } + // Check the parent URI with the URI we're loading + nsCOMPtr parentAsNav(do_QueryInterface(parentAsItem)); + if (parentAsNav) { + // Does the URI match the one we're about to load? + nsCOMPtr parentURI; + parentAsNav->GetCurrentURI(getter_AddRefs(parentURI)); + if (parentURI) { + PRBool matches = PR_FALSE; + parentURI->Equals(uri, &matches); + if (matches) { + matchCount++; + if (matchCount >= MAX_SAME_URL_CONTENT_FRAMES) { + NS_WARNING("Too many nested content frames have the same url (recursion?) so giving up"); + return NS_ERROR_UNEXPECTED; + } + } + } + } + nsIDocShellTreeItem* temp = parentAsItem; + temp->GetParent(getter_AddRefs(parentAsItem)); + } + // Kick off the load... rv = mDocShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE); @@ -323,7 +366,7 @@ nsFrameLoader::EnsureDocShell() while (parentAsItem) { ++depth; - if (MAX_DEPTH_CONTENT_FRAMES < depth) { + if (depth >= MAX_DEPTH_CONTENT_FRAMES) { NS_WARNING("Too many nested content frames so giving up"); return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?)