From fc861fca508a6a0406114bfdb4577077191ab95f Mon Sep 17 00:00:00 2001 From: hakimel Date: Wed, 9 Mar 2022 09:44:19 +0100 Subject: [PATCH] throttle calls to replaceState to fix security error when navigating quickly in Safari #3147 --- js/controllers/location.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/js/controllers/location.js b/js/controllers/location.js index ec86e65..b0c80ce 100644 --- a/js/controllers/location.js +++ b/js/controllers/location.js @@ -3,6 +3,10 @@ */ export default class Location { + // The minimum number of milliseconds that must pass between + // calls to history.replaceState + MAX_REPLACE_STATE_FREQUENCY = 250 + constructor( Reveal ) { this.Reveal = Reveal; @@ -10,6 +14,8 @@ export default class Location { // Delays updates to the URL due to a Chrome thumbnailer bug this.writeURLTimeout = 0; + this.replaceStateTimestamp = 0; + this.onWindowHashChange = this.onWindowHashChange.bind( this ); } @@ -142,10 +148,10 @@ export default class Location { else if( config.hash ) { // If the hash is empty, don't add it to the URL if( hash === '/' ) { - window.history.replaceState( null, null, window.location.pathname + window.location.search ); + this.debouncedReplaceState( window.location.pathname + window.location.search ); } else { - window.history.replaceState( null, null, '#' + hash ); + this.debouncedReplaceState( '#' + hash ); } } // UPDATE: The below nuking of all hash changes breaks @@ -163,6 +169,26 @@ export default class Location { } + replaceState( url ) { + + window.history.replaceState( null, null, url ); + this.replaceStateTimestamp = Date.now(); + + } + + debouncedReplaceState( url ) { + + clearTimeout( this.replaceStateTimeout ); + + if( Date.now() - this.replaceStateTimestamp > this.MAX_REPLACE_STATE_FREQUENCY ) { + this.replaceState( url ); + } + else { + this.replaceStateTimeout = setTimeout( () => this.replaceState( url ), this.MAX_REPLACE_STATE_FREQUENCY ); + } + + } + /** * Return a hash URL that will resolve to the given slide location. *