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 committed Nov 28, 2023
1 parent 6344978 commit 92ece07
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
"ts-node": "^10.9.1",
"tslint": "5.14.0",
"typescript": "^5.1.6",
"vm-browserify": "^1.1.2",
"webpack": "^5.88.2",
"webpack-bundle-analyzer": "^4.9.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
1 change: 1 addition & 0 deletions test/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ module.exports = function setKarmaConfig(config) {
stream: false,
// required by enzyme > cheerio > parse5
util: require.resolve('util/'),
vm: require.resolve('vm-browserify'),
},
},
// TODO: 'browserslist:modern'
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17417,6 +17417,11 @@ vlq@^0.2.2:
resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==

vm-browserify@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==

void-elements@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
Expand Down

0 comments on commit 92ece07

Please sign in to comment.