Skip to content

Commit

Permalink
fix freezing of Map values during finalization
Browse files Browse the repository at this point in the history
Map keys are not enumerable properties of the Map object, so the propertyIsEnumerable check does not apply to them.

This commit adds a condition to detect Map objects and uses Map.prototype.has to check for key existence.

Fixes immerjs#1119.
  • Loading branch information
chetan-satpute committed Nov 15, 2024
1 parent 19cbe47 commit 29054cc
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
2 changes: 2 additions & 0 deletions __tests__/frozen.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,12 @@ function runTests(name) {

const res = produce(base, draft => {
draft.set("a", 1)
draft.set("o", {b: 1})
})
expect(() => res.set("b", 2)).toThrowErrorMatchingSnapshot()
expect(() => res.clear()).toThrowErrorMatchingSnapshot()
expect(() => res.delete("b")).toThrowErrorMatchingSnapshot()
expect(Object.isFrozen(res.get("o"))).toBe(true)

// In draft, still editable
expect(produce(res, d => void d.set("a", 2))).not.toBe(res)
Expand Down
7 changes: 5 additions & 2 deletions src/core/finalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
getPlugin,
die,
revokeScope,
isFrozen
isFrozen,
isMap
} from "../internal"

export function processResult(result: any, scope: ImmerScope) {
Expand Down Expand Up @@ -151,7 +152,9 @@ function finalizeProperty(
if (
(!parentState || !parentState.scope_.parent_) &&
typeof prop !== "symbol" &&
Object.prototype.propertyIsEnumerable.call(targetObject, prop)
(isMap(targetObject)
? targetObject.has(prop)
: Object.prototype.propertyIsEnumerable.call(targetObject, prop))
)
maybeFreeze(rootScope, childValue)
}
Expand Down

0 comments on commit 29054cc

Please sign in to comment.