Skip to content

Commit 9e6d6ce

Browse files
BridgeARaduh95
authored andcommitted
util: mark special properties when inspecting them
This makes sure special properties (such as a byteLength, buffer, and more) are marked that they are not regular properties. They are mostly getters, that just seemed even more of a breaking change. Thus, they just use square brackets for now. On top of that, it makes inspecting detached DataViews robust. Inspecting those failed so far. PR-URL: #60131 Reviewed-By: Jordan Harband <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 8a6de38 commit 9e6d6ce

File tree

3 files changed

+103
-79
lines changed

3 files changed

+103
-79
lines changed

‎lib/internal/util/inspect.js‎

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ const{
111111
StringPrototypeSplit,
112112
StringPrototypeStartsWith,
113113
StringPrototypeToLowerCase,
114-
StringPrototypeTrim,
115114
StringPrototypeValueOf,
116115
SymbolIterator,
117116
SymbolPrototypeToString,
@@ -1223,6 +1222,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray){
12231222
constfilter=ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE;
12241223

12251224
letextrasType=kObjectType;
1225+
letextraKeys;
12261226

12271227
// Iterators and the rest are split to reduce checks.
12281228
// We have to check all values in case the constructor is set to null.
@@ -1278,6 +1278,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray){
12781278
// bound function is required to reconstruct missing information.
12791279
formatter=FunctionPrototypeBind(formatTypedArray,null,bound,size);
12801280
extrasType=kArrayExtrasType;
1281+
1282+
if(ctx.showHidden){
1283+
extraKeys=['BYTES_PER_ELEMENT','length','byteLength','byteOffset','buffer'];
1284+
typedArray=true;
1285+
}
12811286
}elseif(isMapIterator(value)){
12821287
keys=getKeys(value,ctx.showHidden);
12831288
braces=getIteratorBraces('Map',tag);
@@ -1347,14 +1352,14 @@ function formatRaw(ctx, value, recurseTimes, typedArray){
13471352
formatter=formatArrayBuffer;
13481353
}elseif(keys.length===0&&protoProps===undefined){
13491354
returnprefix+
1350-
`{byteLength: ${formatNumber(ctx.stylize,value.byteLength,false)} }`;
1355+
`{[byteLength]: ${formatNumber(ctx.stylize,value.byteLength,false)} }`;
13511356
}
13521357
braces[0]=`${prefix}{`;
1353-
ArrayPrototypeUnshift(keys,'byteLength');
1358+
extraKeys=['byteLength'];
13541359
}elseif(isDataView(value)){
13551360
braces[0]=`${getPrefix(constructor,tag,'DataView')}{`;
13561361
// .buffer goes last, it's not a primitive like the others.
1357-
ArrayPrototypeUnshift(keys,'byteLength','byteOffset','buffer');
1362+
extraKeys=['byteLength','byteOffset','buffer'];
13581363
}elseif(isPromise(value)){
13591364
braces[0]=`${getPrefix(constructor,tag,'Promise')}{`;
13601365
formatter=formatPromise;
@@ -1404,6 +1409,18 @@ function formatRaw(ctx, value, recurseTimes, typedArray){
14041409
constindentationLvl=ctx.indentationLvl;
14051410
try{
14061411
output=formatter(ctx,value,recurseTimes);
1412+
if(extraKeys!==undefined){
1413+
for(i=0;i<extraKeys.length;i++){
1414+
letformatted;
1415+
try{
1416+
formatted=formatExtraProperties(ctx,value,recurseTimes,extraKeys[i],typedArray);
1417+
}catch{
1418+
consttempValue={[extraKeys[i]]: value.buffer[extraKeys[i]]};
1419+
formatted=formatExtraProperties(ctx,tempValue,recurseTimes,extraKeys[i],typedArray);
1420+
}
1421+
ArrayPrototypePush(output,formatted);
1422+
}
1423+
}
14071424
for(i=0;i<keys.length;i++){
14081425
ArrayPrototypePush(
14091426
output,
@@ -2263,11 +2280,15 @@ function formatArrayBuffer(ctx, value){
22632280
}
22642281
if(hexSlice===undefined)
22652282
hexSlice=uncurryThis(require('buffer').Buffer.prototype.hexSlice);
2266-
letstr=StringPrototypeTrim(RegExpPrototypeSymbolReplace(
2267-
/(.{2})/g,
2268-
hexSlice(buffer,0,MathMin(ctx.maxArrayLength,buffer.length)),
2269-
'$1 ',
2270-
));
2283+
constrawString=hexSlice(buffer,0,MathMin(ctx.maxArrayLength,buffer.length));
2284+
letstr='';
2285+
leti=0;
2286+
for(;i<rawString.length-2;i+=2){
2287+
str+=`${rawString[i]}${rawString[i+1]} `;
2288+
}
2289+
if(rawString.length>0){
2290+
str+=`${rawString[i]}${rawString[i+1]}`;
2291+
}
22712292
constremaining=buffer.length-ctx.maxArrayLength;
22722293
if(remaining>0)
22732294
str+=` ... ${remaining} more byte${remaining>1 ? 's' : ''}`;
@@ -2294,7 +2315,7 @@ function formatArray(ctx, value, recurseTimes){
22942315
returnoutput;
22952316
}
22962317

2297-
functionformatTypedArray(value,length,ctx,ignored,recurseTimes){
2318+
functionformatTypedArray(value,length,ctx){
22982319
constmaxLength=MathMin(MathMax(0,ctx.maxArrayLength),length);
22992320
constremaining=value.length-maxLength;
23002321
constoutput=newArray(maxLength);
@@ -2307,22 +2328,6 @@ function formatTypedArray(value, length, ctx, ignored, recurseTimes){
23072328
if(remaining>0){
23082329
output[maxLength]=remainingText(remaining);
23092330
}
2310-
if(ctx.showHidden){
2311-
// .buffer goes last, it's not a primitive like the others.
2312-
// All besides `BYTES_PER_ELEMENT` are actually getters.
2313-
ctx.indentationLvl+=2;
2314-
for(constkeyof[
2315-
'BYTES_PER_ELEMENT',
2316-
'length',
2317-
'byteLength',
2318-
'byteOffset',
2319-
'buffer',
2320-
]){
2321-
conststr=formatValue(ctx,value[key],recurseTimes,true);
2322-
ArrayPrototypePush(output,`[${key}]: ${str}`);
2323-
}
2324-
ctx.indentationLvl-=2;
2325-
}
23262331
returnoutput;
23272332
}
23282333

@@ -2470,12 +2475,20 @@ function formatPromise(ctx, value, recurseTimes){
24702475
returnoutput;
24712476
}
24722477

2478+
functionformatExtraProperties(ctx,value,recurseTimes,key,typedArray){
2479+
ctx.indentationLvl+=2;
2480+
conststr=formatValue(ctx,value[key],recurseTimes,typedArray);
2481+
ctx.indentationLvl-=2;
2482+
2483+
// These entries are mainly getters. Should they be formatted like getters?
2484+
returnctx.stylize(`[${key}]: ${str}`,'string');
2485+
}
2486+
24732487
functionformatProperty(ctx,value,recurseTimes,key,type,desc,
24742488
original=value){
24752489
letname,str;
24762490
letextra=' ';
2477-
desc||=ObjectGetOwnPropertyDescriptor(value,key)||
2478-
{value: value[key],enumerable: true};
2491+
desc??=ObjectGetOwnPropertyDescriptor(value,key);
24792492
if(desc.value!==undefined){
24802493
constdiff=(ctx.compact!==true||type!==kObjectType) ? 2 : 3;
24812494
ctx.indentationLvl+=diff;

‎test/parallel/test-util-format.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ assert.strictEqual(
588588

589589
assert.strictEqual(
590590
util.format(newSharedArrayBuffer(4)),
591-
'SharedArrayBuffer{[Uint8Contents]: <00 00 00 00>, byteLength: 4 }'
591+
'SharedArrayBuffer{[Uint8Contents]: <00 00 00 00>, [byteLength]: 4 }'
592592
);
593593

594594
assert.strictEqual(

‎test/parallel/test-util-inspect.js‎

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -172,56 +172,67 @@ assert.doesNotMatch(
172172
constdv=newDataView(ab,1,2);
173173
assert.strictEqual(
174174
util.inspect(ab,showHidden),
175-
'ArrayBuffer{[Uint8Contents]: <01 02 03 04>, byteLength: 4 }'
175+
'ArrayBuffer{[Uint8Contents]: <01 02 03 04>, [byteLength]: 4 }'
176176
);
177177
assert.strictEqual(util.inspect(newDataView(ab,1,2),showHidden),
178178
'DataView{\n'+
179-
' byteLength: 2,\n'+
180-
' byteOffset: 1,\n'+
181-
' buffer: ArrayBuffer{'+
182-
' [Uint8Contents]: <01 02 03 04>, byteLength: 4 }\n}');
179+
' [byteLength]: 2,\n'+
180+
' [byteOffset]: 1,\n'+
181+
' [buffer]: ArrayBuffer{'+
182+
' [Uint8Contents]: <01 02 03 04>, [byteLength]: 4 }\n}');
183183
assert.strictEqual(
184184
util.inspect(ab,showHidden),
185-
'ArrayBuffer{[Uint8Contents]: <01 02 03 04>, byteLength: 4 }'
185+
'ArrayBuffer{[Uint8Contents]: <01 02 03 04>, [byteLength]: 4 }'
186186
);
187187
assert.strictEqual(util.inspect(dv,showHidden),
188188
'DataView{\n'+
189-
' byteLength: 2,\n'+
190-
' byteOffset: 1,\n'+
191-
' buffer: ArrayBuffer{[Uint8Contents]: '+
192-
'<01 02 03 04>, byteLength: 4 }\n}');
189+
' [byteLength]: 2,\n'+
190+
' [byteOffset]: 1,\n'+
191+
' [buffer]: ArrayBuffer{[Uint8Contents]: '+
192+
'<01 02 03 04>, [byteLength]: 4 }\n}');
193193
ab.x=42;
194194
dv.y=1337;
195195
assert.strictEqual(util.inspect(ab,showHidden),
196196
'ArrayBuffer{[Uint8Contents]: <01 02 03 04>, '+
197-
'byteLength: 4, x: 42 }');
198-
assert.strictEqual(util.inspect(dv,showHidden),
197+
'[byteLength]: 4, x: 42 }');
198+
assert.strictEqual(util.inspect(dv,{showHidden,breakLength: 82}),
199199
'DataView{\n'+
200-
' byteLength: 2,\n'+
201-
' byteOffset: 1,\n'+
202-
' buffer: ArrayBuffer{[Uint8Contents]: <01 02 03 04>,'+
203-
' byteLength: 4, x: 42 },\n'+
200+
' [byteLength]: 2,\n'+
201+
' [byteOffset]: 1,\n'+
202+
' [buffer]: ArrayBuffer{[Uint8Contents]: <01 02 03 04>,'+
203+
' [byteLength]: 4, x: 42 },\n'+
204204
' y: 1337\n}');
205205
}
206206

207207
{
208208
constab=newArrayBuffer(42);
209+
constdv=newDataView(ab);
210+
209211
assert.strictEqual(ab.byteLength,42);
210212
newMessageChannel().port1.postMessage(ab,[ab]);
211213
assert.strictEqual(ab.byteLength,0);
212214
assert.strictEqual(util.inspect(ab),
213-
'ArrayBuffer{(detached), byteLength: 0 }');
215+
'ArrayBuffer{(detached), [byteLength]: 0 }');
216+
217+
assert.strictEqual(
218+
util.inspect(dv),
219+
'DataView{\n'+
220+
' [byteLength]: 0,\n'+
221+
' [byteOffset]: undefined,\n'+
222+
' [buffer]: ArrayBuffer{(detached), [byteLength]: 0 }\n'+
223+
'}',
224+
);
214225
}
215226

216227
// Truncate output for ArrayBuffers using plural or singular bytes
217228
{
218229
constab=newArrayBuffer(3);
219-
assert.strictEqual(util.inspect(ab,{showHidden: true,maxArrayLength: 2}),
230+
assert.strictEqual(util.inspect(ab,{showHidden: true,maxArrayLength: 2,breakLength: 82}),
220231
'ArrayBuffer{[Uint8Contents]'+
221-
': <00 00 ... 1 more byte>, byteLength: 3 }');
222-
assert.strictEqual(util.inspect(ab,{showHidden: true,maxArrayLength: 1}),
232+
': <00 00 ... 1 more byte>, [byteLength]: 3 }');
233+
assert.strictEqual(util.inspect(ab,{showHidden: true,maxArrayLength: 1,breakLength: 82}),
223234
'ArrayBuffer{[Uint8Contents]'+
224-
': <00 ... 2 more bytes>, byteLength: 3 }');
235+
': <00 ... 2 more bytes>, [byteLength]: 3 }');
225236
}
226237

227238
// Now do the same checks but from a different context.
@@ -231,35 +242,35 @@ assert.doesNotMatch(
231242
constdv=vm.runInNewContext('new DataView(ab, 1, 2)',{ ab });
232243
assert.strictEqual(
233244
util.inspect(ab,showHidden),
234-
'ArrayBuffer{[Uint8Contents]: <00 00 00 00>, byteLength: 4 }'
245+
'ArrayBuffer{[Uint8Contents]: <00 00 00 00>, [byteLength]: 4 }'
235246
);
236247
assert.strictEqual(util.inspect(newDataView(ab,1,2),showHidden),
237248
'DataView{\n'+
238-
' byteLength: 2,\n'+
239-
' byteOffset: 1,\n'+
240-
' buffer: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
241-
' byteLength: 4 }\n}');
249+
' [byteLength]: 2,\n'+
250+
' [byteOffset]: 1,\n'+
251+
' [buffer]: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
252+
' [byteLength]: 4 }\n}');
242253
assert.strictEqual(
243254
util.inspect(ab,showHidden),
244-
'ArrayBuffer{[Uint8Contents]: <00 00 00 00>, byteLength: 4 }'
255+
'ArrayBuffer{[Uint8Contents]: <00 00 00 00>, [byteLength]: 4 }'
245256
);
246257
assert.strictEqual(util.inspect(dv,showHidden),
247258
'DataView{\n'+
248-
' byteLength: 2,\n'+
249-
' byteOffset: 1,\n'+
250-
' buffer: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
251-
' byteLength: 4 }\n}');
259+
' [byteLength]: 2,\n'+
260+
' [byteOffset]: 1,\n'+
261+
' [buffer]: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
262+
' [byteLength]: 4 }\n}');
252263
ab.x=42;
253264
dv.y=1337;
254265
assert.strictEqual(util.inspect(ab,showHidden),
255266
'ArrayBuffer{[Uint8Contents]: <00 00 00 00>, '+
256-
'byteLength: 4, x: 42 }');
257-
assert.strictEqual(util.inspect(dv,showHidden),
267+
'[byteLength]: 4, x: 42 }');
268+
assert.strictEqual(util.inspect(dv,{showHidden,breakLength: 82}),
258269
'DataView{\n'+
259-
' byteLength: 2,\n'+
260-
' byteOffset: 1,\n'+
261-
' buffer: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
262-
' byteLength: 4, x: 42 },\n'+
270+
' [byteLength]: 2,\n'+
271+
' [byteOffset]: 1,\n'+
272+
' [buffer]: ArrayBuffer{[Uint8Contents]: <00 00 00 00>,'+
273+
' [byteLength]: 4, x: 42 },\n'+
263274
' y: 1337\n}');
264275
}
265276

@@ -286,7 +297,7 @@ assert.doesNotMatch(
286297
` [length]: ${length},\n`+
287298
` [byteLength]: ${byteLength},\n`+
288299
' [byteOffset]: 0,\n'+
289-
` [buffer]: ArrayBuffer{byteLength: ${byteLength} }\n]`);
300+
` [buffer]: ArrayBuffer{[byteLength]: ${byteLength} }\n]`);
290301
assert.strictEqual(
291302
util.inspect(array,false),
292303
`${constructor.name}(${length}) [ 65, 97 ]`
@@ -320,7 +331,7 @@ assert.doesNotMatch(
320331
` [length]: ${length},\n`+
321332
` [byteLength]: ${byteLength},\n`+
322333
' [byteOffset]: 0,\n'+
323-
` [buffer]: ArrayBuffer{byteLength: ${byteLength} }\n]`);
334+
` [buffer]: ArrayBuffer{[byteLength]: ${byteLength} }\n]`);
324335
assert.strictEqual(
325336
util.inspect(array,false),
326337
`${constructor.name}(${length}) [ 65, 97 ]`
@@ -1837,7 +1848,7 @@ util.inspect(process);
18371848
' [byteLength]: 0,',
18381849
' [byteOffset]: 0,',
18391850
' [buffer]: ArrayBuffer{',
1840-
' byteLength: 0,',
1851+
' [byteLength]: 0,',
18411852
' foo: true',
18421853
'}',
18431854
' ],',
@@ -1855,7 +1866,7 @@ util.inspect(process);
18551866
' [byteLength]: 0,',
18561867
' [byteOffset]: 0,',
18571868
' [buffer]: ArrayBuffer{',
1858-
' byteLength: 0,',
1869+
' [byteLength]: 0,',
18591870
' foo: true',
18601871
'}',
18611872
' ],',
@@ -1885,7 +1896,7 @@ util.inspect(process);
18851896
' [length]: 0,',
18861897
' [byteLength]: 0,',
18871898
' [byteOffset]: 0,',
1888-
' [buffer]: ArrayBuffer{byteLength: 0, foo: true }',
1899+
' [buffer]: ArrayBuffer{[byteLength]: 0, foo: true }',
18891900
' ],',
18901901
' [Set Iterator]{',
18911902
' [ 1, 2, [length]: 2 ],',
@@ -1896,7 +1907,7 @@ util.inspect(process);
18961907
' [length]: 0,',
18971908
' [byteLength]: 0,',
18981909
' [byteOffset]: 0,',
1899-
' [buffer]: ArrayBuffer{byteLength: 0, foo: true }',
1910+
' [buffer]: ArrayBuffer{[byteLength]: 0, foo: true }',
19001911
' ],',
19011912
' [Circular *1],',
19021913
" [Symbol(Symbol.toStringTag)]: 'Map Iterator'",
@@ -1924,7 +1935,7 @@ util.inspect(process);
19241935
' [byteLength]: 0,',
19251936
' [byteOffset]: 0,',
19261937
' [buffer]: ArrayBuffer{',
1927-
' byteLength: 0,',
1938+
' [byteLength]: 0,',
19281939
' foo: true } ],',
19291940
' [Set Iterator]{',
19301941
' [ 1,',
@@ -1938,7 +1949,7 @@ util.inspect(process);
19381949
' [byteLength]: 0,',
19391950
' [byteOffset]: 0,',
19401951
' [buffer]: ArrayBuffer{',
1941-
' byteLength: 0,',
1952+
' [byteLength]: 0,',
19421953
' foo: true } ],',
19431954
' [Circular *1],',
19441955
' [Symbol(Symbol.toStringTag)]:',
@@ -2244,12 +2255,12 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
22442255
[newBigUint64Array(2),'[BigUint64Array(2): null prototype] [ 0n, 0n ]'],
22452256
[newArrayBuffer(16),'[ArrayBuffer: null prototype]{\n'+
22462257
' [Uint8Contents]: <00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>,\n'+
2247-
' byteLength: undefined\n}'],
2258+
' [byteLength]: undefined\n}'],
22482259
[newDataView(newArrayBuffer(16)),
2249-
'[DataView: null prototype]{\n byteLength: undefined,\n '+
2250-
'byteOffset: undefined,\n buffer: undefined\n}'],
2260+
'[DataView: null prototype]{\n [byteLength]: undefined,\n '+
2261+
'[byteOffset]: undefined,\n [buffer]: undefined\n}'],
22512262
[newSharedArrayBuffer(2),'[SharedArrayBuffer: null prototype] '+
2252-
'{\n [Uint8Contents]: <00 00>,\n byteLength: undefined\n}'],
2263+
'{\n [Uint8Contents]: <00 00>,\n [byteLength]: undefined\n}'],
22532264
[/foobar/,'[RegExp: null prototype] /foobar/'],
22542265
[newDate('Sun, 14 Feb 2010 11:48:40 GMT'),
22552266
'[Date: null prototype] 2010-02-14T11:48:40.000Z'],
@@ -3632,7 +3643,7 @@ assert.strictEqual(
36323643
assert.strictEqual(
36333644
util.inspect(o),
36343645
'{\n'+
3635-
' arrayBuffer: ArrayBuffer{[Uint8Contents]: <>, byteLength: 0 },\n'+
3646+
' arrayBuffer: ArrayBuffer{[Uint8Contents]: <>, [byteLength]: 0 },\n'+
36363647
' buffer: <Buffer 48 65 6c 6c 6f>,\n'+
36373648
' typedArray: TypedArray(5) [Uint8Array] [ 72, 101, 108, 108, 111 ],\n'+
36383649
' array: [],\n'+

0 commit comments

Comments
(0)