stepping aside from the security aspect, having your code-base’s json-files 
normalized with sorted-keys is good-housekeeping, especially when you want to 
sanely maintain ones >1mb in size (e.g. large swagger json-documentations) [1].

and you can easily operationalize your build-process / pre-commit-checks to 
auto-key-sort json-files with the following simple shell-function [2].

[1] 
https://github.com/kaizhu256/node-swgg-github-all/blob/2018.2.2/assets.swgg.swagger.json
 
<https://github.com/kaizhu256/node-swgg-github-all/blob/2018.2.2/assets.swgg.swagger.json>
[2] 
https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.sh#L1513 
<https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.sh#L1513>



```shell
#!/bin/sh
# .bashrc
: '
# to install, copy-paste the shell-function shFileJsonNormalize below
# into your shell startup script (.bashrc, .profile, etc...)


# example shell-usage:

source ~/.bashrc
printf "{
    \"version\": \"0.0.1\",
    \"name\": \"my-app\",
    \"aa\": {
        \"zz\": 1,
        \"yy\": {
            \"xx\": 2,
            \"ww\": 3
        }
    },
    \"bb\": [
        3,
        2,
        1,
        null
    ]
}" > package.json
shFileJsonNormalize package.json
cat package.json


# key-sorted output:
{
    "aa": {
        "yy": {
            "ww": 3,
            "xx": 2
        },
        "zz": 1
    },
    "bb": [
        3,
        2,
        1,
        null
    ],
    "name": "my-app",
    "version": "0.0.1"
}
'


shFileJsonNormalize() {(set -e
# this shell-function will
# 1. read the json-data from $FILE
# 2. normalize the json-data
# 3. write the normalized json-data back to $FILE
    FILE="$1"
    node -e "
// <script>
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 100,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
'use strict';
var local;
local = {};
local.fs = require('fs');
local.jsonStringifyOrdered = function (jsonObj, replacer, space) {
/*
 * this function will JSON.stringify the jsonObj,
 * with object-keys sorted and circular-references removed
 */
    var circularList, stringify, tmp;
    stringify = function (jsonObj) {
    /*
     * this function will recursively JSON.stringify the jsonObj,
     * with object-keys sorted and circular-references removed
     */
        // if jsonObj is an object, then recurse its items with object-keys 
sorted
        if (jsonObj &&
                typeof jsonObj === 'object' &&
                typeof jsonObj.toJSON !== 'function') {
            // ignore circular-reference
            if (circularList.indexOf(jsonObj) >= 0) {
                return;
            }
            circularList.push(jsonObj);
            // if jsonObj is an array, then recurse its jsonObjs
            if (Array.isArray(jsonObj)) {
                return '[' + jsonObj.map(function (jsonObj) {
                    // recurse
                    tmp = stringify(jsonObj);
                    return typeof tmp === 'string'
                        ? tmp
                        : 'null';
                }).join(',') + ']';
            }
            return '{' + Object.keys(jsonObj)
                // sort object-keys
                .sort()
                .map(function (key) {
                    // recurse
                    tmp = stringify(jsonObj[key]);
                    if (typeof tmp === 'string') {
                        return JSON.stringify(key) + ':' + tmp;
                    }
                })
                .filter(function (jsonObj) {
                    return typeof jsonObj === 'string';
                })
                .join(',') + '}';
        }
        // else JSON.stringify as normal
        return JSON.stringify(jsonObj);
    };
    circularList = [];
    return JSON.stringify(typeof jsonObj === 'object' && jsonObj
        // recurse
        ? JSON.parse(stringify(jsonObj))
        : jsonObj, replacer, space);
};
local.fs.writeFileSync(process.argv[1], local.jsonStringifyOrdered(
    JSON.parse(local.fs.readFileSync(process.argv[1], 'utf8')),
    null,
    4
) + '\n');
// </script>
    " "$FILE"
)}
```

> On Mar 17, 2018, at 5:43 AM, Mike Samuel <[email protected]> wrote:
> 
> 
> 
> On Fri, Mar 16, 2018, 4:58 PM Anders Rundgren <[email protected] 
> <mailto:[email protected]>> wrote:
> On 2018-03-16 21:41, Mike Samuel wrote:
> >
> >
> > On Fri, Mar 16, 2018 at 4:34 PM, C. Scott Ananian <[email protected] 
> > <mailto:[email protected]> <mailto:[email protected] 
> > <mailto:[email protected]>>> wrote:
> >
> >     On Fri, Mar 16, 2018 at 4:07 PM, Anders Rundgren 
> > <[email protected] <mailto:[email protected]> 
> > <mailto:[email protected] 
> > <mailto:[email protected]>>> wrote:
> >
> 
> > To restate my main objections:
> >
> > I think any proposal to offer an alternative stringify instead of a 
> > string->string transform is not very good
> > and could be easily improved by rephrasing it as a string->string transform.
> 
> Could you give a concrete example on that?
> 
> 
> 
> I've given three.  As written, the proposal produces invalid or low quality 
> output given (undefined, objects with toJSON methods, and symbols as either 
> keys or values).  These would not be problems for a real canonicalizer since 
> none are present in a string of JSON.
> 
> In addition, two distant users of the canonicalizer who wish to check hashes 
> need to agree on the ancillary arguments like the replacer if canonicalize 
> takes the same arguments and actually uses them.  They also need to agree on 
> implementation details of toJSON methods which is a backward compatibility 
> hazard.
> 
> If you did solve the toJSON problem by incorporating calls to that method 
> you've now complicated cross-platform behavior.  If you phrase in terms of 
> string->string it is much easier to disentangle the definition of 
> canonicalizers JSON from JS and make it language agnostic.
> 
> Finally, your proposal is not the VHS of canonicalizers.  That would be 
> x=>JSON.stringify(JSON.parse(x)) since it's deployed and used.
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss

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

Reply via email to