ITADN

apply() fails to replay patches when intermediate keys are non-string (Map object keys / symbol keys)

#150Openunadlib 创建于 2025-10-07
U
unadlibcommented
### Description `apply()` currently coerces every intermediate path segment to a string while walking the patch path. When the patch targets data indexed by a non-string key—such as object keys in Map or Symbol keys on plain objects—the coerced lookup fails and `apply()` throws Cannot apply patch at .... This breaks replaying patches generated via create(..., { enablePatches: true }) for these structures. ### Reproduction ```js import { create, apply } from 'mutative'; const key = { id: 1 }; const base = { map: new Map([[key, { value: 1 }]]) }; const [nextState, patches] = create( base, (draft) => { draft.map.get(key)!.value = 2; }, { enablePatches: true } ); // Throws: Cannot apply patch at 'map/[object Object]/value' apply(base, patches); ``` A similar failure occurs for symbol-keyed objects: ```js const sym = Symbol('k'); const base = { obj: { [sym]: { value: 1 } } }; const [nextState, patches] = create( base, (draft) => { draft.obj[sym].value = 2; }, { enablePatches: true } ); apply(base, patches); // throws ``` ### Expected behavior `apply()` should preserve the original key type when traversing intermediate path segments so that patches generated for Maps with object keys or symbol-keyed objects can be replayed successfully. ### Actual behavior Intermediate keys are stringified in src/apply.ts, so lookups against Maps / symbol keys fail, causing `apply()` to throw Cannot apply patch at .... ### Environment - mutative 1.3.0 (source src/apply.ts) - Node.js ≥14 ### Proposed fix Retain the original key type during path traversal and only guard against __proto__ / constructor when the parent is an object/array or function prototype to avoid prototype pollution. Add regression tests covering object-keyed Maps and symbol-keyed objects to ensure patch replay works end-to-end.
0 条评论