On Fri, Mar 16, 2018 at 1:30 PM, Anders Rundgren <
[email protected]> wrote:

> On 2018-03-16 18:04, Mike Samuel wrote:
>
> It is entirely unsuitable to embedding in HTML or XML though.
>> IIUC, with an implementation based on this
>>
>>    JSON.canonicalize(JSON.stringify("</script>")) === `"</script>"` &&
>> JSON.canonicalize(JSON.stringify("]]>")) === `"]]>"`
>>
>
> I don't know what you are trying to prove here :-)
>

Only that canonical JSON is useful in a very narrow context.
It cannot be embedded in an HTML script tag.
It cannot be embedded in an XML or HTML foreign content context without
extra care.
If it contains a string literal that embeds a NUL it cannot be embedded in
XML period even if extra care is taken.



>
> The output of JSON.canonicalize would also not be in the subset of JSON
>> that is also a subset of JavaScript's PrimaryExpression.
>>
>>     JSON.canonicalize(JSON.stringify("\u2028\u2029")) ===
>> `"\u2028\u2029"`
>>
>> It also is not suitable for use internally within systems that internally
>> use cstrings.
>>
>>    JSON.canonicalize(JSON.stringify("\u0000")) === `"\u0000"`
>>
>>
> JSON.canonicalize() would be [almost] identical to JSON.stringify()
>

You're correct.  Many JSON producers have a web-safe version, but the
JavaScript builtin does not.
My point is that JSON.canonicalize undoes those web-safety tweaks.



> JSON.canonicalize(JSON.parse('"\u2028\u2029"')) === '"\u2028\u2029"'  //
> Returns true
>
> "Emulator":
>
> var canonicalize = function(object) {
>
>     var buffer = '';
>     serialize(object);
>

I thought canonicalize took in a string of JSON and produced the same.  Am
I wrong?
"Canonicalize" to my mind means a function that returns the canonical
member of an
equivalence class given any member from that same equivalence class, so is
always 'a -> 'a.


>     return buffer;
>
>     function serialize(object) {
>         if (object !== null && typeof object === 'object') {
>

JSON.stringify(new Date(0)) === "\"1970-01-01T00:00:00.000Z\""
because Date.prototype.toJSON exists.

If you operate as a JSON_string -> JSON_string function then you
can avoid this complexity.

            if (Array.isArray(object)) {
>                 buffer += '[';
>                 let next = false;
>                 object.forEach((element) => {
>                     if (next) {
>                         buffer += ',';
>                     }
>                     next = true;
>                     serialize(element);
>                 });
>                 buffer += ']';
>             } else {
>                 buffer += '{';
>                 let next = false;
>                 Object.keys(object).sort().forEach((property) => {
>                     if (next) {
>                         buffer += ',';
>                     }
>                     next = true;

                    buffer += JSON.stringify(property);
>

I think you need a symbol check here.  JSON.stringify(Symbol.for('foo'))
=== undefined


>                     buffer += ':';
>                     serialize(object[property]);
>                 });
>                 buffer += '}';
>             }
>         } else {
>             buffer += JSON.stringify(object);
>

This fails to distinguish non-integral numbers from integral ones, and
produces non-standard output
when object === undefined.  Again, not a problem if the input is required
to be valid JSON.


>         }
>     }
> };
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to