json-bigint icon indicating copy to clipboard operation
json-bigint copied to clipboard

Serializes unicode strings differently than JSON.stringify

Open justin-together opened this issue 1 year ago • 1 comments

JSONbig.stringify escapes '\u202c' while JSON.stringify does not:

Welcome to Node.js v16.20.0.
Type ".help" for more information.
> JSONbig = require('json-bigint')
[Function (anonymous)] {
  parse: [Function (anonymous)],
  stringify: [Function (anonymous)]
}
> x = { k: 'a\u202cz' }
{ k: 'a‬z' }
> [...JSON.stringify(x)].map(i => i.charCodeAt(0).toString(16))
[
  '7b', '22',   '6b',
  '22', '3a',   '22',
  '61', '202c', '7a',
  '22', '7d'
]
> [...JSONbig.stringify(x)].map(i => i.charCodeAt(0).toString(16))
[
  '7b', '22', '6b', '22',
  '3a', '22', '61', '5c',
  '75', '32', '30', '32',
  '63', '7a', '22', '7d'
]
>

Note the absence of 202c. In its place is the escaped string "\u202c".

More parameters controlling escaping would be helpful.

justin-together avatar Apr 27 '23 23:04 justin-together

It seems that JSON.stringify() only escapes \u0000-\u001f:

let i = 0
for (i = 0; i <= 0x9999; i++) {
  const code = i.toString(16).padStart(4, '0')
  const str = JSON.parse(`"\\u${code}"`)
  const encoding = [...JSON.stringify(str)].map(x => x.charCodeAt(0).toString(16))
  if (encoding.length > 3) {
     console.log(code, encoding)
  }
}

I will try testing the change:

-        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\u0000-\u001f]/g,

justin-together avatar Apr 28 '23 00:04 justin-together