Skip to content

Commit 800ef70

Browse files
committed
Add hasOwn into utils as safe replacement for hasOwnProperty
1 parent b51b046 commit 800ef70

File tree

7 files changed

+73
-7
lines changed

7 files changed

+73
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { render } from '@testing-library/react'
2+
console.error = jest.fn()
3+
4+
test('hasOwnProperty', async () => {
5+
'use strict'
6+
// Freeze Object.prototype to not accidentally export its properties again
7+
// see https://github.com/emotion-js/emotion/issues/3158
8+
Object.freeze(Object.prototype)
9+
10+
// Previous version:
11+
// const utils = (await import('../../dist/emotion-element-48d2c2e4.cjs.dev.js'))
12+
// .default
13+
14+
// Current version:
15+
// const utils = (await import('../../dist/emotion-element-e909c831.cjs.dev'))
16+
// .default
17+
18+
// console.log(utils)
19+
// expect(
20+
// Object.prototype.hasOwnProperty.call(utils, 'hasOwnProperty')
21+
// ).toBeFalsy()
22+
23+
const element = await import('../../dist/emotion-react.worker.esm.js').default
24+
console.log(element)
25+
expect(
26+
Object.prototype.hasOwnProperty.call(element, 'hasOwnProperty')
27+
).toBeFalsy()
28+
29+
// /** @jsx jsx */
30+
// const { jsx } = await import('@emotion/react')
31+
// // const { CacheProvider } = await import('@emotion/react')
32+
// const { CacheProvider } = await import('../../dist/emotion-react.cjs.dev.js')
33+
// const createCache = await (await import('@emotion/cache')).default
34+
35+
// const cache = createCache({ key: 'context' })
36+
// render(<CacheProvider cache={cache} />)
37+
expect(console.error).not.toHaveBeenCalled()
38+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { render } from '@testing-library/react'
2+
console.error = jest.fn()
3+
4+
test('hasOwnProperty', async () => {
5+
// Freeze Object.prototype to not accidentally export its properties again
6+
// see https://github.com/emotion-js/emotion/issues/3158
7+
Object.freeze(Object.prototype)
8+
9+
// const utils = (await import('../../dist/emotion-react.cjs.dev.js')).default
10+
// Previous version:
11+
// const utils = (await import('../../dist/emotion-element-48d2c2e4.cjs.dev.js'))
12+
// .default
13+
14+
// Current version:
15+
const utils = (await import('../../dist/emotion-element-e909c831.cjs.dev'))
16+
.default
17+
18+
expect(
19+
Object.prototype.hasOwnProperty.call(utils, 'hasOwnProperty')
20+
).toBeFalsy()
21+
22+
expect(console.error).not.toHaveBeenCalled()
23+
})

packages/react/src/emotion-element.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
insertStyles,
88
registerStyles
99
} from '@emotion/utils'
10-
import { isBrowser } from './utils'
10+
import { hasOwn, isBrowser } from './utils'
1111
import { serializeStyles } from '@emotion/serialize'
1212
import { getLabelFromStackTrace } from './get-label-from-stack-trace'
1313
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
@@ -31,7 +31,7 @@ export const createEmotionProps = (type: React.ElementType, props: Object) => {
3131
let newProps: any = {}
3232

3333
for (let key in props) {
34-
if (Object.hasOwn(props, key)) {
34+
if (hasOwn(props, key)) {
3535
newProps[key] = props[key]
3636
}
3737
}
@@ -133,7 +133,7 @@ let Emotion = /* #__PURE__ */ withEmotionCache<any, any>(
133133
const newProps = {}
134134
for (let key in props) {
135135
if (
136-
Object.hasOwn(props, key) &&
136+
hasOwn(props, key) &&
137137
key !== 'css' &&
138138
key !== typePropName &&
139139
(process.env.NODE_ENV === 'production' || key !== labelPropName)

packages/react/src/jsx-dev-runtime.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @flow
22
import * as ReactJSXRuntimeDev from 'react/jsx-dev-runtime'
33
import Emotion, { createEmotionProps } from './emotion-element'
4+
import { hasOwn } from './utils'
45

56
export const Fragment = ReactJSXRuntimeDev.Fragment
67

@@ -12,7 +13,7 @@ export function jsxDEV(
1213
source: any,
1314
self: any
1415
) {
15-
if (!Object.hasOwn(props, 'css')) {
16+
if (!hasOwn(props, 'css')) {
1617
return ReactJSXRuntimeDev.jsxDEV(
1718
type,
1819
props,

packages/react/src/jsx-runtime.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
// @flow
22
import * as ReactJSXRuntime from 'react/jsx-runtime'
33
import Emotion, { createEmotionProps } from './emotion-element'
4+
import { hasOwn } from './utils'
45

56
export const Fragment = ReactJSXRuntime.Fragment
67

78
export function jsx(type: any, props: any, key: any) {
8-
if (!Object.hasOwn(props, 'css')) {
9+
if (!hasOwn(props, 'css')) {
910
return ReactJSXRuntime.jsx(type, props, key)
1011
}
1112

1213
return ReactJSXRuntime.jsx(Emotion, createEmotionProps(type, props), key)
1314
}
1415

1516
export function jsxs(type: any, props: any, key: any) {
16-
if (!Object.hasOwn(props, 'css')) {
17+
if (!hasOwn(props, 'css')) {
1718
return ReactJSXRuntime.jsxs(type, props, key)
1819
}
1920

packages/react/src/jsx.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @flow
22
import * as React from 'react'
33
import Emotion, { createEmotionProps } from './emotion-element'
4+
import { hasOwn } from './utils'
45

56
// $FlowFixMe
67
export const jsx: typeof React.createElement = function (
@@ -9,7 +10,7 @@ export const jsx: typeof React.createElement = function (
910
) {
1011
let args = arguments
1112

12-
if (props == null || !Object.hasOwn(props, 'css')) {
13+
if (props == null || !hasOwn(props, 'css')) {
1314
// $FlowFixMe
1415
return React.createElement.apply(undefined, args)
1516
}

packages/react/src/utils.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
// @flow
22
export let isBrowser = typeof document !== 'undefined'
3+
4+
export const hasOwn = Object.hasOwn

0 commit comments

Comments
 (0)