mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 11:57:32 +09:00
Issue #1688 - Add flood guard to state change logic.
This commit is contained in:
parent
d6c1cc53ba
commit
51c4b1838c
3 changed files with 56 additions and 0 deletions
|
|
@ -820,6 +820,8 @@ nsDocShell::nsDocShell()
|
||||||
, mParentCharsetSource(0)
|
, mParentCharsetSource(0)
|
||||||
, mJSRunToCompletionDepth(0)
|
, mJSRunToCompletionDepth(0)
|
||||||
, mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE)
|
, mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE)
|
||||||
|
, mStateFloodGuardCount(0)
|
||||||
|
, mStateFloodGuardReported(false)
|
||||||
{
|
{
|
||||||
AssertOriginAttributesMatchPrivateBrowsing();
|
AssertOriginAttributesMatchPrivateBrowsing();
|
||||||
mHistoryID = ++gDocshellIDCounter;
|
mHistoryID = ++gDocshellIDCounter;
|
||||||
|
|
@ -11833,6 +11835,27 @@ nsDocShell::SetReferrerPolicy(uint32_t aReferrerPolicy)
|
||||||
// nsDocShell: Session History
|
// nsDocShell: Session History
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDocShell::IsStateChangeFlooding()
|
||||||
|
{
|
||||||
|
// Issue #1688: Let's copy Firefox's strategy for state flooding here, so
|
||||||
|
// that our implementations are interoperable.
|
||||||
|
if (mStateFloodGuardCount > kStateUpdateLimit) {
|
||||||
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
|
||||||
|
if (now - mStateFloodGuardUpdated > TimeDuration::FromSeconds(kRefreshTimeSecs)) {
|
||||||
|
mStateFloodGuardCount = 0;
|
||||||
|
mStateFloodGuardUpdated = now;
|
||||||
|
mStateFloodGuardReported = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mStateFloodGuardCount++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
||||||
const nsAString& aURL, bool aReplace, JSContext* aCx)
|
const nsAString& aURL, bool aReplace, JSContext* aCx)
|
||||||
|
|
@ -11897,6 +11920,24 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
||||||
nsCOMPtr<nsIDocument> document = GetDocument();
|
nsCOMPtr<nsIDocument> document = GetDocument();
|
||||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// If we're being flooded with state change requests, we should abort early
|
||||||
|
// from the state change logic.
|
||||||
|
if (IsStateChangeFlooding()) {
|
||||||
|
// Report a warning to the console to tell developers why their navigations
|
||||||
|
// failed.
|
||||||
|
// Do this only if not yet marked reported so we only report it once per
|
||||||
|
// flood interval.
|
||||||
|
if (!mStateFloodGuardReported) {
|
||||||
|
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||||
|
NS_LITERAL_CSTRING("PushState"),
|
||||||
|
document,
|
||||||
|
nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"PushStateFloodingPrevented");
|
||||||
|
mStateFloodGuardReported = true;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Step A: Serialize aData using structured clone.
|
// Step A: Serialize aData using structured clone.
|
||||||
// https://html.spec.whatwg.org/multipage/history.html#dom-history-pushstate
|
// https://html.spec.whatwg.org/multipage/history.html#dom-history-pushstate
|
||||||
// step 5.
|
// step 5.
|
||||||
|
|
|
||||||
|
|
@ -1049,6 +1049,15 @@ private:
|
||||||
// as constants in the nsIDocShell.idl file.
|
// as constants in the nsIDocShell.idl file.
|
||||||
uint32_t mTouchEventsOverride;
|
uint32_t mTouchEventsOverride;
|
||||||
|
|
||||||
|
// Keep track how how many history state changes we're getting, to catch &
|
||||||
|
// prevent flooding.
|
||||||
|
int32_t mStateFloodGuardCount;
|
||||||
|
mozilla::TimeStamp mStateFloodGuardUpdated;
|
||||||
|
bool mStateFloodGuardReported;
|
||||||
|
// We have a limit of pushing 50 states to history every 10 seconds.
|
||||||
|
const int32_t kStateUpdateLimit = 50;
|
||||||
|
const double kRefreshTimeSecs = 10.0;
|
||||||
|
|
||||||
// Separate function to do the actual name (i.e. not _top, _self etc.)
|
// Separate function to do the actual name (i.e. not _top, _self etc.)
|
||||||
// searching for FindItemWithName.
|
// searching for FindItemWithName.
|
||||||
nsresult DoFindItemWithName(const nsAString& aName,
|
nsresult DoFindItemWithName(const nsAString& aName,
|
||||||
|
|
@ -1064,6 +1073,10 @@ private:
|
||||||
void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
|
void MaybeNotifyKeywordSearchLoading(const nsString& aProvider,
|
||||||
const nsString& aKeyword);
|
const nsString& aKeyword);
|
||||||
|
|
||||||
|
// Helper method for AddState which checks for excessive calls to PushState or
|
||||||
|
// ReplaceState.
|
||||||
|
bool IsStateChangeFlooding();
|
||||||
|
|
||||||
#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;
|
||||||
|
|
|
||||||
|
|
@ -316,3 +316,5 @@ LargeAllocationRelatedBrowsingContexts=A Large-Allocation header was ignored due
|
||||||
LargeAllocationInIFrame=A Large-Allocation header was ignored due to the load occuring within an iframe.
|
LargeAllocationInIFrame=A Large-Allocation header was ignored due to the load occuring within an iframe.
|
||||||
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name
|
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name
|
||||||
LargeAllocationNonE10S=A Large-Allocation header was ignored due to the document not being loaded out of process.
|
LargeAllocationNonE10S=A Large-Allocation header was ignored due to the document not being loaded out of process.
|
||||||
|
# LOCALIZATION NOTE: Do not translate "pushState" and "replaceState"
|
||||||
|
PushStateFloodingPrevented=Call to pushState or replaceState ignored due to excessive calls within a short timeframe.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue