Skip to content

Commit

Permalink
fix: Short-circuit File and Date constructor access in isObject (rjsf…
Browse files Browse the repository at this point in the history
…-team#4413)

* fix: short-circuit File and Date constructor access in isObject if thing is missing required property

* chore: update changelog with isObject short-circuiting fix

---------

Co-authored-by: Jonathan Sun <jonathan.sun@mujin.co.jp>
  • Loading branch information
Hsifnus and Jonathan Sun authored Dec 13, 2024
1 parent 4359bd1 commit 3c5539a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ should change the heading of the (upcoming) version to include a major version b

- Fix default value population when switching between options in `MultiSchemaField` [#4375](https://github.com/rjsf-team/react-jsonschema-form/pull/4375). Fixes [#4367](https://github.com/rjsf-team/react-jsonschema-form/issues/4367)

## @rjsf/utils

- Short-circuit `File` and `Date` constructor access in isObject to optimize performance in scenarios where `globalThis` is a `Proxy` that incurs overhead for each class constructor access ([#4413](https://github.com/rjsf-team/react-jsonschema-form/pull/4413)). Fixes [#4409](https://github.com/rjsf-team/react-jsonschema-form/issues/4409)

## @rjsf/validator-ajv8

- Fixed issue where `ui:title` in anyOf/oneOf is not shown in error messages. Fixes [#4368](https://github.com/rjsf-team/react-jsonschema-form/issues/4368)
Expand Down
15 changes: 11 additions & 4 deletions packages/utils/src/isObject.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
/** Determines whether a `thing` is an object for the purposes of RSJF. In this case, `thing` is an object if it has
/** Determines whether a `thing` is an object for the purposes of RJSF. In this case, `thing` is an object if it has
* the type `object` but is NOT null, an array or a File.
*
* @param thing - The thing to check to see whether it is an object
* @returns - True if it is a non-null, non-array, non-File object
*/
export default function isObject(thing: any) {
if (typeof File !== 'undefined' && thing instanceof File) {
if (typeof thing !== 'object' || thing === null) {
return false;
}
if (typeof Date !== 'undefined' && thing instanceof Date) {
// lastModified is guaranteed to be a number on a File instance
// as per https://w3c.github.io/FileAPI/#dfn-lastModified
if (typeof thing.lastModified === 'number' && typeof File !== 'undefined' && thing instanceof File) {
return false;
}
return typeof thing === 'object' && thing !== null && !Array.isArray(thing);
// getMonth is guaranteed to be a method on a Date instance
// as per https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getmonth
if (typeof thing.getMonth === 'function' && typeof Date !== 'undefined' && thing instanceof Date) {
return false;
}
return !Array.isArray(thing);
}
34 changes: 34 additions & 0 deletions packages/utils/test/isObject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,38 @@ describe('isObject()', () => {
expect(isObject(object)).toBe(true);
});
});
describe('without accessing File and Date classes', () => {
const NativeFile = File;
const NativeDate = Date;

beforeEach(() => {
Object.defineProperty(global, 'File', {
get() {
throw new Error('File should not have been accessed');
},
});
Object.defineProperty(global, 'Date', {
get() {
throw new Error('Date should not have been accessed');
},
});
});

afterEach(() => {
Object.defineProperty(global, 'File', NativeFile);
Object.defineProperty(global, 'Date', NativeDate);
});

it('returns false when a non-object is provided', () => {
NON_OBJECTS.forEach((nonObject: string | number | boolean | null | undefined) => {
expect(isObject(nonObject)).toBe(false);
});
});

it('returns true when an object is provided', () => {
OBJECTS.forEach((object: any) => {
expect(isObject(object)).toBe(true);
});
});
});
});

0 comments on commit 3c5539a

Please sign in to comment.