From a6154c4f3e58054c52ca15a6645234ad99091cec Mon Sep 17 00:00:00 2001 From: Bhupesh Cholake Date: Fri, 6 Nov 2026 21:19:27 +0530 Subject: [PATCH 1/3] fix: escape error messages in safe mode Use the existing JSON string escaping helper for caught errors. Assisted-by: LLM --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index f33f482..2814eac 100644 --- a/index.js +++ b/index.js @@ -257,7 +257,7 @@ function makeSafe (method, name) { if (name !== undefined) { return getErrorMessage(error, name) } - return `"${getErrorMessage(error, name)}"` + return strEscape(getErrorMessage(error, name)) } } Object.defineProperty(safeMethod, 'name', { value: `safe_${method.name}` }) @@ -753,4 +753,4 @@ if (sharedGlobal[exportSymbol] === undefined) { value: /** @type {typeof import('./index.js').default} */ (stringify), writable: true }) -} + } From 7767581a4fe9dcd0712b8a79f1c7049c797bc17f Mon Sep 17 00:00:00 2001 From: Bhupesh Cholake Date: Fri, 6 Nov 2026 21:20:07 +0530 Subject: [PATCH 2/3] fix: preserve closing brace indentation Remove editor auto-indentation from the final brace. Assisted-by: LLM --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 2814eac..6574753 100644 --- a/index.js +++ b/index.js @@ -753,4 +753,4 @@ if (sharedGlobal[exportSymbol] === undefined) { value: /** @type {typeof import('./index.js').default} */ (stringify), writable: true }) - } +} From d566501784a96e68a3c3749c2db8ee9c1c3e7081 Mon Sep 17 00:00:00 2001 From: Bhupesh Cholake Date: Fri, 6 Nov 2026 21:20:41 +0530 Subject: [PATCH 3/3] test: cover escaped errors in safe serialization Cover quotes, newlines, backslashes, NUL and lone surrogates across compact, indented and replacer modes. Assisted-by: LLM --- test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test.js b/test.js index 8242f5e..c7e88c1 100644 --- a/test.js +++ b/test.js @@ -1972,3 +1972,23 @@ test('safe mode safeguards against failing toJSON and a difficult to stringify e assert.end() }) + +test('safe mode escapes error messages from throwing getters', (assert) => { + const serializer = stringify.configure({ safe: true }) + for (const message of ['Missing "token"', 'line\nbreak', 'path\\file', '\u0000', '\ud800']) { + const input = { get token () { throw new Error(message) } } + const expected = `Error: Stringification failed (${message})` + const results = [ + serializer(input), + serializer(input, null, 2), + serializer(input, ['token']) + ] + for (const result of results) { + assert.equal(result, JSON.stringify(expected)) + assert.equal(JSON.parse(/** @type {string} */ (result)), expected) + } + const replaced = serializer(input, (key, value) => value) + assert.same(JSON.parse(/** @type {string} */ (replaced)), { token: expected }) + } + assert.end() +})