json5-utils
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -1,1 +0,2 @@ | ||
module.exports = require('./lib/parse') | ||
module.exports.parse = require('./lib/parse').parse | ||
module.exports.stringify = require('./lib/stringify').stringify |
@@ -11,19 +11,2 @@ /* | ||
function isIdentifierStart(x) { | ||
return x === '$' | ||
|| x === '_' | ||
|| (x >= 'A' && x <= 'Z') | ||
|| (x >= 'a' && x <= 'z') | ||
|| (x >= '\u0080' && Uni.NonAsciiIdentifierStart.test(x)) | ||
} | ||
function isIdentifierPart(x) { | ||
return x === '$' | ||
|| x === '_' | ||
|| (x >= 'A' && x <= 'Z') | ||
|| (x >= 'a' && x <= 'z') | ||
|| (x >= '0' && x <= '9') // <-- addition to Start | ||
|| (x >= '\u0080' && Uni.NonAsciiIdentifierPart.test(x)) | ||
} | ||
function isHexDigit(x) { | ||
@@ -39,34 +22,2 @@ return (x >= '0' && x <= '9') | ||
function isWhiteSpace(x) { | ||
// section 7.2, table 2 | ||
return x === '\u0020' | ||
|| x === '\u00A0' | ||
|| x === '\uFEFF' // <-- this is not a Unicode WS, only a JS one | ||
// + 9 B C below | ||
// + whitespace characters from unicode 6.0.0 | ||
// http://www.unicode.org/versions/Unicode6.0.0/ch04.pdf | ||
|| (x >= '\u0009' && x <= '\u000D') // 9 A B C D | ||
|| x === '\u0085' | ||
|| x === '\u1680' | ||
|| x === '\u180E' | ||
|| (x >= '\u2000' && x <= '\u200A') // 0 1 2 3 4 5 6 7 8 9 A | ||
|| x === '\u2028' | ||
|| x === '\u2029' | ||
|| x === '\u202F' | ||
|| x === '\u205F' | ||
|| x === '\u3000' | ||
// should be total of 26+1 = 27 characters | ||
} | ||
function isLineTerminator(x) { | ||
// ok, here is the part when JSON is wrong | ||
// section 7.3, table 3 | ||
return x === '\u000A' | ||
|| x === '\u000D' | ||
|| x === '\u2028' | ||
|| x === '\u2029' | ||
} | ||
var unescapeMap = { | ||
@@ -98,3 +49,3 @@ '\'': '\'', | ||
if (isLineTerminator(chr)) break | ||
if (Uni.isLineTerminator(chr)) break | ||
srcline += chr | ||
@@ -116,2 +67,9 @@ | ||
function parse(input, options) { | ||
if (input === undefined) { | ||
// parse(stringify(x)) should be equal x | ||
// with JSON functions it is not 'cause of undefined | ||
// so we're fixing it | ||
return undefined | ||
} | ||
// JSON.parse compat | ||
@@ -149,3 +107,3 @@ if (typeof(input) !== 'string') input = String(input) | ||
var error = new Error(formatError(input, msg, position, lineno, column)) | ||
var error = new SyntaxError(formatError(input, msg, position, lineno, column)) | ||
error.row = lineno | ||
@@ -156,3 +114,3 @@ error.column = column | ||
function parseGeneric(identAllowed) { | ||
function parseGeneric(is_key) { | ||
var result | ||
@@ -164,3 +122,3 @@ //console.log('parse: =============\n', input.substr(position, 40)) | ||
if (isLineTerminator(chr)) { | ||
if (Uni.isLineTerminator(chr)) { | ||
// account for <cr><lf> | ||
@@ -171,3 +129,3 @@ if (chr === '\r' && input[position] === '\n') position++ | ||
} else if (isWhiteSpace(chr)) { | ||
} else if (Uni.isWhiteSpace(chr)) { | ||
// nothing | ||
@@ -190,13 +148,13 @@ | ||
) { | ||
return parseNumber() | ||
return parseNumber(is_key) | ||
} else if (chr === 'n' && !identAllowed) { | ||
} else if (chr === 'n' && !is_key) { | ||
parseKeyword('null') | ||
return null | ||
} else if (chr === 't' && !identAllowed) { | ||
} else if (chr === 't' && !is_key) { | ||
parseKeyword('true') | ||
return true | ||
} else if (chr === 'f' && !identAllowed) { | ||
} else if (chr === 'f' && !is_key) { | ||
parseKeyword('false') | ||
@@ -212,4 +170,4 @@ return false | ||
} else if (!legacy | ||
&& identAllowed | ||
&& isIdentifierStart(chr) || (chr === '\\' && input[position === 'u'])) { | ||
&& is_key | ||
&& Uni.isIdentifierStart(chr) || (chr === '\\' && input[position === 'u'])) { | ||
// unicode char or a unicode sequence | ||
@@ -237,3 +195,3 @@ var rollback = position - 1 | ||
if (isLineTerminator(chr)) { | ||
if (Uni.isLineTerminator(chr)) { | ||
// account for <cr><lf> | ||
@@ -298,3 +256,8 @@ if (chr === '\r' && input[position] === '\n') position++ | ||
result[item1] = item2 | ||
Object.defineProperty(result, item1, { | ||
value: item2, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
}) | ||
@@ -352,3 +315,3 @@ var whitespace = parseGeneric() | ||
function parseNumber() { | ||
function parseNumber(no_sign) { | ||
// rewind because we don't know first char | ||
@@ -372,3 +335,3 @@ position-- | ||
// ^ skipping this | ||
if (chr === '-' || (chr === '+' && !legacy)) chr = input[position++] | ||
if ((chr === '-' || (chr === '+' && !legacy)) && !no_sign) chr = input[position++] | ||
@@ -460,3 +423,3 @@ if (chr === 'N' && !legacy) { | ||
// identifier started | ||
if (isIdentifierPart(chr)) { | ||
if (Uni.isIdentifierPart(chr)) { | ||
result += chr | ||
@@ -469,3 +432,3 @@ } else { | ||
} else { | ||
if (isIdentifierStart(chr)) { | ||
if (Uni.isIdentifierStart(chr)) { | ||
result += chr | ||
@@ -498,3 +461,3 @@ } else { | ||
} else if (isLineTerminator(chr)) { | ||
} else if (Uni.isLineTerminator(chr)) { | ||
// line continuation, do nothing | ||
@@ -530,3 +493,3 @@ | ||
} else if (isLineTerminator(chr)) { | ||
} else if (Uni.isLineTerminator(chr)) { | ||
fail() | ||
@@ -533,0 +496,0 @@ |
@@ -9,2 +9,53 @@ | ||
var Uni = module.exports | ||
module.exports.isWhiteSpace = function isWhiteSpace(x) { | ||
// section 7.2, table 2 | ||
return x === '\u0020' | ||
|| x === '\u00A0' | ||
|| x === '\uFEFF' // <-- this is not a Unicode WS, only a JS one | ||
// + 9 B C below | ||
// + whitespace characters from unicode 6.0.0 | ||
// http://www.unicode.org/versions/Unicode6.0.0/ch04.pdf | ||
|| (x >= '\u0009' && x <= '\u000D') // 9 A B C D | ||
|| x === '\u0085' | ||
|| x === '\u1680' | ||
|| x === '\u180E' | ||
|| (x >= '\u2000' && x <= '\u200A') // 0 1 2 3 4 5 6 7 8 9 A | ||
|| x === '\u2028' | ||
|| x === '\u2029' | ||
|| x === '\u202F' | ||
|| x === '\u205F' | ||
|| x === '\u3000' | ||
// should be total of 26+1 = 27 characters | ||
} | ||
module.exports.isLineTerminator = function isLineTerminator(x) { | ||
// ok, here is the part when JSON is wrong | ||
// section 7.3, table 3 | ||
return x === '\u000A' | ||
|| x === '\u000D' | ||
|| x === '\u2028' | ||
|| x === '\u2029' | ||
} | ||
module.exports.isIdentifierStart = function isIdentifierStart(x) { | ||
return x === '$' | ||
|| x === '_' | ||
|| (x >= 'A' && x <= 'Z') | ||
|| (x >= 'a' && x <= 'z') | ||
|| (x >= '\u0080' && Uni.NonAsciiIdentifierStart.test(x)) | ||
} | ||
module.exports.isIdentifierPart = function isIdentifierPart(x) { | ||
return x === '$' | ||
|| x === '_' | ||
|| (x >= 'A' && x <= 'Z') | ||
|| (x >= 'a' && x <= 'z') | ||
|| (x >= '0' && x <= '9') // <-- addition to Start | ||
|| (x >= '\u0080' && Uni.NonAsciiIdentifierPart.test(x)) | ||
} | ||
module.exports.NonAsciiIdentifierStart = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/ | ||
@@ -11,0 +62,0 @@ |
@@ -1,1 +0,1 @@ | ||
{"name":"json5-utils","version":"0.1.0","description":"JSON and JSON5 parsers done right","author":{"name":"Alex Kocharin","email":"alex@kocharin.ru"},"repository":{"type":"git","url":"git://github.com/rlidwka/json5-utils"},"bugs":{"url":"https://github.com/rlidwka/json5-utils/issues"},"main":"parse.js","scripts":{"test":"node test/test.js"},"keywords":["json","json5","parser"],"license":"WTFPL"} | ||
{"name":"json5-utils","version":"0.2.0","description":"JSON and JSON5 parsers done right","author":{"name":"Alex Kocharin","email":"alex@kocharin.ru"},"repository":{"type":"git","url":"git://github.com/rlidwka/json5-utils"},"bugs":{"url":"https://github.com/rlidwka/json5-utils/issues"},"main":"parse.js","scripts":{"test":"node test/test.js"},"keywords":["json","json5","parser"],"license":"WTFPL"} |
@@ -16,3 +16,3 @@ | ||
- "undefined" is forbidden, use null instead if applicable. | ||
- Comments and whitespace are defined according to spec. Two or more consecutive asterisks in multiline comments are allowed. | ||
- Comments and whitespace are defined according to spec. | ||
@@ -35,1 +35,52 @@ Main authority here is ES5 spec, so strict backward JSON compatibility is not guaranteed. | ||
## Options | ||
parse(string, options): | ||
stringify(object, options): | ||
- ascii - output ascii only (bool, default=false) | ||
- indent - indentation (string or number, default='\t') | ||
- quote - enquoting char (string, "'" or '"', default="'") | ||
## Modes of operation | ||
TODO: not yet working | ||
- simple: | ||
no custom datatypes | ||
no .toJSON/.toJSON5 | ||
for serializing simple json-compatible objects only (i.e. user-generated data) | ||
- full | ||
custom datatypes | ||
.toJSON/.toJSON5 present (prototype only) | ||
for representing arbitrary data structures as close as possible | ||
- json: | ||
no custom datatypes | ||
.toJSON present | ||
json compatible | ||
## Weirdness of JSON5 | ||
- no elisions, `[,,,] -> [null,null,null]` | ||
- `[Object], [Circular]` aren't parsed | ||
- no way of nicely representing multiline strings | ||
- unicode property names are way to hard to implement | ||
## Unicode support | ||
```javascript | ||
// 27 whitespace characters (unicode defines 26 characters, and ES5 spec also adds \uFEFF as a whitespace) | ||
var whitespace = /[\u0009-\u000D\u0020\u0085\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/ | ||
// 4 line terminators | ||
var lineterminator = /[\u000A\u000D\u2028\u2029]/ | ||
``` | ||
All json5 libraries MUST support 4 line terminator characters and 27 whitespace characters described above. Some libraries MAY choose not to include support for other unicode characters and apply following restrictions: | ||
Parsers that do not fully support unicode SHOULD treat all unknown characters starting with \x80 as unicode\_letter except for line terminators and whitespace characters. This way all valid json5 objects will be parsed correctly, but some invalid json5 objects will be parsed as well. | ||
Serializers that do not fully support unicode SHOULD treat all unknown characters starting with \x80 as control characters, and quote property names if they happen to be in there. This way all data will be serialized correctly. | ||
@@ -6,3 +6,3 @@ | ||
function addTest(arg) { | ||
console.log('testing: ', arg) | ||
//console.log('testing: ', arg) | ||
try { | ||
@@ -58,2 +58,27 @@ var x = parse(arg) | ||
if (process.version > 'v0.11.7') { | ||
assert(Array.isArray(parse('{__proto__:[]}').__proto__)) | ||
assert.equal(parse('{__proto__:{xxx:5}}').xxx, undefined) | ||
assert.equal(parse('{__proto__:{xxx:5}}').__proto__.xxx, 5) | ||
var o1 = parse('{"__proto__":[]}') | ||
assert.deepEqual([], o1.__proto__) | ||
assert.deepEqual(["__proto__"], Object.keys(o1)) | ||
assert.deepEqual([], Object.getOwnPropertyDescriptor(o1, "__proto__").value) | ||
assert.deepEqual(["__proto__"], Object.getOwnPropertyNames(o1)) | ||
assert(o1.hasOwnProperty("__proto__")) | ||
assert(Object.prototype.isPrototypeOf(o1)) | ||
// Parse a non-object value as __proto__. | ||
var o2 = JSON.parse('{"__proto__":5}') | ||
assert.deepEqual(5, o2.__proto__) | ||
assert.deepEqual(["__proto__"], Object.keys(o2)) | ||
assert.deepEqual(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value) | ||
assert.deepEqual(["__proto__"], Object.getOwnPropertyNames(o2)) | ||
assert(o2.hasOwnProperty("__proto__")) | ||
assert(Object.prototype.isPrototypeOf(o2)) | ||
} | ||
assert.throws(parse.bind(null, "{-1:42}")) | ||
for (var i=0; i<100; i++) { | ||
@@ -60,0 +85,0 @@ var str = '-01.e'.split('') |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
66955
15
1124
85
1
5