Skip to content

Commit f0bd6e1

Browse files
authored
fix: exclude __proto__ from walk() (#2699)
[`__proto__`] is a special property to access an object's prototype. It has many pitfalls: - Setting it to an object value changes an object's prototype, which is generally discouraged and may be unexpected by the `iterator` callback. - Setting it to a non-object value does nothing (meaning `seen[k] = true` has no effect). - When Node.js is run with the [`--disable-proto=throw`] option, getting or setting `__proto__` causes an exception with code `ERR_PROTO_ACCESS` to be thrown. Additionally, since this property (and all properties of `Object.prototype`) are currently unused in this project by consumers of `walk()`, it is both safe and preferable to exclude. [`__proto__`]: https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.prototype.__proto__ [`--disable-proto=throw`]: https://nodejs.org/api/cli.html#disable-protomode Fixes: #2695 Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
1 parent 1f8afd5 commit f0bd6e1

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

src/sinon/util/core/walk.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ function walkInternal(obj, iterator, context, originalObj, seen) {
2828
}
2929

3030
forEach(Object.getOwnPropertyNames(obj), function (k) {
31-
if (seen[k] !== true) {
31+
// Skip __proto__ because:
32+
// - It's not currently useful in this project.
33+
// - It's automatic, problematic, and deprecated.
34+
// - Assigning to it has special effects (or no effect for non-object)
35+
// which may not be expected/handled properly by iterator callback.
36+
// - Getting it throws Error with node --disable-proto=throw.
37+
if (k !== "__proto__" && seen[k] !== true) {
3238
seen[k] = true;
3339
const target =
3440
typeof Object.getOwnPropertyDescriptor(obj, k).get ===

0 commit comments

Comments
 (0)