Skip to content

runtime: objectKey in obj never runs ToPropertyKey (only number keys are coerced) #6944

Description

@proggeramlug

Found while writing the #6941 regression suite (an assertion had to be dropped because of it). Nothing to do with GC — a plain spec gap, reproducible with zero allocation pressure.

js_object_has_property (crates/perry-runtime/src/object/field_get_set/has_property.rs) only runs ToPropertyKey when the key is a number:

let key = {
    let kv = JSValue::from_bits(key.to_bits());
    if kv.is_number() {
        unsafe { crate::object::js_to_property_key(key) }
    } else {
        key
    }
};

That number arm was added for Next.js's Number(digest.at(-2)) in RedirectStatusCode. But per spec RelationalExpression in ShiftExpression is ToPropertyKey(lval) for every key type, so an object key must have its Symbol.toPrimitive / toString / valueOf invoked. Today it is compared as a raw pointer and never matches.

Repro:

const obj: any = { here: 1 };
const k: any = { toString(): string { return "here"; } };
console.log("in with object key:", (k as any) in obj);
console.log("in with string key:", "here" in obj);

Node 26.5.0 (the pinned oracle):

in with object key: true
in with string key: true

Perry (main @ 0bb03e8):

in with object key: false
in with string key: true

Two things to get right in the fix:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions