MOBILE-3068 utils: Fix max stack size reached when cloning

main
Dani Palou 2019-08-27 16:13:41 +02:00
parent ebd4577be2
commit 3da30f665a
2 changed files with 19 additions and 4 deletions

View File

@ -337,7 +337,7 @@ export class AddonModDataHelperProvider {
approved: !data.approval || data.manageapproved,
canmanageentry: true,
fullname: site.getInfo().fullname,
contents: [],
contents: {},
}
});
}

View File

@ -58,6 +58,7 @@ export interface PromiseDefer {
*/
@Injectable()
export class CoreUtilsProvider {
protected DONT_CLONE = ['[object FileEntry]', '[object DirectoryEntry]', '[object DOMFileSystem]'];
protected logger;
protected iabInstance: InAppBrowserObject;
protected uniqueIds: {[name: string]: number} = {};
@ -267,22 +268,36 @@ export class CoreUtilsProvider {
* Clone a variable. It should be an object, array or primitive type.
*
* @param {any} source The variable to clone.
* @param {number} [level=0] Depth we are right now inside a cloned object. It's used to prevent reaching max call stack size.
* @return {any} Cloned variable.
*/
clone(source: any): any {
clone(source: any, level: number = 0): any {
if (level >= 20) {
// Max 20 levels.
this.logger.error('Max depth reached when cloning object.', source);
return source;
}
if (Array.isArray(source)) {
// Clone the array and all the entries.
const newArray = [];
for (let i = 0; i < source.length; i++) {
newArray[i] = this.clone(source[i]);
newArray[i] = this.clone(source[i], level + 1);
}
return newArray;
} else if (typeof source == 'object' && source !== null) {
// Check if the object shouldn't be copied.
if (source && source.toString && this.DONT_CLONE.indexOf(source.toString()) != -1) {
// Object shouldn't be copied, return it as it is.
return source;
}
// Clone the object and all the subproperties.
const newObject = {};
for (const name in source) {
newObject[name] = this.clone(source[name]);
newObject[name] = this.clone(source[name], level + 1);
}
return newObject;