| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | 'use strict';const internals = {    suspectRx: /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*\:/};exports.parse = function (text, reviver, options) {    // Normalize arguments    if (!options) {        if (reviver &&            typeof reviver === 'object') {            options = reviver;            reviver = undefined;        }        else {            options = {};        }    }    // Parse normally, allowing exceptions    const obj = JSON.parse(text, reviver);    // options.protoAction: 'error' (default) / 'remove' / 'ignore'    if (options.protoAction === 'ignore') {        return obj;    }    // Ignore null and non-objects    if (!obj ||        typeof obj !== 'object') {        return obj;    }    // Check original string for potential exploit    if (!text.match(internals.suspectRx)) {        return obj;    }    // Scan result for proto keys    exports.scan(obj, options);    return obj;};exports.scan = function (obj, options) {    options = options || {};    let next = [obj];    while (next.length) {        const nodes = next;        next = [];        for (const node of nodes) {            if (Object.prototype.hasOwnProperty.call(node, '__proto__')) {      // Avoid calling node.hasOwnProperty directly                if (options.protoAction !== 'remove') {                    throw new SyntaxError('Object contains forbidden prototype property');                }                delete node.__proto__;            }            for (const key in node) {                const value = node[key];                if (value &&                    typeof value === 'object') {                    next.push(node[key]);                }            }        }    }};exports.safeParse = function (text, reviver) {    try {        return exports.parse(text, reviver);    }    catch (ignoreError) {        return null;    }};
 |