Skip to content

Commit 0a29dd2

Browse files
committed
fix: implement safe option for toJSON and make other accesses safe
1 parent 346f295 commit 0a29dd2

2 files changed

Lines changed: 28 additions & 18 deletions

File tree

index.js

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -162,26 +162,36 @@ function getStrictOption (options) {
162162
if (value) {
163163
return (value) => {
164164
let message = `Object can not safely be stringified. Received type ${typeof value}`
165-
if (typeof value !== 'function') message += ` (${value.toString()})`
165+
if (typeof value !== 'function') message += ` (${safeErrorMessage(value)})`
166166
throw new Error(message)
167167
}
168168
}
169169
}
170170
}
171171

172-
function makeSafe (method) {
173-
return function (...input) {
174-
try {
175-
return method(...input)
176-
} catch (error) {
177-
const message = typeof error?.message === 'string'
178-
? error.message
179-
: (() => { try { return String(error) } catch { return 'Failed' } })()
180-
return strEscape('Error: Stringification failed. Message: ' + message)
181-
}
172+
function safeErrorMessage (error) {
173+
try {
174+
return String(error)
175+
} catch {
176+
return 'Failed'
177+
}
178+
}
179+
180+
function callSafe (method, ...input) {
181+
try {
182+
return method(...input)
183+
} catch (error) {
184+
const message = typeof error?.message === 'string'
185+
? error.message
186+
: safeErrorMessage(error)
187+
return strEscape('Error: Stringification failed. Message: ' + message)
182188
}
183189
}
184190

191+
function makeSafe (method) {
192+
return callSafe.bind(null, method)
193+
}
194+
185195
function configure (options) {
186196
options = { ...options }
187197
const fail = getStrictOption(options)
@@ -205,7 +215,7 @@ function configure (options) {
205215
let value = parent[key]
206216

207217
if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {
208-
value = value.toJSON(key)
218+
value = safe ? callSafe(value.toJSON, key) : value.toJSON(key)
209219
}
210220
value = replacer.call(parent, key, value)
211221

@@ -314,7 +324,7 @@ function configure (options) {
314324

315325
let stringifyArrayReplacer = function (key, value, stack, replacer, spacer, indentation) {
316326
if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {
317-
value = value.toJSON(key)
327+
value = safe ? callSafe(value.toJSON, key) : value.toJSON(key)
318328
}
319329

320330
switch (typeof value) {
@@ -410,7 +420,7 @@ function configure (options) {
410420
return 'null'
411421
}
412422
if (typeof value.toJSON === 'function') {
413-
value = value.toJSON(key)
423+
value = safe ? callSafe(value.toJSON, key) : value.toJSON(key)
414424
// Prevent calling `toJSON` again.
415425
if (typeof value !== 'object') {
416426
return stringifyIndent(key, value, stack, spacer, indentation)
@@ -520,7 +530,7 @@ function configure (options) {
520530
return 'null'
521531
}
522532
if (typeof value.toJSON === 'function') {
523-
value = value.toJSON(key)
533+
value = safe ? callSafe(value.toJSON, key) : value.toJSON(key)
524534
// Prevent calling `toJSON` again
525535
if (typeof value !== 'object') {
526536
return stringifySimple(key, value, stack)

readme.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ stringify(circular, ['a', 'b'], 2)
6666
Circular values and bigint values throw as well in case either option is not
6767
explicitly defined. Sets and Maps are not detected as well as Symbol keys!
6868
**Default:** `false`
69-
* `safe` {boolean} If `true`, calls to .toJSON() and getters that throw an error
70-
are going to return the error message as content in place of the object
71-
instead of throwing the error. **Default:** `false`
69+
* `safe` {boolean} If `true`, calls to .toJSON() and replacers that throw will
70+
return the error message in place of the object instead of throwing.
71+
**Default:** `false`
7272
* Returns: {function} A stringify function with the options applied.
7373

7474
```js

0 commit comments

Comments
 (0)