[utils] Fix potential EMPTY_OBJECT mutation in useRenderElement#3986
[utils] Fix potential EMPTY_OBJECT mutation in useRenderElement#3986Jkker wants to merge 2 commits intomui:masterfrom
Conversation
Replace EMPTY_OBJECT fallback with a fresh empty object literal to prevent potential TypeError when setting ref, className, or style properties. EMPTY_OBJECT is frozen and mutations would fail in strict mode. Add tests to verify the fix handles edge cases with minimal props.
commit: |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Bundle size report
Check out the code infra dashboard for more information about this PR. |
|
@Jkker Is there a reason to keep the PR as a draft, or is it ready for merging? |
|
That variable could be renamed to |
Could we update the tests so they fail without the change to the source? |
| it('renders correctly with className when using minimal props', async () => { | ||
| const { container } = await render(<MinimalComponent className="custom-class" />); | ||
| const element = container.firstElementChild; | ||
| expect(element).to.have.attribute('class', 'custom-class'); |
There was a problem hiding this comment.
Looks like we could add this assertion after L282 (first test) and remove this almost duplicate test.
| it('renders correctly with style when using minimal props', async () => { | ||
| const { container } = await render(<MinimalComponent style={{ color: 'rgb(255, 0, 0)' }} />); | ||
| const element = container.firstElementChild as HTMLElement; | ||
| expect(element.style.color).to.equal('rgb(255, 0, 0)'); |
There was a problem hiding this comment.
The same comment applies here. Seems like this can be combined with the 2nd test.
Summary
This PR fixes a latent bug in
useRenderElementwhere the frozenEMPTY_OBJECTcould potentially be mutated, causing aTypeErrorin strict mode.The Problem
EMPTY_OBJECTis defined asObject.freeze({})- a frozen, immutable object. InuseRenderElementProps, there's a fallback path whereoutPropscould be assignedEMPTY_OBJECT:Later, the code attempts to mutate
outProps:If
mergeObjects()returnsundefined, mutations on the frozenEMPTY_OBJECTwould:Current Status
The bug is latent but not currently triggerable because
getStateAttributesProps()always returns a new{}. However, the code is fragile and any refactoring could surface this issue.The Fix
Replace
?? EMPTY_OBJECTwith?? {}to ensureoutPropsis always a fresh mutable object whenenabled=true.Tests Added