From 8c15238c7c874ccc64b0d118a766d4fc3d6851f1 Mon Sep 17 00:00:00 2001 From: Alex Riviere Date: Sun, 26 Feb 2023 20:22:47 -0500 Subject: [PATCH] Fix #2230: Stop accidental infinite recursion (#2233) * Add check for `then` being replaced * adjust white space * Change to be a limit of the number of times then can be replaced. * Create .changeset/nasty-cougars-hear.md --------- Co-authored-by: Ziad Beyens --- .changeset/nasty-cougars-hear.md | 5 ++++ packages/core/src/types/plugin/PlatePlugin.ts | 5 ++++ .../src/utils/plate/overridePluginsByKey.ts | 26 ++++++++++++------- 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 .changeset/nasty-cougars-hear.md diff --git a/.changeset/nasty-cougars-hear.md b/.changeset/nasty-cougars-hear.md new file mode 100644 index 0000000000..3b1106af81 --- /dev/null +++ b/.changeset/nasty-cougars-hear.md @@ -0,0 +1,5 @@ +--- +"@udecode/plate-core": patch +--- + +Fixes #2230: infinite recursion when using plugin field `then` diff --git a/packages/core/src/types/plugin/PlatePlugin.ts b/packages/core/src/types/plugin/PlatePlugin.ts index 09534b6334..bf820c0209 100644 --- a/packages/core/src/types/plugin/PlatePlugin.ts +++ b/packages/core/src/types/plugin/PlatePlugin.ts @@ -187,6 +187,11 @@ export type PlatePlugin< plugin: WithPlatePlugin ) => Partial> | void; + /** + * For internal use. Tracks if then has been replaced for recursive calls. + */ + _thenReplaced?: number; + /** * Hook called when the editor is initialized. */ diff --git a/packages/core/src/utils/plate/overridePluginsByKey.ts b/packages/core/src/utils/plate/overridePluginsByKey.ts index 10acca5112..c1503c06d8 100644 --- a/packages/core/src/utils/plate/overridePluginsByKey.ts +++ b/packages/core/src/utils/plate/overridePluginsByKey.ts @@ -49,15 +49,23 @@ export const overridePluginsByKey = < const { then } = plugin; if (then) { - // override plugin.then - plugin.then = (editor, p) => { - const pluginThen = { key: plugin.key, ...then(editor, p) }; - - return defaultsDeep( - overridePluginsByKey(pluginThen as any, overrideByKey), - pluginThen - ); - }; + if(typeof plugin._thenReplaced === 'undefined') { + plugin._thenReplaced = 0; + } + // Limit the number of times that `then` can be replaced. + // otherwise we will accidentally create a stack overflow. + // There is probably a better solution for this. + if((plugin._thenReplaced as number) < 3) { + // override plugin.then + plugin.then = (editor, p) => { + const pluginThen = { key: plugin.key, ...then(editor, p) }; + return defaultsDeep( + overridePluginsByKey(pluginThen as any, overrideByKey), + pluginThen + ); + }; + (plugin._thenReplaced as number)++; + } } else if (overrideByKey[plugin.key]?.then) { // TODO: recursvie plugin.then = overrideByKey[plugin.key].then as any;