Skip to content

Commit

Permalink
lib: make IterableWeakMap safe to iterate
Browse files Browse the repository at this point in the history
PR-URL: #38523
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
aduh95 authored and targos committed May 17, 2021
1 parent 1d9fd49 commit cf4dc80
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
21 changes: 15 additions & 6 deletions lib/internal/util/iterable_weak_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,22 @@ class IterableWeakMap {
return true;
}

*[SymbolIterator]() {
for (const ref of this.#refSet) {
const key = ref.deref();
if (!key) continue;
[SymbolIterator]() {
const iterator = this.#refSet[SymbolIterator]();

const next = () => {
const result = iterator.next();
if (result.done) return result;
const key = result.value.deref();
if (key == null) return next();
const { value } = this.#weakMap.get(key);
yield value;
}
return { done: false, value };
};

return {
[SymbolIterator]() { return this; },
next,
};
}
}

Expand Down
8 changes: 7 additions & 1 deletion test/parallel/test-internal-iterable-weak-map.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// Flags: --expose-gc --expose-internals
'use strict';

require('../common');
const common = require('../common');
const { deepStrictEqual, strictEqual } = require('assert');
const { IterableWeakMap } = require('internal/util/iterable_weak_map');

// Ensures iterating over the map does not rely on methods which can be
// mutated by users.
Reflect.getPrototypeOf(function*() {}).prototype.next = common.mustNotCall();
Reflect.getPrototypeOf(new Set()[Symbol.iterator]()).next =
common.mustNotCall();

// It drops entry if a reference is no longer held.
{
const wm = new IterableWeakMap();
Expand Down

0 comments on commit cf4dc80

Please sign in to comment.