Bug 1267339 part 2. Push maintenance of the popup spam count down into the window watcher. r=mconley

This commit is contained in:
Boris Zbarsky 2016-10-20 16:52:38 -04:00
Родитель fe57b51a79
Коммит 9c68071fa2
6 изменённых файлов: 51 добавлений и 29 удалений

Просмотреть файл

@ -1502,9 +1502,20 @@ void
nsGlobalWindow::MaybeForgiveSpamCount() nsGlobalWindow::MaybeForgiveSpamCount()
{ {
if (IsOuterWindow() && if (IsOuterWindow() &&
IsPopupSpamWindow()) IsPopupSpamWindow()) {
{ SetIsPopupSpamWindow(false);
SetPopupSpamWindow(false); }
}
void
nsGlobalWindow::SetIsPopupSpamWindow(bool aIsPopupSpam)
{
MOZ_ASSERT(IsOuterWindow());
mIsPopupSpam = aIsPopupSpam;
if (aIsPopupSpam) {
++gOpenPopupSpamCount;
} else {
--gOpenPopupSpamCount; --gOpenPopupSpamCount;
NS_ASSERTION(gOpenPopupSpamCount >= 0, NS_ASSERTION(gOpenPopupSpamCount >= 0,
"Unbalanced decrement of gOpenPopupSpamCount"); "Unbalanced decrement of gOpenPopupSpamCount");
@ -11884,6 +11895,13 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch)); nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
NS_ENSURE_STATE(pwwatch); NS_ENSURE_STATE(pwwatch);
MOZ_ASSERT_IF(checkForPopup, abuseLevel < openAbused);
// At this point we should know for a fact that if checkForPopup then
// abuseLevel < openAbused, so we could just check for abuseLevel ==
// openControlled. But let's be defensive just in case and treat anything
// that fails the above assert as a spam popup too, if it ever happens.
bool isPopupSpamWindow = checkForPopup && (abuseLevel >= openControlled);
{ {
// Reset popup state while opening a window to prevent the // Reset popup state while opening a window to prevent the
// current state from being active the whole time a modal // current state from being active the whole time a modal
@ -11896,6 +11914,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr, rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr,
options_ptr, /* aCalledFromScript = */ true, options_ptr, /* aCalledFromScript = */ true,
aDialog, aNavigate, argv, aDialog, aNavigate, argv,
isPopupSpamWindow,
getter_AddRefs(domReturn)); getter_AddRefs(domReturn));
} else { } else {
// Force a system caller here so that the window watcher won't screw us // Force a system caller here so that the window watcher won't screw us
@ -11912,10 +11931,10 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
nojsapi.emplace(); nojsapi.emplace();
} }
rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr, rv = pwwatch->OpenWindow2(AsOuter(), url.get(), name_ptr,
options_ptr, /* aCalledFromScript = */ false, options_ptr, /* aCalledFromScript = */ false,
aDialog, aNavigate, aExtraArgument, aDialog, aNavigate, aExtraArgument,
isPopupSpamWindow,
getter_AddRefs(domReturn)); getter_AddRefs(domReturn));
} }
@ -11946,18 +11965,6 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
} }
} }
if (checkForPopup) {
MOZ_ASSERT(abuseLevel < openAbused, "Why didn't we take the early return?");
if (abuseLevel >= openControlled) {
nsGlobalWindow *opened = nsGlobalWindow::Cast(*aReturn);
if (!opened->IsPopupSpamWindow()) {
opened->SetPopupSpamWindow(true);
++gOpenPopupSpamCount;
}
}
}
return rv; return rv;
} }

Просмотреть файл

@ -1407,6 +1407,7 @@ protected:
// Get the parent, returns null if this is a toplevel window // Get the parent, returns null if this is a toplevel window
nsPIDOMWindowOuter* GetParentInternal(); nsPIDOMWindowOuter* GetParentInternal();
public:
// popup tracking // popup tracking
bool IsPopupSpamWindow() bool IsPopupSpamWindow()
{ {
@ -1417,17 +1418,10 @@ protected:
return GetOuterWindowInternal()->mIsPopupSpam; return GetOuterWindowInternal()->mIsPopupSpam;
} }
void SetPopupSpamWindow(bool aPopup) // Outer windows only.
{ void SetIsPopupSpamWindow(bool aIsPopupSpam);
if (IsInnerWindow() && !mOuterWindow) {
NS_ERROR("SetPopupSpamWindow() called on inner window w/o an outer!");
return;
}
GetOuterWindowInternal()->mIsPopupSpam = aPopup;
}
protected:
// Window Control Functions // Window Control Functions
// Outer windows only. // Outer windows only.

Просмотреть файл

@ -607,6 +607,8 @@ private:
nullptr, nullptr,
nullptr, nullptr,
false, false, true, nullptr, false, false, true, nullptr,
// Not a spammy popup; we got permission, we swear!
/* aIsPopupSpam = */ false,
getter_AddRefs(newWindow)); getter_AddRefs(newWindow));
nsCOMPtr<nsPIDOMWindowOuter> pwindow = nsPIDOMWindowOuter::From(newWindow); nsCOMPtr<nsPIDOMWindowOuter> pwindow = nsPIDOMWindowOuter::From(newWindow);
pwindow.forget(aWindow); pwindow.forget(aWindow);

Просмотреть файл

@ -55,6 +55,8 @@ interface nsPIWindowWatcher : nsISupports
@param aNavigate true if we should navigate the new window to the @param aNavigate true if we should navigate the new window to the
specified URL. specified URL.
@param aArgs Window argument @param aArgs Window argument
@param aIsPopupSpam true if the window is a popup spam window; used for
popup blocker internals.
@return the new window @return the new window
@note This method may examine the JS context stack for purposes of @note This method may examine the JS context stack for purposes of
@ -70,7 +72,8 @@ interface nsPIWindowWatcher : nsISupports
in boolean aCalledFromScript, in boolean aCalledFromScript,
in boolean aDialog, in boolean aDialog,
in boolean aNavigate, in boolean aNavigate,
in nsISupports aArgs); in nsISupports aArgs,
in boolean aIsPopupSpam);
/** /**
* Opens a new window using the most recent non-private browser * Opens a new window using the most recent non-private browser

Просмотреть файл

@ -19,6 +19,7 @@
#include "plstr.h" #include "plstr.h"
#include "nsDocShell.h" #include "nsDocShell.h"
#include "nsGlobalWindow.h"
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsIBrowserDOMWindow.h" #include "nsIBrowserDOMWindow.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
@ -371,7 +372,9 @@ nsWindowWatcher::OpenWindow(mozIDOMWindowProxy* aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures, return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
/* calledFromJS = */ false, dialog, /* calledFromJS = */ false, dialog,
/* navigate = */ true, argv, aResult); /* navigate = */ true, argv,
/* aIsPopupSpam = */ false,
aResult);
} }
struct SizeSpec struct SizeSpec
@ -434,6 +437,7 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent,
bool aDialog, bool aDialog,
bool aNavigate, bool aNavigate,
nsISupports* aArguments, nsISupports* aArguments,
bool aIsPopupSpam,
mozIDOMWindowProxy** aResult) mozIDOMWindowProxy** aResult)
{ {
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments); nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
@ -453,7 +457,7 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures, return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
aCalledFromScript, dialog, aCalledFromScript, dialog,
aNavigate, argv, aNavigate, argv, aIsPopupSpam,
aResult); aResult);
} }
@ -690,6 +694,7 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
bool aDialog, bool aDialog,
bool aNavigate, bool aNavigate,
nsIArray* aArgv, nsIArray* aArgv,
bool aIsPopupSpam,
mozIDOMWindowProxy** aResult) mozIDOMWindowProxy** aResult)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -1133,6 +1138,16 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent,
// SetInitialPrincipalToSubject is safe to call multiple times. // SetInitialPrincipalToSubject is safe to call multiple times.
if (newWindow) { if (newWindow) {
newWindow->SetInitialPrincipalToSubject(); newWindow->SetInitialPrincipalToSubject();
if (aIsPopupSpam) {
nsGlobalWindow* globalWin = nsGlobalWindow::Cast(newWindow);
MOZ_ASSERT(!globalWin->IsPopupSpamWindow(),
"Who marked it as popup spam already???");
if (!globalWin->IsPopupSpamWindow()) { // Make sure we don't mess up our
// counter even if the above
// assert fails.
globalWin->SetIsPopupSpamWindow(true);
}
}
} }
} }

Просмотреть файл

@ -84,6 +84,7 @@ protected:
bool aDialog, bool aDialog,
bool aNavigate, bool aNavigate,
nsIArray* aArgv, nsIArray* aArgv,
bool aIsPopupSpam,
mozIDOMWindowProxy** aResult); mozIDOMWindowProxy** aResult);
static nsresult URIfromURL(const char* aURL, static nsresult URIfromURL(const char* aURL,