Skip to content

A function referenced inside its own module is a different object from the same function imported elsewhere: export function isSame(x){ return x === f } returns false for the imported f #10554

Description

@proggeramlug

Found by the package audit (while fixing #10434) on Perry 7661bc0 (v0.5.1587→v0.5.1589 baseline), Linux x64.
A module-level function f compared by identity inside its defining module is not === to the f value an importer
receives, although two importers' views agree with each other (ns.f === f is true in the importer).

Reproduction

lib/fns.ts:

function f() { return 1; }
export function isSame(x: unknown) { return x === f; }
export { f };

main.ts:

import { f, isSame } from "./lib/fns.ts";
import * as ns from "./lib/fns.ts";
console.log(isSame(f), isSame(ns.f), ns.f === f);
node main.ts
PERRY_NO_AUTO_OPTIMIZE=1 perry compile main.ts -o main && ./main

Expected (Node 26.5.1)

true true true

Actual (Perry)

false false true

Impact

Identity checks against a module's own exported functions are common: registries and caches keyed by function
(map.get(handler)), "is this our default implementation" checks (if (opts.serialize === defaultSerialize)),
removeEventListener/off(fn) with an exported listener, memoization keyed by function, and plugin dedup. With
Perry these silently take the wrong branch or fail to remove listeners.

Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    package-auditFound by the 2026 package audit: compiling real npm packages from source instead of native bindings

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions