Skip to content

Commit cea8b42

Browse files
aduh95targos
authored andcommitted
lib: make IterableWeakMap safe to iterate
PR-URL: #38523 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 726cb48 commit cea8b42

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

lib/internal/util/iterable_weak_map.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,22 @@ class IterableWeakMap {
6565
return true;
6666
}
6767

68-
*[SymbolIterator]() {
69-
for (const ref of this.#refSet) {
70-
const key = ref.deref();
71-
if (!key) continue;
68+
[SymbolIterator]() {
69+
const iterator = this.#refSet[SymbolIterator]();
70+
71+
const next = () => {
72+
const result = iterator.next();
73+
if (result.done) return result;
74+
const key = result.value.deref();
75+
if (key == null) return next();
7276
const { value } = this.#weakMap.get(key);
73-
yield value;
74-
}
77+
return { done: false, value };
78+
};
79+
80+
return {
81+
[SymbolIterator]() { return this; },
82+
next,
83+
};
7584
}
7685
}
7786

test/parallel/test-internal-iterable-weak-map.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// Flags: --expose-gc --expose-internals
22
'use strict';
33

4-
require('../common');
4+
const common = require('../common');
55
const { deepStrictEqual, strictEqual } = require('assert');
66
const { IterableWeakMap } = require('internal/util/iterable_weak_map');
77

8+
// Ensures iterating over the map does not rely on methods which can be
9+
// mutated by users.
10+
Reflect.getPrototypeOf(function*() {}).prototype.next = common.mustNotCall();
11+
Reflect.getPrototypeOf(new Set()[Symbol.iterator]()).next =
12+
common.mustNotCall();
13+
814
// It drops entry if a reference is no longer held.
915
{
1016
const wm = new IterableWeakMap();

0 commit comments

Comments
 (0)