Skip to content

Unexpected access to getter property in irrelevant plain objects #1012

@zthxxx

Description

@zthxxx

🙋‍♂ Question

Here is two question, when will a plain object contain drafts in the recursively finalize function?

I think a plain object here always means not modify in produce() and not create by immer proxy, maybe move a proxy draft property into new object then add it back to draft's new property field?

image

// A plain object, might need freezing, might contain drafts
if (!state) {
each(
value,
(key, childValue) =>
finalizeProperty(rootScope, state, value, key, childValue, path),
true // See #590, don't recurse into non-enumerable of non drafted objects
)
return value
}

Is that the only thing need to do in this condition for plain object is maybeFreeze(rootScope, value, true) rather than each(finalizeProperty(...))) ?

I think this is the reason to cause some UNEXPECTED access to getter property in an irrelevant plain object when produce() returns result, which will have some side effects.

The problem case like below:

image

Link to repro

To reproduce: https://stackblitz.com/edit/node-pgmcfz?file=immer-getter-without-freeze.mjs

Environment

  • Immer version: 9.0.17
  • Occurs with setUseProxies(true)
  • Occurs with setUseProxies(false) (ES5 only)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions