ES2019: Well-formed JSON.stringify

[2019-01-29] dev, javascript, es2019, json
(Ad, please don’t block)

The proposal “Well-formed JSON.stringify” (by Richard Gibson) is at stage 4 and therefore part of ECMAScript 2019. This blog post explains how it works.

According to the RFC for JSON, if you exchange JSON “in public”, you must encode it as UTF-8. That can be a problem if you use JSON.stringify(), because it may return sequences of UTF-16 code units that can’t be encoded as UTF-8.

How can that happen? If a JavaScript string contains a lone surrogate (a JavaScript character in the range 0xD800–0xDFFF) then JSON.stringify() produces a string with a lone surrogate:

assert.equal(JSON.stringify('\u{D800}'), '"\u{D800}"');

Lone UTF-16 surrogates cannot be encoded as UTF-8, which is why this proposal changes JSON.stringify() so that it represents them via code unit escape sequences:

assert.equal(JSON.stringify('\u{D800}'), '"\\ud800"');

Note: JSON supports code unit escape sequences (e.g. \uD800), but not code point escape sequences (e.g. \u{D800}).