MCPcopy
hub / github.com/rrweb-io/rrweb / getUntaintedPrototype

Function getUntaintedPrototype

packages/utils/src/index.ts:57–131  ·  view source on GitHub ↗
(
  key: T,
)

Source from the content-addressed store, hash-verified

55};
56
57export function getUntaintedPrototype<T extends keyof BasePrototypeCache>(
58 key: T,
59): BasePrototypeCache[T] {
60 if (untaintedBasePrototype[key])
61 return untaintedBasePrototype[key] as BasePrototypeCache[T];
62
63 const defaultObj = globalThis[key] as TypeofPrototypeOwner;
64 const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];
65
66 // use list of testable accessors to check if the prototype is tainted
67 const accessorNames =
68 key in testableAccessors ? testableAccessors[key] : undefined;
69 const isUntaintedAccessors = Boolean(
70 accessorNames &&
71 // @ts-expect-error 2345
72 accessorNames.every((accessor: keyof typeof defaultPrototype) =>
73 Boolean(
74 Object.getOwnPropertyDescriptor(defaultPrototype, accessor)
75 ?.get?.toString()
76 .includes('[native code]'),
77 ),
78 ),
79 );
80
81 const methodNames = key in testableMethods ? testableMethods[key] : undefined;
82 const isUntaintedMethods = Boolean(
83 methodNames &&
84 methodNames.every(
85 // @ts-expect-error 2345
86 (method: keyof typeof defaultPrototype) =>
87 typeof defaultPrototype[method] === 'function' &&
88 defaultPrototype[method]?.toString().includes('[native code]'),
89 ),
90 );
91
92 if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {
93 untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];
94 return defaultObj.prototype as BasePrototypeCache[T];
95 }
96
97 try {
98 const iframeEl = document.createElement('iframe');
99 iframeEl.style.display = 'none';
100 document.body.appendChild(iframeEl);
101 const win = iframeEl.contentWindow;
102 if (!win) return defaultObj.prototype as BasePrototypeCache[T];
103
104 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
105 const untaintedObject = (win as any)[key]
106 .prototype as BasePrototypeCache[T];
107
108 if (!untaintedObject) {
109 iframeEl.remove();
110 return defaultPrototype;
111 }
112
113 // WebKit/Safari: WebKit tears down an iframe's ScriptExecutionContext when it is
114 // detached from the DOM. MutationObserver.deliver() silently drops callbacks when

Callers 3

getUntaintedAccessorFunction · 0.85
getUntaintedMethodFunction · 0.85
mutationObserverCtorFunction · 0.85

Calls 6

isAngularZonePresentFunction · 0.85
toStringMethod · 0.65
createElementMethod · 0.65
appendChildMethod · 0.65
addMethod · 0.65
setAttributeMethod · 0.65

Tested by

no test coverage detected