From 3fd4288ab557342d280dcf7d9888fb2079624d34 Mon Sep 17 00:00:00 2001 From: huangweihao <15660254+huangweihaoyyds@user.noreply.gitee.com> Date: Fri, 31 Jul 2026 10:02:32 +0800 Subject: [PATCH] util: fix inspect crash when getter returns a function When a property getter returns a function, formatProperty incorrectly routes the function value to formatPrimitive, which does not handle functions and falls through to Symbol.prototype.toString(), causing a TypeError. Fix by treating getter-returned functions the same as getter-returned objects in formatProperty, routing them through formatValue which properly formats functions. Before (broken): getFunction: [Getter: ] After (fixed): getFunction: [Getter] [Function: fn] Fixes: https://github.com/nodejs/node/issues/64838 --- lib/internal/util/inspect.js | 2 +- test/parallel/test-util-inspect.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 193ae8524632..a9e49a65b628 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -2576,7 +2576,7 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc, const tmp = FunctionPrototypeCall(desc.get, original); if (tmp === null) { str = `${s(`[${label}:`, sp)} ${s('null', 'null')}${s(']', sp)}`; - } else if (typeof tmp === 'object') { + } else if (typeof tmp === 'object' || typeof tmp === 'function') { str = `${s(`[${label}]`, sp)} ${formatValue(ctx, tmp, recurseTimes)}`; } else { const primitive = formatPrimitive(s, tmp, ctx); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 1e305f0a45fb..673ee7ceee0b 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -2596,6 +2596,26 @@ assert.strictEqual( "'foobar', { x: 1 } },\n inc: [Getter: NaN]\n}"); } +// Property getter returning a function. +{ + const getterFn = { + get getString() { return 'foo'; }, + string: 'foo', + get getObject() { return { nested: true }; }, + object: { nested: true }, + get getFunction() { return function fn() {}; }, + function: function fn() {}, + }; + assert.strictEqual( + inspect(getterFn, { getters: true }), + "{ getString: [Getter: 'foo'],\n" + + " string: 'foo',\n" + + ' getObject: [Getter] { nested: true },\n' + + " object: { nested: true },\n" + + ' getFunction: [Getter] [Function: fn],\n' + + ' function: [Function: fn] }'); +} + // Property getter throwing an error. { const error = new Error('Oops');