mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Prevent augmentObject from creating infinitely deep proxies (#5893)
fixes #5848
This commit is contained in:
parent
35cf783e83
commit
6906b00b0e
|
@ -1,18 +1,9 @@
|
||||||
import type { IDataObject } from './Interfaces';
|
import type { IDataObject } from './Interfaces';
|
||||||
|
|
||||||
const augmentedObjects = new WeakSet<object>();
|
const augmentedObjects = new WeakSet<object>();
|
||||||
|
|
||||||
function augment<T>(value: T): T {
|
function augment<T>(value: T): T {
|
||||||
if (
|
if (typeof value !== 'object' || value === null || value instanceof RegExp) return value;
|
||||||
typeof value !== 'object' ||
|
|
||||||
value === null ||
|
|
||||||
value instanceof RegExp ||
|
|
||||||
augmentedObjects.has(value)
|
|
||||||
)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
// Track augmented objects to prevent infinite recursion in cases where an object contains circular references
|
|
||||||
augmentedObjects.add(value);
|
|
||||||
|
|
||||||
if (value instanceof Date) return new Date(value.valueOf()) as T;
|
if (value instanceof Date) return new Date(value.valueOf()) as T;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
|
@ -23,6 +14,8 @@ function augment<T>(value: T): T {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function augmentArray<T>(data: T[]): T[] {
|
export function augmentArray<T>(data: T[]): T[] {
|
||||||
|
if (augmentedObjects.has(data)) return data;
|
||||||
|
|
||||||
let newData: unknown[] | undefined = undefined;
|
let newData: unknown[] | undefined = undefined;
|
||||||
|
|
||||||
function getData(): unknown[] {
|
function getData(): unknown[] {
|
||||||
|
@ -32,7 +25,7 @@ export function augmentArray<T>(data: T[]): T[] {
|
||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Proxy(data, {
|
const proxy = new Proxy(data, {
|
||||||
deleteProperty(target, key: string) {
|
deleteProperty(target, key: string) {
|
||||||
return Reflect.deleteProperty(getData(), key);
|
return Reflect.deleteProperty(getData(), key);
|
||||||
},
|
},
|
||||||
|
@ -63,24 +56,25 @@ export function augmentArray<T>(data: T[]): T[] {
|
||||||
return Reflect.ownKeys(newData !== undefined ? newData : target);
|
return Reflect.ownKeys(newData !== undefined ? newData : target);
|
||||||
},
|
},
|
||||||
set(target, key: string, newValue: unknown) {
|
set(target, key: string, newValue: unknown) {
|
||||||
if (newValue !== null && typeof newValue === 'object') {
|
|
||||||
// Always proxy all objects. Like that we can check in get simply if it
|
// Always proxy all objects. Like that we can check in get simply if it
|
||||||
// is a proxy and it does then not matter if it was already there from the
|
// is a proxy and it does then not matter if it was already there from the
|
||||||
// beginning and it got proxied at some point or set later and so theoretically
|
// beginning and it got proxied at some point or set later and so theoretically
|
||||||
// does not have to get proxied
|
// does not have to get proxied
|
||||||
newValue = new Proxy(newValue, {});
|
return Reflect.set(getData(), key, augment(newValue));
|
||||||
}
|
|
||||||
|
|
||||||
return Reflect.set(getData(), key, newValue);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
augmentedObjects.add(proxy);
|
||||||
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function augmentObject<T extends object>(data: T): T {
|
export function augmentObject<T extends object>(data: T): T {
|
||||||
|
if (augmentedObjects.has(data)) return data;
|
||||||
|
|
||||||
const newData = {} as IDataObject;
|
const newData = {} as IDataObject;
|
||||||
const deletedProperties: Array<string | symbol> = [];
|
const deletedProperties: Array<string | symbol> = [];
|
||||||
|
|
||||||
return new Proxy(data, {
|
const proxy = new Proxy(data, {
|
||||||
get(target, key: string, receiver): unknown {
|
get(target, key: string, receiver): unknown {
|
||||||
if (deletedProperties.indexOf(key) !== -1) {
|
if (deletedProperties.indexOf(key) !== -1) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -144,4 +138,7 @@ export function augmentObject<T extends object>(data: T): T {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
augmentedObjects.add(proxy);
|
||||||
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue