mirror of https://github.com/gorhill/uBlock.git
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
|
@ -101,6 +101,7 @@ const webext = {
|
||||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
|
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
|
||||||
webNavigation: {
|
webNavigation: {
|
||||||
getFrame: promisify(chrome.webNavigation, 'getFrame'),
|
getFrame: promisify(chrome.webNavigation, 'getFrame'),
|
||||||
|
getAllFrames: promisify(chrome.webNavigation, 'getAllFrames'),
|
||||||
},
|
},
|
||||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
|
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
|
||||||
windows: {
|
windows: {
|
||||||
|
|
|
@ -163,6 +163,7 @@ const FrameStore = class {
|
||||||
}
|
}
|
||||||
|
|
||||||
init(frameURL) {
|
init(frameURL) {
|
||||||
|
this.t0 = Date.now();
|
||||||
this.exceptCname = undefined;
|
this.exceptCname = undefined;
|
||||||
this.rawURL = frameURL;
|
this.rawURL = frameURL;
|
||||||
if ( frameURL !== undefined ) {
|
if ( frameURL !== undefined ) {
|
||||||
|
@ -252,6 +253,7 @@ const PageStore = class {
|
||||||
|
|
||||||
this.frames = new Map();
|
this.frames = new Map();
|
||||||
this.setFrame(0, tabContext.rawURL);
|
this.setFrame(0, tabContext.rawURL);
|
||||||
|
this.frameAddCount = 0;
|
||||||
|
|
||||||
// The current filtering context is cloned because:
|
// The current filtering context is cloned because:
|
||||||
// - We may be called with or without the current context having been
|
// - 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);
|
const frameStore = this.frames.get(frameId);
|
||||||
if ( frameStore !== undefined ) {
|
if ( frameStore !== undefined ) {
|
||||||
frameStore.init(frameURL);
|
frameStore.init(frameURL);
|
||||||
} else {
|
return;
|
||||||
this.frames.set(frameId, FrameStore.factory(frameURL));
|
}
|
||||||
|
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 New Issue