Fix dead objects errors

This commit is contained in:
Kuba Orlik 2022-05-02 17:04:56 +02:00
parent 1961d072bf
commit fa441b5b81
9 changed files with 94 additions and 72 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@ node_modules
sidebar.js
/web-ext-artifacts/
lib/*
/yarn-error.log
/rentgen.zip

View File

@ -104,7 +104,7 @@ const Sidebar = () => {
<button
onClick={() => {
getMemory().removeRequestsFor(origin);
getMemory().emit('change', false, origin, 'clicked trash');
getMemory().emit('change', origin);
setMarksOccurrence(false);
}}
>
@ -114,7 +114,7 @@ const Sidebar = () => {
<button
onClick={() => {
getMemory().removeCookiesFor(origin);
getMemory().emit('change', false, origin, 'clicked clear cookies');
getMemory().emit('change', origin);
setMarksOccurrence(false);
}}
>

View File

@ -21,7 +21,7 @@ function StolenDataValue({ entry }: { entry: StolenDataEntry; prefixKey?: string
className="value"
onClick={(e) => {
entry.toggleMark();
getMemory().emit('change', false, entry.request.shorthost, 'clicked value');
getMemory().emit('change', entry.request.shorthost);
e.stopPropagation();
}}
title={entry.value}
@ -45,12 +45,7 @@ function StolenDataRow({ entry }: { entry: StolenDataEntry }) {
checked={entry.isMarked}
onChange={() => {
entry.toggleMark();
getMemory().emit(
'change',
false,
entry.request.shorthost,
'clicked checkbox'
);
getMemory().emit('change', entry.request.shorthost);
}}
/>
</td>
@ -139,7 +134,7 @@ export default function StolenDataCluster({
checked={cluster.hasMarks()}
onChange={() => {
cluster.hasMarks() ? cluster.undoMark() : cluster.autoMark();
getMemory().emit('change', true, cluster.id, 'clicked checkbox');
getMemory().emit('change', cluster.id);
}}
/>
<a className="domain" href={'https://' + cluster.id}>

View File

@ -1,7 +1,7 @@
import ExtendedRequest from './extended-request';
import { getshorthost, makeThrottle } from './util';
import { EventEmitter } from 'events';
import { RequestCluster } from './request-cluster';
import { SaferEmitter } from './safer-emitter';
function setDomainsNumber(counter: number, tabId: number) {
browser.browserAction.setBadgeText({ text: counter < 0 ? '0' : counter.toString(), tabId });
@ -11,9 +11,8 @@ function setDomainsNumber(counter: number, tabId: number) {
});
}
export default class Memory extends EventEmitter {
export default class Memory extends SaferEmitter {
origin_to_history = {} as Record<string, Record<string, RequestCluster>>;
private throttle = makeThrottle(100);
async register(request: ExtendedRequest) {
await request.init();
if (!request.isThirdParty()) {
@ -28,7 +27,7 @@ export default class Memory extends EventEmitter {
this.origin_to_history[request.origin][shorthost] = cluster;
}
this.origin_to_history[request.origin][shorthost].add(request);
this.emit('change', false, shorthost, 'registered request(shorthost emit)');
this.emit('change', shorthost);
Object.values(this.getClustersForOrigin(request.origin)).some((cluster) =>
cluster.hasCookies()
@ -64,62 +63,8 @@ export default class Memory extends EventEmitter {
);
}
private originalEmit(type: string, ...args: unknown[]) {
let doError = type === 'error';
let events = (this as any)._events;
if (events !== undefined) doError = doError && events.error === undefined;
else if (!doError) return false;
// If there is no 'error' event listener then throw.
if (doError) {
let er;
if (args.length > 0) er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
let err = new Error('Unhandled error.' + (er ? ' (' + (er as any).message + ')' : ''));
(err as any).context = er;
throw err; // Unhandled 'error' event
}
let handler = events[type];
if (handler === undefined) return false;
if (typeof handler === 'function') {
try {
Reflect.apply(handler, this, args);
} catch (error) {
events[type] = undefined;
}
} else {
let listeners = [...handler];
listeners
.filter((e) => {
try {
e.call;
} catch (error) {
return false;
}
return true;
})
.forEach((listener) => {
try {
Reflect.apply(listener, this, args);
} catch (error) {
console.error(error);
debugger;
}
});
}
return true;
}
emit(eventName: string, immediate = false, data = 'any', reason: string): boolean {
setTimeout(() => this.originalEmit(eventName, data), 0);
emit(eventName: string, data = 'any'): boolean {
setTimeout(() => super.emit(eventName, data), 0);
return;
}

20
package-lock.json generated
View File

@ -24,6 +24,7 @@
"addons-linter": "^4.7.0",
"esbuild": "^0.14.14",
"esbuild-plugin-sass": "^1.0.1",
"typescript": "^4.6.4",
"web-ext": "^6.7.0",
"web-ext-types": "^3.2.1"
}
@ -5117,6 +5118,19 @@
"is-typedarray": "^1.0.0"
}
},
"node_modules/typescript": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/unique-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@ -9448,6 +9462,12 @@
"is-typedarray": "^1.0.0"
}
},
"typescript": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
"dev": true
},
"unique-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",

View File

@ -46,6 +46,7 @@
"addons-linter": "^4.7.0",
"esbuild": "^0.14.14",
"esbuild-plugin-sass": "^1.0.1",
"typescript": "^4.6.4",
"web-ext": "^6.7.0",
"web-ext-types": "^3.2.1"
}

View File

@ -1,12 +1,13 @@
import { EventEmitter } from 'events';
import ExtendedRequest from './extended-request';
import { SaferEmitter } from './safer-emitter';
import { Sources, StolenDataEntry } from './stolen-data-entry';
import { allSubhosts, isSameURL, reduceConcat, unique } from './util';
const source_priority: Array<Sources> = ['cookie', 'pathname', 'queryparams', 'header'];
export class RequestCluster extends EventEmitter {
export class RequestCluster extends SaferEmitter {
public requests: ExtendedRequest[] = [];
public representativeStolenData: StolenDataEntry[] = [];
public expanded: boolean;

57
safer-emitter.ts Normal file
View File

@ -0,0 +1,57 @@
import EventEmitter from 'events';
export class SaferEmitter extends EventEmitter {
emit(type: string, ...args: unknown[]) {
let doError = type === 'error';
let events = (this as any)._events;
if (events !== undefined) doError = doError && events.error === undefined;
else if (!doError) return false;
// If there is no 'error' event listener then throw.
if (doError) {
let er;
if (args.length > 0) er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
let err = new Error('Unhandled error.' + (er ? ' (' + (er as any).message + ')' : ''));
(err as any).context = er;
throw err; // Unhandled 'error' event
}
let handler = events[type];
if (handler === undefined) return false;
if (typeof handler === 'function') {
try {
Reflect.apply(handler, this, args);
} catch (error) {
events[type] = undefined;
}
} else {
let listeners = [...handler];
listeners
.filter((e) => {
try {
e.call;
} catch (error) {
return false;
}
return true;
})
.forEach((listener) => {
try {
Reflect.apply(listener, this, args);
} catch (error) {
console.error(error);
debugger;
}
});
}
return true;
}
}

View File

@ -1,5 +1,6 @@
import { EventEmitter } from 'events';
import ExtendedRequest, { HAREntry } from './extended-request';
import { SaferEmitter } from './safer-emitter';
import {
getshorthost,
@ -33,7 +34,7 @@ const id = (function* id() {
export type DecodingSchema = 'base64' | 'raw';
export class StolenDataEntry extends EventEmitter {
export class StolenDataEntry extends SaferEmitter {
public isIAB = false;
public id: number;
private marked = false;