Skip to content

Commit ae2333d

Browse files
BridgeARtargos
authored andcommitted
util: add prototype support for boxed primitives
This makes sure manipulated prototypes from boxed primitives will be highlighted. It also makes sure that a potential `Symbol.toStringTag` is taken into account. PR-URL: #27351 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: John-David Dalton <john.david.dalton@gmail.com> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
1 parent e7026f1 commit ae2333d

2 files changed

Lines changed: 56 additions & 28 deletions

File tree

‎lib/internal/util/inspect.js‎

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,6 @@ function getPrefix(constructor, tag, fallback) {
385385
return`${constructor} `;
386386
}
387387

388-
constgetBoxedValue=formatPrimitive.bind(null,stylizeNoColor);
389-
390388
// Look up the keys of the object.
391389
functiongetKeys(value,showHidden){
392390
letkeys;
@@ -709,31 +707,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
709707
braces[0]=`[${tag}] {`;
710708
formatter=formatNamespaceObject;
711709
}elseif(isBoxedPrimitive(value)){
712-
lettype;
713-
if(isNumberObject(value)){
714-
base=`[Number: ${getBoxedValue(NumberPrototype.valueOf(value))}]`;
715-
type='number';
716-
}elseif(isStringObject(value)){
717-
base=`[String: ${
718-
getBoxedValue(StringPrototype.valueOf(value),ctx)
719-
}]`;
720-
type='string';
721-
// For boxed Strings, we have to remove the 0-n indexed entries,
722-
// since they just noisy up the output and are redundant
723-
// Make boxed primitive Strings look like such
724-
keys=keys.slice(value.length);
725-
}elseif(isBooleanObject(value)){
726-
base=`[Boolean: ${getBoxedValue(BooleanPrototype.valueOf(value))}]`;
727-
type='boolean';
728-
}elseif(isBigIntObject(value)){
729-
base=`[BigInt: ${getBoxedValue(BigIntPrototype.valueOf(value))}]`;
730-
type='bigint';
731-
}else{
732-
base=`[Symbol: ${getBoxedValue(SymbolPrototype.valueOf(value))}]`;
733-
type='symbol';
734-
}
710+
base=getBoxedBase(value,ctx,keys,constructor,tag);
735711
if(keys.length===0){
736-
returnctx.stylize(base,type);
712+
returnbase;
737713
}
738714
}else{
739715
// The input prototype got manipulated. Special handle these. We have to
@@ -818,6 +794,46 @@ function getIteratorBraces(type, tag) {
818794
return[`[${tag}] {`,'}'];
819795
}
820796

797+
functiongetBoxedBase(value,ctx,keys,constructor,tag){
798+
letfn;
799+
lettype;
800+
if(isNumberObject(value)){
801+
fn=NumberPrototype;
802+
type='Number';
803+
}elseif(isStringObject(value)){
804+
fn=StringPrototype;
805+
type='String';
806+
// For boxed Strings, we have to remove the 0-n indexed entries,
807+
// since they just noisy up the output and are redundant
808+
// Make boxed primitive Strings look like such
809+
keys.splice(0,value.length);
810+
}elseif(isBooleanObject(value)){
811+
fn=BooleanPrototype;
812+
type='Boolean';
813+
}elseif(isBigIntObject(value)){
814+
fn=BigIntPrototype;
815+
type='BigInt';
816+
}else{
817+
fn=SymbolPrototype;
818+
type='Symbol';
819+
}
820+
letbase=`[${type}`;
821+
if(type!==constructor){
822+
if(constructor===null){
823+
base+=' (null prototype)';
824+
}else{
825+
base+=` (${constructor})`;
826+
}
827+
}
828+
base+=`: ${formatPrimitive(stylizeNoColor,fn.valueOf(value),ctx)}]`;
829+
if(tag!==''&&tag!==constructor){
830+
base+=` [${tag}]`;
831+
}
832+
if(keys.length!==0||ctx.stylize===stylizeNoColor)
833+
returnbase;
834+
returnctx.stylize(base,type.toLowerCase());
835+
}
836+
821837
functionformatError(err,constructor,tag,ctx){
822838
// TODO(BridgeAR): Always show the error code if present.
823839
letstack=err.stack||ErrorPrototype.toString(err);

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,9 +856,21 @@ assert.strictEqual(
856856
'[Symbol: Symbol(test)]'
857857
);
858858
assert.strictEqual(util.inspect(newBoolean(false)),'[Boolean: false]');
859-
assert.strictEqual(util.inspect(newBoolean(true)),'[Boolean: true]');
859+
assert.strictEqual(
860+
util.inspect(Object.setPrototypeOf(newBoolean(true),null)),
861+
'[Boolean (null prototype): true]'
862+
);
860863
assert.strictEqual(util.inspect(newNumber(0)),'[Number: 0]');
861-
assert.strictEqual(util.inspect(newNumber(-0)),'[Number: -0]');
864+
assert.strictEqual(
865+
util.inspect(
866+
Object.defineProperty(
867+
Object.setPrototypeOf(newNumber(-0),Array.prototype),
868+
Symbol.toStringTag,
869+
{value: 'Foobar'}
870+
)
871+
),
872+
'[Number (Array): -0] [Foobar]'
873+
);
862874
assert.strictEqual(util.inspect(newNumber(-1.1)),'[Number: -1.1]');
863875
assert.strictEqual(util.inspect(newNumber(13.37)),'[Number: 13.37]');
864876

0 commit comments

Comments
 (0)