Skip to content

Commit

Permalink
[utils] Update isPlainObject implementation
Browse files Browse the repository at this point in the history
This update adds support for checking plain object in non-v8/standard
runtimes as well (ie vercel edge-runtime)
  • Loading branch information
brijeshb42 authored and oliviertassinari committed Jan 7, 2024
1 parent 5518265 commit b891ccf
Show file tree
Hide file tree
Showing 6 changed files with 18,085 additions and 144 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
"tsx": "^4.7.0",
"typescript": "^5.3.3",
"typescript-to-proptypes": "workspace:^",
"vm-browserify": "^1.1.2",
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4",
Expand Down
19 changes: 15 additions & 4 deletions packages/mui-utils/src/deepmerge.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import { expect } from 'chai';
import { runInNewContext } from 'vm';
import deepmerge from './deepmerge';

describe('deepmerge', () => {
// https://snyk.io/blog/after-three-years-of-silence-a-new-jquery-prototype-pollution-vulnerability-emerges-once-again/
it('should not be subject to prototype pollution', () => {
deepmerge({}, JSON.parse('{ "myProperty": "a", "__proto__" : { "isAdmin" : true } }'), {
clone: false,
});
const result = deepmerge(
{},
JSON.parse('{ "myProperty": "a", "__proto__" : { "isAdmin" : true } }'),
{
clone: false,
},
);

expect(result).not.to.have.property('isAdmin');
});

expect({}).not.to.have.property('isAdmin');
it('should merge objects across realms', () => {
const vmObject = runInNewContext('({hello: "realm"})');
const result = deepmerge({ hello: 'original' }, vmObject);
expect(result.hello).to.equal('realm');
});

// https://github.com/mui/material-ui/issues/20095
Expand Down
14 changes: 13 additions & 1 deletion packages/mui-utils/src/deepmerge.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
// https://github.com/sindresorhus/is-plain-obj/blob/main/index.js
export function isPlainObject(item: unknown): item is Record<keyof any, unknown> {
return item !== null && typeof item === 'object' && item.constructor === Object;
if (typeof item !== 'object' || item === null) {
return false;
}

const prototype = Object.getPrototypeOf(item);
return (
(prototype === null ||
prototype === Object.prototype ||
Object.getPrototypeOf(prototype) === null) &&
!(Symbol.toStringTag in item) &&
!(Symbol.iterator in item)
);
}

export interface DeepmergeOptions {
Expand Down
Loading

0 comments on commit b891ccf

Please sign in to comment.