Fix for bug 838692 - Navigating named targets from sandboxed iframes (r=smaug)

This commit is contained in:
Bob Owen 2013-04-24 18:13:25 +01:00
parent c030b1e599
commit 1f4d023302
2 changed files with 32 additions and 16 deletions

View File

@ -3087,14 +3087,18 @@ nsDocShell::FindItemWithName(const PRUnichar * aName,
if (!*aName) if (!*aName)
return NS_OK; return NS_OK;
if (!aRequestor) if (aRequestor) {
{ // If aRequestor is not null we don't need to check special names, so
nsCOMPtr<nsIDocShellTreeItem> foundItem; // just hand straight off to the search by actual name function.
return DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
_retval);
} else {
// This is the entry point into the target-finding algorithm. Check // This is the entry point into the target-finding algorithm. Check
// for special names. This should only be done once, hence the check // for special names. This should only be done once, hence the check
// for a null aRequestor. // for a null aRequestor.
nsCOMPtr<nsIDocShellTreeItem> foundItem;
nsDependentString name(aName); nsDependentString name(aName);
if (name.LowerCaseEqualsLiteral("_self")) { if (name.LowerCaseEqualsLiteral("_self")) {
foundItem = this; foundItem = this;
@ -3143,16 +3147,19 @@ nsDocShell::FindItemWithName(const PRUnichar * aName,
// a new window? // a new window?
} }
#endif #endif
} else {
// Do the search for item by an actual name.
DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
getter_AddRefs(foundItem));
} }
if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) { if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
foundItem = nullptr; foundItem = nullptr;
} }
// DoFindItemWithName only returns active items and we don't check if
// the item is active for the special cases.
if (foundItem) { if (foundItem) {
// We return foundItem here even if it's not an active
// item since all the names we've dealt with so far are
// special cases that we won't bother looking for further.
// If our document is sandboxed, we need to do some extra checks. // If our document is sandboxed, we need to do some extra checks.
uint32_t sandboxFlags = 0; uint32_t sandboxFlags = 0;
@ -3174,17 +3181,14 @@ nsDocShell::FindItemWithName(const PRUnichar * aName,
bool isAncestor = false; bool isAncestor = false;
nsCOMPtr<nsIDocShellTreeItem> parentAsItem; nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
GetSameTypeParent(getter_AddRefs(parentAsItem)); foundItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
while (parentAsItem) { while (parentAsItem) {
nsCOMPtr<nsIDocShellTreeItem> tmp; if (parentAsItem == selfAsItem) {
parentAsItem->GetParent(getter_AddRefs(tmp));
if (tmp && tmp == selfAsItem) {
isAncestor = true; isAncestor = true;
break; break;
} }
parentAsItem = tmp; nsCOMPtr<nsIDocShellTreeItem> tmp = parentAsItem;
tmp->GetSameTypeParent(getter_AddRefs(parentAsItem));
} }
if (!isAncestor) { if (!isAncestor) {
@ -3212,12 +3216,17 @@ nsDocShell::FindItemWithName(const PRUnichar * aName,
} }
foundItem.swap(*_retval); foundItem.swap(*_retval);
return NS_OK;
} }
return NS_OK;
} }
}
// Keep looking nsresult
nsDocShell::DoFindItemWithName(const PRUnichar* aName,
nsISupports* aRequestor,
nsIDocShellTreeItem* aOriginalRequestor,
nsIDocShellTreeItem** _retval)
{
// First we check our name. // First we check our name.
if (mName.Equals(aName) && ItemIsActive(this) && if (mName.Equals(aName) && ItemIsActive(this) &&
CanAccessItem(this, aOriginalRequestor)) { CanAccessItem(this, aOriginalRequestor)) {

View File

@ -874,6 +874,13 @@ private:
int32_t mParentCharsetSource; int32_t mParentCharsetSource;
nsCString mOriginalUriString; nsCString mOriginalUriString;
// Separate function to do the actual name (i.e. not _top, _self etc.)
// searching for FindItemWithName.
nsresult DoFindItemWithName(const PRUnichar* aName,
nsISupports* aRequestor,
nsIDocShellTreeItem* aOriginalRequestor,
nsIDocShellTreeItem** _retval);
#ifdef DEBUG #ifdef DEBUG
// We're counting the number of |nsDocShells| to help find leaks // We're counting the number of |nsDocShells| to help find leaks
static unsigned long gNumberOfDocShells; static unsigned long gNumberOfDocShells;