Tumortisch-Dist/resources/app/node_modules/bourne/lib/index.js

87 lines
1.8 KiB
JavaScript
Raw Normal View History

2021-06-15 16:00:08 +02:00
'use strict';
const internals = {
suspectRx: /"(?:_|\\u005f)(?:_|\\u005f)(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006f)(?:t|\\u0074)(?:o|\\u006f)(?:_|\\u005f)(?:_|\\u005f)"\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]);
}
}
}
}
};