Skip to content

SIGSEGV: iterating a values() override on a class X extends Map #7563

Description

@proggeramlug

A class X extends Map that overrides values() segfaults when the
override is iterated. The plain, non-overriding subclass is fine, so this is
specific to a user method shadowing a native collection method.

Repro

class MyMap<K, V> extends Map<K, V> {
    values(): IterableIterator<V> {
        return [777 as unknown as V][Symbol.iterator]();
    }
}

const m = new MyMap<string, number>();
m.set("q", 5);
console.log("size:", m.size);   // 1   — ok
console.log("get:", m.get("q")); // 5   — ok

const out: number[] = [];
for (const v of m.values()) out.push(v);   // <-- SIGSEGV here
console.log("values:", out.join(","));
console.log("done");
$ node --experimental-strip-types repro.ts
size: 1
get: 5
values: 777
done
rc=0

$ ./repro
size: 1
get: 5
rc=139            # SIGSEGV

The two lines before the loop print correctly, so construction, set and get
all work through the subclass; only the overridden values() faults.

class MyMap<K, V> extends Map<K, V> {} with no override runs correctly
and prints 1,2 for the same shape — the crash needs the shadowing method.

Related shapes (not crashes, but the same family)

Perry silently ignores every other way of replacing a Map's iteration, where
node honours all three. Verified against the node oracle:

shape node perry
Map.prototype.values = … then for (const v of m.values()) patched original
Map.prototype[Symbol.iterator] = … then for (const [k,v] of m) patched original
own-instance m.values = … then for (const v of m.values()) patched original

That is the same class as #7542 (Array.prototype[Symbol.iterator] ignored by
spread) and is a known consequence of the statically-typed collection fast
paths. It is recorded here for completeness — the crash is the actionable part.

Provenance

Found while building the semantics matrix for PR #7561 (map_1m iteration).
Reproduces identically at 969b447cc (main, v0.5.1315) and on that branch —
not introduced by either.

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