Skip to content
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

util: fix inspecting of proxy objects #6465

Closed
wants to merge 6 commits into from

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented Apr 29, 2016

Checklist
  • tests and code linting passes
  • a test and/or benchmark is included
  • the commit message follows commit guidelines
Affected core subsystem(s)

util

Description of change

In certain conditions (see #6464), inspecting a Proxy object can lead to a max call stack error. Avoid that by detecting the Proxy object and outputting information about the Proxy object itself.

Also adds util.isProxy()

Fixes: #6464

/cc @bnoordhuis

@jasnell jasnell added the util Issues and PRs related to the built-in util module. label Apr 29, 2016
@nodejs-github-bot nodejs-github-bot added the c++ Issues and PRs that require attention from people who are familiar with C++. label Apr 29, 2016
@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@MylesBorins
Copy link
Contributor

CI is green LGTM

@vkurchatkin
Copy link
Contributor

-1, the whole point of proxies is being transparent

@mscdex mscdex removed the c++ Issues and PRs that require attention from people who are familiar with C++. label Apr 29, 2016
@addaleax
Copy link
Member

the whole point of proxies is being transparent

That’s true for the programmatic use of proxies, but util.inspect comes with the intention of showing humans what is going on.

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@addaleax +1 . Note that getters/setters are also generally intended to be transparent for most cases but util.inspect will produce output like {a: [Getter]} which avoids similar stack-depth side effects... e.g.

var m = {};
Object.defineProperty(m, 'a', {
  enumerable: true,
  get: function() {
    console.log(this);
    return 5;
  }
});
util.inspect(m);
  // Returns `{a: [Getter]}`

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

(@thealphanerd ... what are you doing up at 2am reviewing code I wrote at 1am? Sleep my friend! Sleep!)

function isProxy(p) {
return binding.isProxy(p);
}
exports.isProxy = isProxy;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you export this, it becomes public API, and should be documented.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 ... Forgot to add the doc for it. Will add soon!
On Apr 29, 2016 6:29 AM, "Colin Ihrig" notifications@github.com wrote:

In lib/util.js
#6465 (comment):

@@ -785,6 +792,10 @@ exports.isPrimitive = isPrimitive;

exports.isBuffer = Buffer.isBuffer;

+function isProxy(p) {

  • return binding.isProxy(p);
    +}
    +exports.isProxy = isProxy;

If you export this, it becomes public API, and should be documented.


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
https://github.com/nodejs/node/pull/6465/files/3d4ff4311a3cf1ff756413756ffc859a663aba99#r61577439

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@cjihrig ... updated! PTAL

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

New CI after update: https://ci.nodejs.org/job/node-test-pull-request/2432/

@vkurchatkin vkurchatkin added the semver-major PRs that contain breaking changes and should be released in the next major version. label Apr 29, 2016

```js
const util = require('util');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary blank line.

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@cjihrig ... done! :-)

@vkurchatkin ... +1 on it being semver-major (unfortunately).

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@vkurchatkin ... would this be a bit more palatable if there were an option on util.inspect to turn off this special treatment of Proxy objects? e.g. util.inspect(proxyObj, {unwrapProxy: false});

require('../common');
const assert = require('assert');
const util = require('util');
const process_util = process.binding('util');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be camelCase.

@cjihrig
Copy link
Contributor

cjihrig commented Apr 29, 2016

LGTM pending CI, but it should sit for a couple days.

@vkurchatkin
Copy link
Contributor

would this be a bit more palatable if there were an option on util.inspect to turn off

@jasnell after some thinking, I agree with your reasoning. Having an option is nice, but in practice no one uses them

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@cjihrig +1 for letting it sit a couple days. There's definitely no rush on it.
@vkurchatkin ... awesome.

In certain conditions, inspecting a Proxy object can lead to a
max call stack error. Avoid that by detecting the Proxy object
and outputting information about the Proxy object itself.

Also adds util.isProxy()

Fixes: nodejs#6464
@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

@jasnell
Copy link
Member Author

jasnell commented Apr 29, 2016

CI is green. Will land on monday if there are no objections. /cc @nodejs/ctc

@Fishrock123
Copy link
Contributor

Fishrock123 commented Apr 29, 2016

Looks like this conflates two things:

  1. fixing inspect (which shouldn't be major)
  2. adding util.isProxy() (which we should not do given we don't even know what the hell do do with the existing functions: util: deprecate most of util.is*() #6235)

Please do not land in this state.

@Fishrock123
Copy link
Contributor

Oh shoot. I agree defaulting to false makes sense for that.

@jasnell
Copy link
Member Author

jasnell commented Apr 30, 2016

@@ -241,6 +242,41 @@ function inspectPromise(p) {


function formatValue(ctx, value, recurseTimes) {

if (ctx.showProxy &&
(typeof value === 'object' || typeof value === 'function')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should check that typeof value === 'object' && value !== null, I think?

Style nit: can you drop the blank line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

@jasnell
Copy link
Member Author

jasnell commented May 1, 2016

@bnoordhuis ... updated

// for it to get proper formatting, and because
// the target and handle objects also might be
// proxies... it's unfortunate but necessary.
proxyCache.set(proxy, undefined);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the logic but I don't think the 'necessary' is accurate; if you skipped adding proxy to the cache here, the algorithm would still work, only less efficiently. The next iteration would check the cache, miss, call .getProxyDetails() for the details array, and add the undefined return value to the cache a few lines below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary in the sense of avoiding an extraneous call to getProxyDetails... Which I would consider to be a bug since the point is to only check when we don't know for sure. ;)

@bnoordhuis
Copy link
Member

LGTM

@Fishrock123
Copy link
Contributor

CI after nits.. seems fine to me if others are happy with the details: https://ci.nodejs.org/job/node-test-pull-request/2459/

@jasnell
Copy link
Member Author

jasnell commented May 3, 2016

@thealphanerd and @cjihrig ... still LGTY?

@MylesBorins
Copy link
Contributor

LGTM

@cjihrig
Copy link
Contributor

cjihrig commented May 3, 2016

Yes, LGTM

jasnell added a commit that referenced this pull request May 3, 2016
In certain conditions, inspecting a Proxy object can lead to a
max call stack error. Avoid that by detecting the Proxy object
and outputting information about the Proxy object itself.

Fixes: #6464
PR-URL: #6465
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
@jasnell jasnell removed the wip Issues and PRs that are still a work in progress. label May 3, 2016
@jasnell
Copy link
Member Author

jasnell commented May 3, 2016

Landed in ba6196f.
Thank you all.

@jasnell jasnell closed this May 3, 2016
Fishrock123 pushed a commit that referenced this pull request May 4, 2016
In certain conditions, inspecting a Proxy object can lead to a
max call stack error. Avoid that by detecting the Proxy object
and outputting information about the Proxy object itself.

Fixes: #6464
PR-URL: #6465
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
joelostrowski pushed a commit to joelostrowski/node that referenced this pull request May 4, 2016
In certain conditions, inspecting a Proxy object can lead to a
max call stack error. Avoid that by detecting the Proxy object
and outputting information about the Proxy object itself.

Fixes: nodejs#6464
PR-URL: nodejs#6465
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Fishrock123 added a commit that referenced this pull request May 5, 2016
* assert: `deep{Strict}Equal()` now works correctly with circular
references. (Rich Trott) #6432
* debugger: Arrays are now formatted correctly in the debugger repl.
(cjihrig) #6448
* deps: Upgrade OpenSSL sources to 1.0.2h (Shigeki Ohtsu)
#6550
* net: Introduced a `Socket#connecting` property. (Fedor Indutny)
#6404
  - Previously this information was only available as the undocumented,
internal `_connecting` property.
* process: Introduced `process.cpuUsage()`. (Patrick Mueller)
#6157
* stream: `Writable#setDefaultEncoding()` now returns `this`.
(Alexander Makarenko) #5040
* util: Two new additions to `util.inspect()`:
  - Added a `maxArrayLength` option to truncate the formatting of
Arrays. (James M Snell) #6334
    - This is set to `100` by default.
  - Added a `showProxy` option for formatting proxy intercepting
handlers. (James M Snell) #6465
    - Inspecting proxies is non-trivial and as such this is off by
default.

PR-URL: #6557
Fishrock123 added a commit that referenced this pull request May 5, 2016
* assert: `deep{Strict}Equal()` now works correctly with circular
references. (Rich Trott) #6432
* debugger: Arrays are now formatted correctly in the debugger repl.
(cjihrig) #6448
* deps: Upgrade OpenSSL sources to 1.0.2h (Shigeki Ohtsu)
#6550
  - Please see our blog post for more info on the security contents of this release:
  - https://nodejs.org/en/blog/vulnerability/openssl-may-2016/
* net: Introduced a `Socket#connecting` property. (Fedor Indutny)
#6404
  - Previously this information was only available as the undocumented,
internal `_connecting` property.
* process: Introduced `process.cpuUsage()`. (Patrick Mueller)
#6157
* stream: `Writable#setDefaultEncoding()` now returns `this`.
(Alexander Makarenko) #5040
* util: Two new additions to `util.inspect()`:
  - Added a `maxArrayLength` option to truncate the formatting of
Arrays. (James M Snell) #6334
    - This is set to `100` by default.
  - Added a `showProxy` option for formatting proxy intercepting
handlers. (James M Snell) #6465
    - Inspecting proxies is non-trivial and as such this is off by
default.

PR-URL: #6557
Fishrock123 added a commit that referenced this pull request May 5, 2016
* assert: `deep{Strict}Equal()` now works correctly with circular
references. (Rich Trott) #6432
* debugger: Arrays are now formatted correctly in the debugger repl.
(cjihrig) #6448
* deps: Upgrade OpenSSL sources to 1.0.2h (Shigeki Ohtsu)
#6550
- Please see our blog post for more info on the security contents of
this release:
- https://nodejs.org/en/blog/vulnerability/openssl-may-2016/
* net: Introduced a `Socket#connecting` property. (Fedor Indutny)
#6404
- Previously this information was only available as the undocumented,
internal `_connecting` property.
* process: Introduced `process.cpuUsage()`. (Patrick Mueller)
#6157
* stream: `Writable#setDefaultEncoding()` now returns `this`.
(Alexander Makarenko) #5040
* util: Two new additions to `util.inspect()`:
- Added a `maxArrayLength` option to truncate the formatting of
Arrays. (James M Snell) #6334
- This is set to `100` by default.
- Added a `showProxy` option for formatting proxy intercepting
handlers. (James M Snell) #6465
- Inspecting proxies is non-trivial and as such this is off by
default.

PR-URL: #6557
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-minor PRs that contain new features and should be released in the next minor version. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants