Skip to content

Commit 91582d4

Browse files
fix(utils): avoid enumerating string defaults in mergeDefaultsWithFormData (#5062)
* fix(utils): avoid Object.entries on string defaults in mergeDefaultsWithFormData * Apply suggestion from @heath-freenome * Update CHANGELOG.md * Update CHANGELOG.md --------- Co-authored-by: Heath C <51679588+heath-freenome@users.noreply.github.com>
1 parent ca98803 commit 91582d4

3 files changed

Lines changed: 11 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ should change the heading of the (upcoming) version to include a major version b
2929
- Added `deprecatedHandling` to `GlobalUISchemaOptions` and updated `StrictRJSFSchema` to be recursive, ensuring the `deprecated` keyword (and future extensions) are supported in all nested schema structures without requiring type casts, fixing [#5024](https://github.com/rjsf-team/react-jsonschema-form/issues/5024)
3030
- Also added `DeprecatedLabel` to `TranslatableString` to support internationalization of the deprecated field suffix
3131
- Added `SchemaFieldPath` (`string | FieldPathList`) for `getFromSchema` / `findFieldInSchema`; fixed schema descent when a segment is numeric `0` (previously skipped due to falsy check); use string keys for `required` / oneOf fallback matching
32+
- Fixed `mergeDefaultsWithFormData` calling `Object.entries` on non-object defaults (e.g. long `data:` URL strings for single file fields), which iterated every character and caused severe UI freezes, fixing [#5055](https://github.com/rjsf-team/react-jsonschema-form/issues/5055)
3233

3334
# 6.5.2
3435

packages/utils/src/mergeDefaultsWithFormData.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ export default function mergeDefaultsWithFormData<T = any>(
6868
const keyExistsInDefaults = isObject(defaults) && key in (defaults as GenericObjectType);
6969
const keyExistsInFormData = key in (formData as GenericObjectType);
7070
const keyDefault = get(defaults, key) ?? {};
71-
const defaultValueIsNestedObject = keyExistsInDefaults && Object.entries(keyDefault).some(([, v]) => isObject(v));
71+
const defaultValueIsNestedObject =
72+
keyExistsInDefaults && isObject(keyDefault) && Object.values(keyDefault).some((v) => isObject(v));
7273

7374
const keyDefaultIsObject = keyExistsInDefaults && isObject(get(defaults, key));
7475
const keyHasFormDataObject = keyExistsInFormData && isObject(keyValue);

packages/utils/test/mergeDefaultsWithFormData.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,14 @@ describe('mergeDefaultsWithFormData()', () => {
148148
expect(mergeDefaultsWithFormData(obj1, obj2)?.a).toBeInstanceOf(File);
149149
});
150150

151+
it('should merge quickly when the default for a key is a long string (e.g. data-url file value)', () => {
152+
const largeDefault = `data:application/octet-stream;base64,${'A'.repeat(200_000)}`;
153+
const formValue = 'data:application/octet-stream;base64,B';
154+
expect(mergeDefaultsWithFormData<{ file: string }>({ file: largeDefault }, { file: formValue })).toEqual({
155+
file: formValue,
156+
});
157+
});
158+
151159
describe('test with overrideFormDataWithDefaults set to true', () => {
152160
it('should return data in formData when no defaults', () => {
153161
expect(mergeDefaultsWithFormData(undefined, [2], undefined, undefined, true)).toEqual([2]);

0 commit comments

Comments
 (0)