Skip to content

fix: accessor descriptors from Proxy getOwnPropertyDescriptor trap - #1658

Open
NathanWalker wants to merge 1 commit into
quickjs-ng:masterfrom
NathanWalker:fix/proxy-accessor-descriptor-flags
Open

fix: accessor descriptors from Proxy getOwnPropertyDescriptor trap#1658
NathanWalker wants to merge 1 commit into
quickjs-ng:masterfrom
NathanWalker:fix/proxy-accessor-descriptor-flags

Conversation

@NathanWalker

Copy link
Copy Markdown

js_obj_to_desc() returns defineProperty-style flags (JS_PROP_HAS_GET / JS_PROP_HAS_SET, never JS_PROP_GETSET), but js_proxy_get_own_property() published the parsed trap result unconverted. Descriptor consumers test JS_PROP_GETSET, so any accessor descriptor returned by a getOwnPropertyDescriptor trap degraded to a data descriptor { value: undefined, writable: false }.

Convert the flags to own-property form before publishing, per the CompletePropertyDescriptor(resultDesc) step of Proxy [[GetOwnProperty]]:

    const t = {};
    Object.defineProperty(t, 'x', { configurable: true, get() { return 42; } });
    const p = new Proxy(t, { getOwnPropertyDescriptor: Reflect.getOwnPropertyDescriptor });
    Object.getOwnPropertyDescriptor(p, 'x');
    // before: { value: undefined, writable: false, ... }
    // after:  { get: [Function], set: undefined, ... }

Embedders exposing host objects through descriptor-trap proxies hit this in practice (eg, NativeScript's iOS runtime did).

js_obj_to_desc() returns defineProperty-style flags (JS_PROP_HAS_GET / JS_PROP_HAS_SET, never JS_PROP_GETSET), but js_proxy_get_own_property() published the parsed trap result unconverted. Descriptor consumers test JS_PROP_GETSET, so any accessor descriptor returned by a getOwnPropertyDescriptor trap degraded to a data descriptor { value: undefined, writable: false }.

Convert the flags to own-property form before publishing, per the CompletePropertyDescriptor(resultDesc) step of Proxy [[GetOwnProperty]]:

```
    const t = {};
    Object.defineProperty(t, 'x', { configurable: true, get() { return 42; } });
    const p = new Proxy(t, { getOwnPropertyDescriptor: Reflect.getOwnPropertyDescriptor });
    Object.getOwnPropertyDescriptor(p, 'x');
    // before: { value: undefined, writable: false, ... }
    // after:  { get: [Function], set: undefined, ... }
```

Embedders exposing host objects through descriptor-trap proxies hit this in practice (eg, NativeScript's iOS runtime did).
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