Skip to content

Commit

Permalink
fix(unpatch): ensure unpatch does not hold a reference to Patch object
Browse files Browse the repository at this point in the history
  • Loading branch information
twnlink committed Aug 20, 2024
1 parent a0de6a3 commit 3c2b5fc
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spitroast",
"version": "2.0.0",
"version": "2.0.1",
"description": "A simple JavaScript function patcher.",
"main": "dist/cjs.js",
"module": "dist/esm/index.js",
Expand Down
14 changes: 10 additions & 4 deletions src/getPatchFunc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ export default <CallbackType extends Function>(patchType: PatchType) =>
callback: CallbackType,
oneTime = false
) => {
if (typeof funcParent[funcName] !== "function")
let origFunc = funcParent[funcName];

if (typeof origFunc !== "function")
throw new Error(
`${funcName} is not a function in ${funcParent.constructor.name}`
);

let origFunc = funcParent[funcName];
let funcPatch = patchedFunctions.get(origFunc);

if (!funcPatch) {
Expand All @@ -43,7 +44,11 @@ export default <CallbackType extends Function>(patchType: PatchType) =>
: Reflect.get(target, prop, receiver),
});

const runHook: any = (ctxt: unknown, args: unknown[], construct: boolean) => hook(replaceProxy, origFunc, args, ctxt, construct);
const runHook: any = (
ctxt: unknown,
args: unknown[],
construct: boolean
) => hook(replaceProxy, origFunc, args, ctxt, construct);

patchedFunctions.set(replaceProxy, funcPatch);

Expand All @@ -58,7 +63,8 @@ export default <CallbackType extends Function>(patchType: PatchType) =>
}

const hookId = Symbol();
const unpatchThisPatch = () => unpatch(funcPatch, hookId, patchType);
const funcPatchRef = new WeakRef(funcPatch);
const unpatchThisPatch = () => unpatch(funcPatchRef, hookId, patchType);

if (oneTime) funcPatch.c.push(unpatchThisPatch);
funcPatch[patchType].set(hookId, callback);
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import getPatchFunc from "./getPatchFunc";
import { unpatchAll } from "./unpatch";

type BeforeCallback = (args: any[]) => void | undefined | any[];
type InsteadCallback = (args: any[], origFunc: Function) => any;
Expand All @@ -9,4 +8,5 @@ const before = getPatchFunc<BeforeCallback>("b");
const instead = getPatchFunc<InsteadCallback>("i");
const after = getPatchFunc<AfterCallback>("a");

export { instead, before, after, unpatchAll };
export { instead, before, after };
export { resetPatches as unpatchAll } from "./shared";
Empty file added src/patcher.ts
Empty file.
2 changes: 0 additions & 2 deletions src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export type Patch = {
i: Map<symbol, Function>;
};

export const patcherContext = { currentContext: { SHOULD_UNPATCH: false } };

export let patchedFunctions: WeakMap<Function, Patch>;
export let resetPatches = () =>
(patchedFunctions = new WeakMap<Function, Patch>());
Expand Down
10 changes: 5 additions & 5 deletions src/unpatch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { PatchType, Patch, patchTypes, patchedFunctions } from "./shared";

export function unpatch(patch: Patch, hookId: symbol, type: PatchType) {
if (!patch[type].delete(hookId)) return false;
export function unpatch(patchRef: WeakRef<Patch>, hookId: symbol, type: PatchType) {
const patch = patchRef.deref();

if (!patch || !patch[type].delete(hookId)) return false;
const funcParent = patch.p.deref();

// If there are no more hooks for every type, remove the patch
Expand All @@ -24,6 +26,4 @@ export function unpatch(patch: Patch, hookId: symbol, type: PatchType) {
}

return true;
}

export { resetPatches as unpatchAll } from "./shared";
}

0 comments on commit 3c2b5fc

Please sign in to comment.