Skip to content

WeakValueMap: replacing an entry doesn't unregister the old value, causing erroneous deletion #1

@mvduin

Description

@mvduin

When replacing an existing entry of a WeakValueMap, the old value is not unregistered from the FinalizationRegistry so when it later get garbage-collected the corresponding entry gets erroneously deleted from the map.

Test case using node --expose-gc:

import { WeakValueMap } from 'weakref';
import assert from 'node:assert';

function next_job() {
    return new Promise( resolve => setImmediate( resolve ) );
}

let map = new WeakValueMap;

map.set( 42, {} );  // create entry pointing to fresh garbage

let x = {};

map.set( 42, x );  // overwrite entry with a strongly retained value

await next_job();  // release strong ref on new/dereferenced weakrefs
gc();  // garbage-collect the now-unreferenced old value
await next_job();  // fire finalization callback

assert.strictEqual( map.get( 42 ), x );  // FAILS
assert.strictEqual( map.size, 1 );  // FAILS

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