зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1720926 - Rate limit calls to location.reload. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D128636
This commit is contained in:
Родитель
75d192487c
Коммит
a6a4f92ea0
|
@ -29,6 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1314912
|
|||
"history.back": () => win.history.back(),
|
||||
"history.forward": () => win.history.forward(),
|
||||
"history.go": () => win.history.go(-1),
|
||||
"location.href": () => win.location.href = win.location.href + "",
|
||||
"location.hash": () => win.location.hash = inc++,
|
||||
"location.host": () => win.location.host = win.location.host + "",
|
||||
"location.hostname": () => win.location.hostname = win.location.hostname + "",
|
||||
|
@ -36,6 +37,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1314912
|
|||
"location.port": () => win.location.port = win.location.port + "",
|
||||
"location.protocol": () => win.location.protocol = win.location.protocol + "",
|
||||
"location.search": () => win.location.search = win.location.search + "",
|
||||
"location.assign": () => win.location.assign(`${win.location.href}#${inc++}`),
|
||||
"location.replace": () => win.location.replace(`${win.location.href}#${inc++}`),
|
||||
"location.reload": () => win.location.reload(),
|
||||
});
|
||||
|
||||
async function test() {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/ServoStyleConsts.h"
|
||||
|
@ -548,7 +549,13 @@ void Location::SetSearch(const nsAString& aSearch,
|
|||
SetURI(uri, aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
void Location::Reload(bool aForceget, ErrorResult& aRv) {
|
||||
void Location::Reload(bool aForceget, nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv) {
|
||||
if (!CallerSubsumes(&aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell(GetDocShell());
|
||||
if (!docShell) {
|
||||
return aRv.Throw(NS_ERROR_FAILURE);
|
||||
|
@ -574,6 +581,21 @@ void Location::Reload(bool aForceget, ErrorResult& aRv) {
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<BrowsingContext> bc = GetBrowsingContext();
|
||||
if (!bc || bc->IsDiscarded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallerType callerType = aSubjectPrincipal.IsSystemPrincipal()
|
||||
? CallerType::System
|
||||
: CallerType::NonSystem;
|
||||
|
||||
nsresult rv = bc->CheckLocationChangeRateLimit(callerType);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t reloadFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
|
||||
|
||||
if (aForceget) {
|
||||
|
@ -581,7 +603,7 @@ void Location::Reload(bool aForceget, ErrorResult& aRv) {
|
|||
nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
|
||||
}
|
||||
|
||||
nsresult rv = nsDocShell::Cast(docShell)->Reload(reloadFlags);
|
||||
rv = nsDocShell::Cast(docShell)->Reload(reloadFlags);
|
||||
if (NS_FAILED(rv) && rv != NS_BINDING_ABORTED) {
|
||||
// NS_BINDING_ABORTED is returned when we attempt to reload a POST result
|
||||
// and the user says no at the "do you want to reload?" prompt. Don't
|
||||
|
|
|
@ -43,14 +43,7 @@ class Location final : public nsISupports,
|
|||
ErrorResult& aError);
|
||||
|
||||
void Reload(bool aForceget, nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError) {
|
||||
if (!CallerSubsumes(&aSubjectPrincipal)) {
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
Reload(aForceget, aError);
|
||||
}
|
||||
ErrorResult& aError);
|
||||
|
||||
void GetHref(nsAString& aHref, nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError) {
|
||||
|
@ -118,8 +111,6 @@ class Location final : public nsISupports,
|
|||
|
||||
nsresult ToString(nsAString& aString) { return GetHref(aString); }
|
||||
|
||||
void Reload(bool aForceget, ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
virtual ~Location();
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mozilla/dom/Location.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -137,7 +138,8 @@ void nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
|||
aResult.setNull();
|
||||
}
|
||||
|
||||
void nsHistory::Go(int32_t aDelta, CallerType aCallerType, ErrorResult& aRv) {
|
||||
void nsHistory::Go(int32_t aDelta, nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv) {
|
||||
LOG(("nsHistory::Go(%d)", aDelta));
|
||||
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !win->HasActiveDocument()) {
|
||||
|
@ -149,7 +151,7 @@ void nsHistory::Go(int32_t aDelta, CallerType aCallerType, ErrorResult& aRv) {
|
|||
// "When the go(delta) method is invoked, if delta is zero, the user agent
|
||||
// must act as if the location.reload() method was called instead."
|
||||
RefPtr<Location> location = win->Location();
|
||||
return location->Reload(false, aRv);
|
||||
return location->Reload(false, aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
RefPtr<ChildSHistory> session_history = GetSessionHistory();
|
||||
|
@ -163,12 +165,16 @@ void nsHistory::Go(int32_t aDelta, CallerType aCallerType, ErrorResult& aRv) {
|
|||
? win->GetWindowContext()->HasValidTransientUserGestureActivation()
|
||||
: false;
|
||||
|
||||
CallerType callerType = aSubjectPrincipal.IsSystemPrincipal()
|
||||
? CallerType::System
|
||||
: CallerType::NonSystem;
|
||||
|
||||
// Ignore the return value from Go(), since returning errors from Go() can
|
||||
// lead to exceptions and a possible leak of history length
|
||||
// AsyncGo throws if we hit the location change rate limit.
|
||||
if (StaticPrefs::dom_window_history_async()) {
|
||||
session_history->AsyncGo(aDelta, /* aRequireUserInteraction = */ false,
|
||||
userActivation, aCallerType, aRv);
|
||||
userActivation, callerType, aRv);
|
||||
} else {
|
||||
session_history->Go(aDelta, /* aRequireUserInteraction = */ false,
|
||||
userActivation, IgnoreErrors());
|
||||
|
|
|
@ -45,7 +45,7 @@ class nsHistory final : public nsISupports, public nsWrapperCache {
|
|||
mozilla::ErrorResult& aRv);
|
||||
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||
mozilla::ErrorResult& aRv) const;
|
||||
void Go(int32_t aDelta, mozilla::dom::CallerType aCallerType,
|
||||
void Go(int32_t aDelta, nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void Back(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
|
||||
void Forward(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
|
||||
|
|
|
@ -21,7 +21,7 @@ interface History {
|
|||
attribute ScrollRestoration scrollRestoration;
|
||||
[Throws]
|
||||
readonly attribute any state;
|
||||
[Throws, NeedsCallerType]
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void go(optional long delta = 0);
|
||||
[Throws, NeedsCallerType]
|
||||
void back();
|
||||
|
|
Загрузка…
Ссылка в новой задаче