@@ -2874,3 +2874,86 @@ assert.strictEqual(
28742874 "'aaaa'... 999996 more characters"
28752875 ) ;
28762876}
2877+
2878+ {
2879+ // Verify that util.inspect() invokes custom inspect functions on objects
2880+ // from other vm.Contexts but does not pass data from its own Context to that
2881+ // function.
2882+ const target = vm . runInNewContext ( `
2883+ ({
2884+ [Symbol.for('nodejs.util.inspect.custom')](depth, ctx) {
2885+ this.depth = depth;
2886+ this.ctx = ctx;
2887+ try {
2888+ this.stylized = ctx.stylize('🐈');
2889+ } catch (e) {
2890+ this.stylizeException = e;
2891+ }
2892+ return this.stylized;
2893+ }
2894+ })
2895+ ` , Object . create ( null ) ) ;
2896+ assert . strictEqual ( target . ctx , undefined ) ;
2897+
2898+ {
2899+ // Subtest 1: Just try to inspect the object with default options.
2900+ assert . strictEqual ( util . inspect ( target ) , '🐈' ) ;
2901+ assert . strictEqual ( typeof target . ctx , 'object' ) ;
2902+ const objectGraph = fullObjectGraph ( target ) ;
2903+ assert ( ! objectGraph . has ( Object ) ) ;
2904+ assert ( ! objectGraph . has ( Function ) ) ;
2905+ }
2906+
2907+ {
2908+ // Subtest 2: Use a stylize function that returns a non-primitive.
2909+ const output = util . inspect ( target , {
2910+ stylize : common . mustCall ( ( str ) => {
2911+ return { } ;
2912+ } )
2913+ } ) ;
2914+ assert . strictEqual ( output , '[object Object]' ) ;
2915+ assert . strictEqual ( typeof target . ctx , 'object' ) ;
2916+ const objectGraph = fullObjectGraph ( target ) ;
2917+ assert ( ! objectGraph . has ( Object ) ) ;
2918+ assert ( ! objectGraph . has ( Function ) ) ;
2919+ }
2920+
2921+ {
2922+ // Subtest 3: Use a stylize function that throws an exception.
2923+ const output = util . inspect ( target , {
2924+ stylize : common . mustCall ( ( str ) => {
2925+ throw new Error ( 'oops' ) ;
2926+ } )
2927+ } ) ;
2928+ assert . strictEqual ( output , '🐈' ) ;
2929+ assert . strictEqual ( typeof target . ctx , 'object' ) ;
2930+ const objectGraph = fullObjectGraph ( target ) ;
2931+ assert ( ! objectGraph . has ( Object ) ) ;
2932+ assert ( ! objectGraph . has ( Function ) ) ;
2933+ }
2934+
2935+ function fullObjectGraph ( value ) {
2936+ const graph = new Set ( [ value ] ) ;
2937+
2938+ for ( const entry of graph ) {
2939+ if ( ( typeof entry !== 'object' && typeof entry !== 'function' ) ||
2940+ entry === null ) {
2941+ continue ;
2942+ }
2943+
2944+ graph . add ( Object . getPrototypeOf ( entry ) ) ;
2945+ const descriptors = Object . values (
2946+ Object . getOwnPropertyDescriptors ( entry ) ) ;
2947+ for ( const descriptor of descriptors ) {
2948+ graph . add ( descriptor . value ) ;
2949+ graph . add ( descriptor . set ) ;
2950+ graph . add ( descriptor . get ) ;
2951+ }
2952+ }
2953+
2954+ return graph ;
2955+ }
2956+
2957+ // Consistency check.
2958+ assert ( fullObjectGraph ( global ) . has ( Function . prototype ) ) ;
2959+ }
0 commit comments