-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow cloning WeakMaps/WeakSets with .from
#26
Comments
It looks wrong for me and somehow related to removing of |
They could still do that - by copying the internal slots over, for example. |
In this case, it's also will be a performance problem. But IIRC it's only one of many reasons for removing |
@ljharb BTW, for example, it's our primitive slot-based class WeakMap {
static #ids = Symbol();
#id = Symbol();
constructor(init) {
if (init) for (const el of init) this.set(el[0], el[1]);
}
delete(key) {
if (key[WeakMap.#ids]) return key[WeakMap.#ids].delete(this.#id);
}
get(key) {
if (key[WeakMap.#ids]) return key[WeakMap.#ids].get(this.#id);
}
has(key) {
return !!key[WeakMap.#ids] && key[WeakMap.#ids].has(this.#id);
}
set(key, value) {
if (!hasOwnProperty.call(key, WeakMap.#ids)) {
Object.defineProperty(key, WeakMap.#ids, { value: new Map() });
}
key[WeakMap.#ids].set(this.#id, value);
return this;
}
} How do you implement cloning without performance degradation (at least on cloned weak maps)? |
static from(weakMap) {
const wm = new WeakMap():
wm[ids] = weakMap[ids];
return wm;
} |
And, in this case, any changes on clone affect original, on original - clone (if I understood your idea correctly, since |
Ah, that's true. In that case, there's no way to avoid enumeration for a polyfill, but performance considerations of userland implementations don't tend to hold much weight when designing a feature, historically. |
One more time - it's not about userland, it's about engines implementations which works in this way, see my first comment. |
I'd be happy to hear from engine implementors if that in fact is a concern. |
I don't know how it works in popular engines, but at least it will cause problems for developers of new engines. Also interesting opinions of implementors -) |
Also, it will cause some security issues. For example: // frozen env where we can't patch WeakSet and methods
// somehow we got access to a weakset
const clone = WeakSet.from(weakset);
// sometime later the `weakset` is cleared or just `object` key removed from it
// and now we have access to the `object`
clone.has(object);
// we could know that the `object` was in the `weakset` in the moment of creating a clone It's far-fetched, but the idea of |
I agree that this is a capability which was not previous present, but I don't think it's likely to be a security issue. The important guarantee that a WeakMap provides is that having the map does not allow you to access its contents. That guarantee is preserved. |
In this case, making all private fields public in the next version of an abstract language is not a security issue, just a new possibility. I think that it should solve the committee. |
... what? |
|
I don't think this makes keys observable |
It makes keys observable, an example above. |
If you have |
The example above does not demonstrate keys being observable. |
@ljharb at the moment of creation clone we haven't access to the |
@bakkot one more time - lets the committee solve is this a security issue or not. In my opinion - yes, since I see some places where it can be exploited. |
I see what you're saying, but you also can't know if someone did |
@ljharb since we create a |
Currently
WeakMap.from(x)
requiresx
to be an iterable, whichWeakMap
s are not. It might make sense to allowx
to be aWeakMap
, in which caseWeakMap.from(x)
would return a copy ofx
. That's not currently possible in the language, but I am pretty confident it wouldn't violate any important guarantees.Alternatively, we might say that
WeakSet.prototype.union
(see tc39/proposal-set-methods#23) is the right place for that ability. I am neutral on that question.The text was updated successfully, but these errors were encountered: