Skip to content

Commit

Permalink
fix: may as well just check for presence of zone
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldambra committed Nov 28, 2024
1 parent e3646f5 commit fdc8226
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 40 deletions.
43 changes: 15 additions & 28 deletions patches/@[email protected]
Original file line number Diff line number Diff line change
@@ -1,45 +1,32 @@
diff --git a/dist/record.js b/dist/record.js
index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83a7e17c58 100644
index 46ec389fefb698243008b39db65470dbdf0a3857..efc65d8c393de8d0ad35083cba315aef91a04c2c 100644
--- a/dist/record.js
+++ b/dist/record.js
@@ -26,6 +26,27 @@ const testableMethods$1 = {
@@ -26,6 +26,14 @@ const testableMethods$1 = {
Element: [],
MutationObserver: ["constructor"]
};
+const isFunction = (x) => typeof x === 'function';
+const isAngularZonePatchedFunction = (x) => {
+
+const isAngularZonePresent = () => {
+ try {
+ if (!isFunction(x)) {
+ return false;
+ }
+ // if Angular has a zone, then whatever this is could be tainted
+ if (globalThis.Zone) {
+ return true
+ }
+ for (const key of Object.getOwnPropertyNames(x || {})) {
+ if (key.indexOf('__zone') !== -1) {
+ return true;
+ }
+ }
+ return false
+ return !!globalThis.Zone
+ } catch {
+ // we've seen some intermittent problems in Safari since introducing this check
+ return false
+ }
+}
const untaintedBasePrototype$1 = {};
function getUntaintedPrototype$1(key) {
if (untaintedBasePrototype$1[key])
@@ -54,7 +75,7 @@ function getUntaintedPrototype$1(key) {
@@ -54,7 +62,7 @@ function getUntaintedPrototype$1(key) {
}
)
);
- if (isUntaintedAccessors && isUntaintedMethods) {
+ if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePatchedFunction(defaultObj)) {
+ if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {
untaintedBasePrototype$1[key] = defaultObj.prototype;
return defaultObj.prototype;
}
@@ -65,10 +86,10 @@ function getUntaintedPrototype$1(key) {
@@ -65,10 +73,10 @@ function getUntaintedPrototype$1(key) {
if (!win) return defaultObj.prototype;
const untaintedObject = win[key].prototype;
document.body.removeChild(iframeEl);
Expand All @@ -52,7 +39,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
}
}
const untaintedAccessorCache$1 = {};
@@ -246,6 +267,9 @@ function isCSSImportRule(rule2) {
@@ -246,6 +254,9 @@ function isCSSImportRule(rule2) {
function isCSSStyleRule(rule2) {
return "selectorText" in rule2;
}
Expand All @@ -62,7 +49,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
class Mirror {
constructor() {
__publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map());
@@ -809,9 +833,14 @@ function serializeElementNode(n2, options) {
@@ -809,9 +820,14 @@ function serializeElementNode(n2, options) {
}
}
if (tagName === "link" && inlineStylesheet) {
Expand All @@ -80,7 +67,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
let cssText = null;
if (stylesheet) {
cssText = stringifyStylesheet(stylesheet);
@@ -855,7 +884,15 @@ function serializeElementNode(n2, options) {
@@ -855,7 +871,15 @@ function serializeElementNode(n2, options) {
}
}
if (tagName === "dialog" && n2.open) {
Expand All @@ -97,7 +84,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
}
if (tagName === "canvas" && recordCanvas) {
if (n2.__context === "2d") {
@@ -1116,7300 +1153,227 @@ function serializeNodeWithId(n2, options) {
@@ -1116,7300 +1140,227 @@ function serializeNodeWithId(n2, options) {
keepIframeSrcFn
};
if (serializedNode.type === NodeType$2.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
Expand Down Expand Up @@ -7607,7 +7594,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
class BaseRRNode {
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
constructor(..._args) {
@@ -8507,7 +1471,7 @@ function getUntaintedPrototype(key) {
@@ -8507,7 +1458,7 @@ function getUntaintedPrototype(key) {
}
)
);
Expand All @@ -7616,7 +7603,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
untaintedBasePrototype[key] = defaultObj.prototype;
return defaultObj.prototype;
}
@@ -11382,11 +4346,19 @@ class CanvasManager {
@@ -11382,11 +4333,19 @@ class CanvasManager {
let rafId;
const getCanvas = () => {
const matchedCanvas = [];
Expand All @@ -7641,7 +7628,7 @@ index 46ec389fefb698243008b39db65470dbdf0a3857..6c62dab78676066344afb27976dd7d83
return matchedCanvas;
};
const takeCanvasSnapshots = (timestamp) => {
@@ -11407,13 +4379,20 @@ class CanvasManager {
@@ -11407,13 +4366,20 @@ class CanvasManager {
context.clear(context.COLOR_BUFFER_BIT);
}
}
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/utils/prototype-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { AssignableWindow } from './globals'
import { isAngularZonePatchedFunction, isFunction, isNativeFunction } from './type-utils'
import { isAngularZonePresent, isFunction, isNativeFunction } from './type-utils'
import { logger } from './logger'

interface NativeImplementationsCache {
Expand All @@ -25,7 +25,7 @@ export function getNativeImplementation<T extends keyof NativeImplementationsCac

let impl = assignableWindow[name] as NativeImplementationsCache[T]

if (isNativeFunction(impl) && !isAngularZonePatchedFunction(impl)) {
if (isNativeFunction(impl) && !isAngularZonePresent()) {
return (cachedImplementations[name] = impl.bind(assignableWindow) as NativeImplementationsCache[T])
}

Expand Down
11 changes: 4 additions & 7 deletions src/utils/type-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { includes } from '.'
import { window } from './globals'
import { knownUnsafeEditableEvent, KnownUnsafeEditableEvent } from '../types'

// eslint-disable-next-line posthog-js/no-direct-array-check
Expand All @@ -24,13 +25,9 @@ export const isFunction = (x: unknown): x is (...args: any[]) => any => {
export const isNativeFunction = (x: unknown): x is (...args: any[]) => any =>
isFunction(x) && x.toString().indexOf('[native code]') !== -1

// When angular patches functions they pass the above `isNativeFunction` check
export const isAngularZonePatchedFunction = (x: unknown): boolean => {
if (!isFunction(x)) {
return false
}
const prototypeKeys = Object.getOwnPropertyNames(x.prototype || {})
return prototypeKeys.some((key) => key.indexOf('__zone'))
// When angular patches functions they pass the above `isNativeFunction` check (at least the MutationObserver)
export const isAngularZonePresent = (): boolean => {
return !!(window as any).Zone
}

// Underscore Addons
Expand Down

0 comments on commit fdc8226

Please sign in to comment.