Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.2k
util: compact inspect() for sparse arrays#5070
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
Trott commented Feb 4, 2016
Thanks for the fix!
|
lib/util.js Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be explained in the comments. How this calculation determines if the array is sparse or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thefourtheye added a comment. If less than 1/10th of the slots in an array are populated, util.inspect / console.log now renders it compactly
var arr = [] arr[100] = 1 console.log(arr) Before:[ , , , , , (lots of commas) , 1 ]
After:[ 100:1 ]
6c3bd3a to d7b8af2Comparedcposch commented Feb 4, 2016
@Trott@thefourtheye sounds good, fixed |
65033e3 to 6821944Comparedcposch commented Feb 4, 2016
@Trott added test cases, LMK if these look dece vararr=[];arr[2]=1;// expect util.inspect() to return [ , , 1 ]arr[1000]=1;// expect [ 2: 1, 1000: 1, <sparse array, length 1001> ]')arr['foo']='bar';// expect [ 2: 1, 1000: 1, foo: 'bar', <sparse array, length 1001> ]arr=newArray(1000000);// expect [ <empty array, length 1000000> ] |
This prevents `console.log(arr)` from crashing node when given a sparse array with large length. Fixesnodejs#4905
6821944 to d257683Comparethefourtheye commented Feb 4, 2016
I think the sparse arrays are used only to prove the point. What happens when you use a dense array? |
dcposch commented Feb 4, 2016
@thefourtheye no, I think it's specifically about sparse arrays, where a small object can potentially lead to a huge
...by contrast there are lots of ways to make a large JSON produce a large |
dcposch commented Feb 4, 2016
Say you can crash a server by sending a 10GB POST, I think the fix is just to set request length limits. If you can crash a server by sending a 1KB POST which turns into a 10GB string internally, that's a bigger problem. |
thefourtheye commented Feb 4, 2016
Fair enough. But I am not sure if it is acceptable to special case it in the order of 10 like this. Lets hear from @nodejs/collaborators. |
mscdex commented Feb 4, 2016
Perhaps have something configurable like with |
thefourtheye commented Feb 4, 2016
+1 to @mscdex 's idea. If users want to see more data, they can explicitly adjust the value and invoke |
mcollina commented Feb 4, 2016
👍 for @mscdex idea, but with a default, something like |
vkurchatkin commented Feb 4, 2016
-1. We shouldn't treat sparse arrays differently |
mik01aj commented Feb 4, 2016
@vkurchatkin how would you fix the crash issue then? |
rvagg commented Feb 4, 2016
Not sure how I feel about this, surprising behaviour if you accidentally ran into it and I'm not sure it's intuitive although I guess the message helps. @vkurchatkin given that sparse arrays can kill Node, and this is an even more surprising and destructive behaviour, I'm not sure there's anything else we can do than treat large arrays differently. In terms of this actually fixing said issue, it only deals with sparse arrays, not large arrays. Consider: That won't be solved here |
mik01aj commented Feb 4, 2016
Maybe we should treat large (and not sparse) arrays differently. E.g.: if the array has more than 1000 elements, print a |
vkurchatkin commented Feb 4, 2016
exactly. printing very large array to console is not useful anyway |
dcposch commented Feb 4, 2016
I also think adding an What I was saying above is, that will not just apply to arrays -- it'll have to limit output of strings and objects as well. Doable but a bit involved, esp since To give an example of what that would entail, I think we'd have to add a functionformatProperty(ctx,value,recurseTimes,visibleKeys,key,array){varname,str,desc;desc=Object.getOwnPropertyDescriptor(value,key)||{value: value[key]};if(desc.get){if(desc.set){str=ctx.stylize('[Getter/Setter]','special');}else{str=ctx.stylize('[Getter]','special');}}else{if(desc.set){str=ctx.stylize('[Setter]','special');}}if(!hasOwnProperty(visibleKeys,key)){if(typeofkey==='symbol'){name='['+ctx.stylize(key.toString(),'symbol')+']';}else{name='['+key+']';}}if(!str){if(ctx.seen.indexOf(desc.value)<0){if(recurseTimes===null){str=formatValue(ctx,desc.value,null);}else{str=formatValue(ctx,desc.value,recurseTimes-1);}if(str.indexOf('\n')>-1){if(array){str=str.replace(/\n/g,'\n ');}else{str=str.replace(/(^|\n)/g,'\n ');}}}else{str=ctx.stylize('[Circular]','special');}}if(name===undefined){if(array&&key.match(/^\d+$/)){returnstr;}name=JSON.stringify(''+key);if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){name=name.substr(1,name.length-2);name=ctx.stylize(name,'name');}else{name=name.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'").replace(/\\\\/g,'\\');name=ctx.stylize(name,'string');}}returnname+': '+str;} |
dcposch commented Feb 4, 2016
This change is smaller and at least covers the small-HTTP-POST-crashing-node case. |
cjihrig commented Feb 4, 2016
That might not be a bad thing. The current algorithm for identifying sparse arrays seems pretty arbitrary. And, as pointed out, it doesn't do anything about large arrays. |
Trott commented Feb 4, 2016
This change is similar to the behavior of Chrome's console with sparse arrays. It may be useful to look and see what Blink/Chrome does to decide whether to do this special rendering or the usual expected rendering. EDIT: Specifically, how does Chrome/Blink decide that an array requires special rendering? |
jasnell commented Feb 4, 2016
curious if this would be a feature change or a fix? minor or patch? lts or no? |
cjihrig commented Feb 4, 2016
IMO it's a breaking change. |
dcposch commented Feb 8, 2016
@Trott just did some experimenting. In Chrome: So it looks like it prints a normal dense array for all indices starting from 0, then as soon as it gets to an index that is not set (which is not the same as an index whose corresponding value is If you want I can change this PR slightly to match that behavior. |
Trott commented Feb 8, 2016
@dcposch I don't have an opinion on that one way or the other, but someone else might. |
domenic commented Feb 8, 2016
Personally I can't understand how this is minor---what new feature does it introduce? It's either major (breaking change to existing feature) or patch (bugfix to existing feature). |
dcposch commented Feb 19, 2016
rvagg commented Feb 19, 2016
I'm finding it hard to conjure up much of an opinion on this one. @nodejs/collaborators anyone else want to champion this one through? I'd like to fix the crashes but am also concerned about how people might already be relying on |
mscdex commented Feb 19, 2016
As I previously mentioned, I wouldn't mind having a |
tunniclm commented Mar 21, 2016
EDIT: Oops, posted the comment to the wrong place. Moved to: #4905 (comment) |
rvagg commented Mar 22, 2016
Building on @tunniclm's suggestion that he's since moved, perhaps the easiest path forward on this one is to add an option to |
jasnell commented Apr 21, 2016
Looking at this again, I would find it difficult to justify leaving the current crash behavior as the default.
|
jasnell commented Apr 21, 2016
I've opened an alternative PR that takes a slightly different approach to this. See #6334 |
7da4fd4 to c7066fbComparebenjamingr commented Apr 30, 2016
I think consensus is going towards #6334 - is this still being pursued? |
jasnell commented Apr 30, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
I'd recommend closing this in favor of #6334 (but I'm a bit biased lol) |
benjamingr commented Apr 30, 2016
I think we can close this now and it can always be reopened. It seems stalled and there seems to be consensus is with the other proposal anyway. Feel free to reopen. |
As an alternative to nodejs#5070, set the max length of Arrays/TypedArrays in util.inspect() to `100` and provide a `maxArrayLength` option to override.
As an alternative to #5070, set the max length of Arrays/TypedArrays in util.inspect() to `100` and provide a `maxArrayLength` option to override. PR-URL: #6334 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Roman Reiss <[email protected]>
As an alternative to #5070, set the max length of Arrays/TypedArrays in util.inspect() to `100` and provide a `maxArrayLength` option to override. PR-URL: #6334 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Roman Reiss <[email protected]>
As an alternative to nodejs#5070, set the max length of Arrays/TypedArrays in util.inspect() to `100` and provide a `maxArrayLength` option to override. PR-URL: nodejs#6334 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Roman Reiss <[email protected]>
This prevents
console.log(arr)from crashing node when given a small sparse array with large lengthFixes#4905