Skip to content

fix(invert): use baseAssignValue for __proto__ key support#6233

Closed
neocrev wants to merge 1 commit into
lodash:mainfrom
neocrev:main
Closed

fix(invert): use baseAssignValue for __proto__ key support#6233
neocrev wants to merge 1 commit into
lodash:mainfrom
neocrev:main

Conversation

@neocrev

@neocrev neocrev commented Jun 11, 2026

Copy link
Copy Markdown

Description

Fixes #6195

Problem

_.invert and _.invertBy silently drop keys when the inverted value is __proto__:

_.invert({ userId: "alice", role: "__proto__", team: "eng" })
// Actual:   { alice: "userId", eng: "team" }
// Expected: { alice: "userId", __proto__: "role", eng: "team" }

The root cause is result[value] = key — when value is "__proto__", this triggers the __proto__ accessor on Object.prototype, setting the prototype instead of a data property.

Fix

Changed both invert and invertBy to use baseAssignValue instead of direct property assignment. baseAssignValue already has correct __proto__ handling via Object.defineProperty, consistent with the rest of lodash (e.g., mapKeys, merge, assign).

  • invert: result[value] = keybaseAssignValue(result, value, key)
  • invertBy: result[value] = [key]baseAssignValue(result, value, [key])

The hasOwnProperty.call(result, value) check in invertBy already works correctly for __proto__ (it checks own properties), so only the else branch needed changing.

Verification

_.invert({ userId: "alice", role: "__proto__", team: "eng" })
// => { alice: "userId", __proto__: "role", eng: "team" } ✅

_.invertBy({ a: "x", b: "__proto__", c: "x" })
// => { x: ["a", "c"], __proto__: ["b"] } ✅

_.invert and _.invertBy silently drop keys when the value becomes
'__proto__' because result['__proto__'] = value triggers the
__proto__ accessor instead of setting a data property.

Fix: use baseAssignValue which already handles __proto__ via
Object.defineProperty, consistent with the rest of lodash.

Fixes #6195
@neocrev neocrev closed this by deleting the head repository Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

_.invert and _invertBy removes key when _proto_ value

1 participant