From 1c50e79e39ddc077ab21a15f04e78fc10d6119fe Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 19 Apr 2024 13:25:17 -0400 Subject: [PATCH] ignore non-enumerable symbols --- src/stringify.js | 3 ++- src/uneval.js | 3 ++- src/utils.js | 7 +++++++ test/test.js | 13 +++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/stringify.js b/src/stringify.js index d4c562b..642c660 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,5 +1,6 @@ import { DevalueError, + enumerable_symbols, get_type, is_plain_object, is_primitive, @@ -143,7 +144,7 @@ export function stringify(value, reducers) { ); } - if (Object.getOwnPropertySymbols(thing).length > 0) { + if (enumerable_symbols(thing).length > 0) { throw new DevalueError( `Cannot stringify POJOs with symbolic keys`, keys diff --git a/src/uneval.js b/src/uneval.js index 21a98a4..82535be 100644 --- a/src/uneval.js +++ b/src/uneval.js @@ -1,5 +1,6 @@ import { DevalueError, + enumerable_symbols, escaped, get_type, is_plain_object, @@ -89,7 +90,7 @@ export function uneval(value, replacer) { ); } - if (Object.getOwnPropertySymbols(thing).length > 0) { + if (enumerable_symbols(thing).length > 0) { throw new DevalueError( `Cannot stringify POJOs with symbolic keys`, keys diff --git a/src/utils.js b/src/utils.js index 5dea3ef..8c2152e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -97,3 +97,10 @@ export function stringify_string(str) { return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`; } + +/** @param {Record} object */ +export function enumerable_symbols(object) { + return Object.getOwnPropertySymbols(object).filter( + (symbol) => Object.getOwnPropertyDescriptor(object, symbol).enumerable + ); +} diff --git a/test/test.js b/test/test.js index d4089e7..5848c4f 100644 --- a/test/test.js +++ b/test/test.js @@ -390,6 +390,19 @@ const fixtures = { assert.equal(Object.getPrototypeOf(value), Object.prototype); assert.equal(Object.keys(value).length, 0); } + }, + { + name: 'non-enumerable symbolic key', + value: (() => { + const obj = { x: 1 }; + Object.defineProperty(obj, Symbol('key'), { + value: 'value', + enumerable: false + }); + return obj; + })(), + js: '{x:1}', + json: '[{"x":1},1]' } ],