Skip to content

Commit 9c77258

Browse files
committed
fix(core): Ensure fill only patches functions
1 parent a2850a3 commit 9c77258

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

packages/browser-utils/src/instrument/history.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ export function instrumentHistory(): void {
6464
};
6565
}
6666

67-
if (typeof WINDOW.history.pushState === 'function') {
68-
fill(WINDOW.history, 'pushState', historyReplacementFunction);
69-
}
70-
if (typeof WINDOW.history.replaceState === 'function') {
71-
fill(WINDOW.history, 'replaceState', historyReplacementFunction);
72-
}
67+
fill(WINDOW.history, 'pushState', historyReplacementFunction);
68+
fill(WINDOW.history, 'replaceState', historyReplacementFunction);
7369
}

packages/core/src/utils-hoist/object.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { truncate } from './string';
1010
/**
1111
* Replace a method in an object with a wrapped version of itself.
1212
*
13+
* If the method on the passed object is not a function, the wrapper will not be applied.
14+
*
1315
* @param source An object that contains a method to be wrapped.
1416
* @param name The name of the method to be wrapped.
1517
* @param replacementFactory A higher-order function that takes the original version of the given method and returns a
@@ -23,7 +25,11 @@ export function fill(source: { [key: string]: any }, name: string, replacementFa
2325
return;
2426
}
2527

26-
const original = source[name] as () => any;
28+
const original = source[name];
29+
if (typeof original !== 'function') {
30+
return;
31+
}
32+
2733
const wrapped = replacementFactory(original) as WrappedFunction;
2834

2935
// Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work

packages/core/test/utils-hoist/object.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ describe('fill()', () => {
5454
expect(source.prop()).toEqual(41);
5555
});
5656

57+
test.each([42, null, undefined, {}])("does't throw if the property is not a function but %s", (propValue: any) => {
58+
const source = {
59+
foo: propValue,
60+
};
61+
const name = 'foo';
62+
const replacement = vi.fn().mockImplementationOnce(cb => cb);
63+
64+
fill(source, name, replacement);
65+
66+
expect(source.foo).toEqual(propValue);
67+
expect(replacement).not.toBeCalled();
68+
});
69+
5770
test('can do anything inside replacement function', () => {
5871
const source = {
5972
foo: (): number => 42,

0 commit comments

Comments
 (0)