Sleds/K2Proxy/json.js

323 lines
6.8 KiB
JavaScript
Raw Normal View History

2025-03-13 21:28:38 +00:00
/*
Modifications Copyright (c) 2014 IOnU Security Inc. All rights reserved
Created June 2014 by Kendrick Webster based on JSON.parseMore
on GitHub (https://github.com/Canop/JSON.parseMore) which is based on
JSON-js on GitHub (https://github.com/douglascrockford/JSON-js) which is
public domain code written by Douglas Crockford.
Comments at the top of JSON.parseMore (where license text should be):
// Adapted from Crockford's JSON.parse (see https://github.com/douglascrockford/JSON-js)
// This version adds support for NaN, -Infinity and Infinity.
*/
/*
K2Proxy/json.js - json parser that handles comments and provides better
error contex than the built-in JSON.parse().
*/
"use strict";
function trace(m) { // comment or un-comment as needed for debugging:
console.log(m);
}
function trace_info(m) { // comment or un-comment as needed for debugging:
console.log(m);
}
(function(){
var at, // The index of the current character
ch, // The current character
line = 1,
column = 0,
escapee = {
'"': '"',
'\\': '\\',
'/': '/',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
},
text,
error = function (m) {
throw {
name: 'SyntaxError',
message: m,
line: line,
column: column
};
},
next = function (c) {
column++;
return ch = text.charAt(at++);
},
prev = function (n) {
++n; // for the ++ in next(), so prev(0) stays put and prev(1) goes back 1 char
column -= n;
at -= n;
return next();
},
check = function (c) {
if (c !== ch) {
error("Expected '" + c + "' instead of '" + ch + "'");
}
ch = text.charAt(at++);
},
number = function () {
var string = '';
if (ch === '-') {
string = '-';
check('-');
}
if (ch === 'I') {
check('I');
check('n');
check('f');
check('i');
check('n');
check('i');
check('t');
check('y');
return -Infinity;
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
if (ch === '.') {
string += '.';
while (next() && ch >= '0' && ch <= '9') {
string += ch;
}
}
if (ch === 'e' || ch === 'E') {
string += ch;
next();
if (ch === '-' || ch === '+') {
string += ch;
next();
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
}
return +string;
},
string = function () {
var hex,
i,
string = '',
uffff;
if (ch === '"') {
while (next()) {
if (ch === '"') {
next();
return string;
}
if (ch === '\\') {
next();
if (ch === 'u') {
uffff = 0;
for (i = 0; i < 4; i ++) {
hex = parseInt(next(), 16);
if (!isFinite(hex)) {
break;
}
uffff = uffff * 16 + hex;
}
string += String.fromCharCode(uffff);
} else if (escapee[ch]) {
string += escapee[ch];
} else {
break;
}
} else {
string += ch;
}
}
}
error("Bad string");
},
white = function () { // Skip whitespace and comments, count lines
var s = 0;
while (ch) {
switch (s) {
case 0: // idle
if (ch === '/') {
s = 1;
} else if (ch > ' ') {
return;
}
break;
case 1: // '/'
if (ch === '/') {
s = 2;
} else if (ch === '*') {
s = 3;
} else {
prev(1);
return;
}
break;
case 2: // '//'
if ((ch === '\r') || (ch === '\n')) {
s = 0;
}
break;
case 3: // '/*'
if (ch === '*') {
s = 4;
}
break;
case 4: // '/* ... *'
if (ch === '/') {
s = 0;
} else if (ch !== '*') {
s = 3;
}
break;
}
if (ch === '\n') {
column = 0;
line++;
}
next();
}
},
word = function () {
switch (ch) {
case 't':
check('t');
check('r');
check('u');
check('e');
return true;
case 'f':
check('f');
check('a');
check('l');
check('s');
check('e');
return false;
case 'n':
check('n');
check('u');
check('l');
check('l');
return null;
case 'N':
check('N');
check('a');
check('N');
return NaN;
case 'I':
check('I');
check('n');
check('f');
check('i');
check('n');
check('i');
check('t');
check('y');
return Infinity;
}
error("Unexpected '" + ch + "'");
},
array = function () {
var array = [];
if (ch === '[') {
check('[');
white();
if (ch === ']') {
check(']');
return array; // empty array
}
while (ch) {
array.push(value());
white();
if (ch === ']') {
check(']');
return array;
}
check(',');
white();
}
}
error("Bad array");
},
object = function () {
var key, object = {};
if (ch === '{') {
check('{');
white();
if (ch === '}') {
check('}');
return object; // empty object
}
while (ch) {
key = string();
white();
check(':');
if (Object.hasOwnProperty.call(object, key)) {
error('Duplicate key "' + key + '"');
}
object[key] = value();
white();
if (ch === '}') {
check('}');
return object;
}
check(',');
white();
}
}
error("Bad object");
};
var value = function () {
white();
switch (ch) {
case '{':
return object();
case '[':
return array();
case '"':
return string();
case '-':
return number();
default:
return ch >= '0' && ch <= '9' ? number() : word();
}
};
JSON.parseMore = function(source, reviver){
var result;
text = source;
at = 0;
ch = ' ';
result = value();
white();
if (ch) {
error("Syntax error");
}
return typeof reviver === 'function'
? (function walk(holder, key) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}({'': result}, ''))
: result;
}
})();