Skip to content

fix(patches): own-property lookups through a non-masking interceptor - #11

Merged
edusperoni merged 1 commit into
mainfrom
fix/nonmasking-own-lookup
Nov 12, 2026
Merged

edusperoni merged 1 commit into
mainfrom
fix/nonmasking-own-lookup

Conversation

@edusperoni

Copy link
Copy Markdown
Collaborator

Adds v8_nonmasking_own_lookup.patch, a fix for a V8 lookup bug reported upstream as crbug 585053531. The iOS runtime needs it for an upcoming wrapper lifetime mode that puts kNonMasking interceptors on ObjC instances.

The bug

If a receiver has a kNonMasking named interceptor and an object on its prototype chain has a named interceptor of its own, an own-property lookup on the receiver ends on that prototype instead of NOT_FOUND:

  • Object.hasOwn(obj, "m") is true for a prototype-only m, and getOwnPropertyDescriptor returns a descriptor with no value;
  • delete obj.m deletes m from the prototype, for every object sharing it;
  • obj.x = v and Object.defineProperty(obj, "x", …) reach the prototype's setter or definer interceptor instead of the receiver's.

In LookupIterator::NextInternal, the visibility walk means to skip the prototype's interceptor (WebIDL named-property visibility), but it continues inside do { } while (!IsFound()) while state_ is still INTERCEPTOR, so the loop exits on the prototype.

The patch

It steps past the invisible interceptor (or a passed access check) within the same holder, so that holder's real properties still count, and moves to the next holder only when nothing is found there. Indexed interceptors are no longer skipped, which is what upstream main has done since 892dda71342.

  • Applies cleanly to 14.9.207.39 alongside the existing patches; no file overlap.
  • Verified against the standalone repro in the upstream report (on an iOS simulator lite-mode build). Not run against V8's own test suite.
  • Applied on every platform: the bug is not platform-specific.

When upstream fixes it, the patch is dropped on the next V8 bump.

If a receiver has a kNonMasking named interceptor and an object on its
prototype chain has a named interceptor of its own, an own-property
lookup on the receiver ended on that prototype instead of NOT_FOUND.
LookupIterator::NextInternal meant to treat the prototype's interceptor
as invisible, but it `continue`d inside `do { } while (!IsFound())`
while the state was still INTERCEPTOR, so the walk stopped there.
Prototype properties then read as own, `delete obj.m` removed `m` from
the prototype, and sets and defineProperty reached the prototype's
interceptor instead of the receiver's.

v8_nonmasking_own_lookup.patch steps past the invisible interceptor (or
a passed access check) within the same holder, so its real properties
still count, and only moves on when nothing is found there. Indexed
interceptors are no longer skipped, matching upstream since
892dda71342. Reported upstream as crbug 585053531; applied on every
platform.

The iOS runtime's wrapper canary mode puts kNonMasking interceptors on
ObjC instances, whose prototypes already carry a named interceptor.
@coderabbitai

coderabbitai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2811ebf2-d50e-427a-ba9f-7893bc38d26e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@edusperoni
edusperoni marked this pull request as ready for review November 12, 2026 23:12
@edusperoni
edusperoni merged commit f77082c into main Nov 12, 2026
17 checks passed
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.

1 participant