mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
Do let grow subframe dictionary grow unbound
Related discussion: - https://bugzilla.mozilla.org/show_bug.cgi?id=1652925 It's not clear the code here will fix the reported issue, but I did identify that the subframe dictionary of a very long-lived web page can theoretically grow unbound.
This commit is contained in:
parent
cf31d83acf
commit
feabfe3793
2 changed files with 36 additions and 2 deletions
|
@ -101,6 +101,7 @@ const webext = {
|
|||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
|
||||
webNavigation: {
|
||||
getFrame: promisify(chrome.webNavigation, 'getFrame'),
|
||||
getAllFrames: promisify(chrome.webNavigation, 'getAllFrames'),
|
||||
},
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
|
||||
windows: {
|
||||
|
|
|
@ -163,6 +163,7 @@ const FrameStore = class {
|
|||
}
|
||||
|
||||
init(frameURL) {
|
||||
this.t0 = Date.now();
|
||||
this.exceptCname = undefined;
|
||||
this.rawURL = frameURL;
|
||||
if ( frameURL !== undefined ) {
|
||||
|
@ -252,6 +253,7 @@ const PageStore = class {
|
|||
|
||||
this.frames = new Map();
|
||||
this.setFrame(0, tabContext.rawURL);
|
||||
this.frameAddCount = 0;
|
||||
|
||||
// The current filtering context is cloned because:
|
||||
// - We may be called with or without the current context having been
|
||||
|
@ -359,8 +361,39 @@ const PageStore = class {
|
|||
const frameStore = this.frames.get(frameId);
|
||||
if ( frameStore !== undefined ) {
|
||||
frameStore.init(frameURL);
|
||||
} else {
|
||||
this.frames.set(frameId, FrameStore.factory(frameURL));
|
||||
return;
|
||||
}
|
||||
this.frames.set(frameId, FrameStore.factory(frameURL));
|
||||
this.frameAddCount += 1;
|
||||
if ( (this.frameAddCount & 0b111111) !== 0 ) { return; }
|
||||
this.pruneFrames();
|
||||
}
|
||||
|
||||
// There is no event to tell us a specific subframe has been removed from
|
||||
// the main document. The code below will remove subframes which are no
|
||||
// longer present in the root document. Removing obsolete subframes is
|
||||
// not a critical task, so this is executed just once on a while, to avoid
|
||||
// bloated dictionary of subframes.
|
||||
// A TTL is used to avoid race conditions when new iframes are added
|
||||
// through the webRequest API but still not yet visible through the
|
||||
// webNavigation API.
|
||||
async pruneFrames() {
|
||||
let entries;
|
||||
try {
|
||||
entries = await webext.webNavigation.getAllFrames({
|
||||
tabId: this.tabId
|
||||
});
|
||||
} catch(ex) {
|
||||
}
|
||||
if ( Array.isArray(entries) === false ) { return; }
|
||||
const toKeep = new Set();
|
||||
for ( const { frameId } of entries ) {
|
||||
toKeep.add(frameId);
|
||||
}
|
||||
const obsolete = Date.now() - 60000;
|
||||
for ( const [ frameId, { t0 } ] of this.frames ) {
|
||||
if ( toKeep.has(frameId) || t0 >= obsolete ) { continue; }
|
||||
this.frames.delete(frameId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue