diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ddc02ffd3..2b1c73b0a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ should change the heading of the (upcoming) version to include a major version b --> +# 5.22.4 + +## Dev / docs / playground + +- Fix issue 'Maximum call stack size exceeded' with playground share with large content. + # 5.22.3 ## @rjsf/utils diff --git a/packages/playground/src/utils/base64.ts b/packages/playground/src/utils/base64.ts index 23f0f3a3b2..43d659ce60 100644 --- a/packages/playground/src/utils/base64.ts +++ b/packages/playground/src/utils/base64.ts @@ -16,7 +16,7 @@ const base64 = (function () { const { TextEncoder } = require('util'); encoder = new TextEncoder(); } - return btoa(String.fromCharCode(...encoder.encode(text))); + return btoa(safeFromCharCode(encoder, text)); }, decode(text: string): string { let decoder: any; @@ -31,4 +31,21 @@ const base64 = (function () { }; })(); +/** + * This function is a workaround for the fact that the String.fromCharCode method can throw a "Maximum call stack size exceeded" error if you try to pass too many arguments to it at once. + * This is because String.fromCharCode expects individual character codes as arguments and javascript has a limit on the number of arguments that can be passed to a function. + */ +function safeFromCharCode(encoder: any, text: string): string { + const codes = encoder.encode(text); + const CHUNK_SIZE = 0x9000; // 36864 + let result = ''; + + for (let i = 0; i < codes.length; i += CHUNK_SIZE) { + const chunk = codes.slice(i, i + CHUNK_SIZE); + result += String.fromCharCode(...chunk); + } + + return result; +} + export default base64;