Skip to content

fix: exclude __proto__ from walk()#2699

Open
kevinoid wants to merge 1 commit intosinonjs:mainfrom
kevinoid:exclude-proto-from-walk
Open

fix: exclude __proto__ from walk()#2699
kevinoid wants to merge 1 commit intosinonjs:mainfrom
kevinoid:exclude-proto-from-walk

Conversation

@kevinoid
Copy link
Copy Markdown

Purpose (TL;DR) - mandatory

Fix issue #2695 by excluding __proto__ from walk().

Background (Problem in detail) - optional

__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, which causes issues like Change in 21.1: sinon.stub() throws with --disable-proto=throw #2695.

Solution - optional

Since __proto__ (and all properties of Object.prototype) are currently unused by consumers of walk() in this project, it is both safe and preferable to exclude it from enumeration by walk().

How to verify - mandatory

  1. Check out this branch
  2. npm install
  3. NODE_OPTIONS=--disable-proto=throw npm test

Checklist for author

  • npm run lint passes
  • References to standard library functions are cached.

Additional Work

It would be great if --disable-proto=throw could be added to the test suite, either by adding --node-option disable-proto=throw to the mocha invocation in test-node, or adding a separate run to test under these conditions. However, this may introduce an additional maintenance burden, so requires additional discussion and is not currently part of this PR.

Thanks for considering,
Kevin

[`__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: sinonjs#2695
Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant