Improvements in sanitizing invalid JSON
This commit is contained in:
parent
5a5c04e48f
commit
8ec471b6dc
|
@ -3,6 +3,11 @@
|
||||||
https://github.com/josdejong/jsoneditor
|
https://github.com/josdejong/jsoneditor
|
||||||
|
|
||||||
|
|
||||||
|
## not yet released, version 5.1.2
|
||||||
|
|
||||||
|
- Improvements in sanitizing invalid JSON.
|
||||||
|
|
||||||
|
|
||||||
## 2016-01-16, version 5.1.1
|
## 2016-01-16, version 5.1.1
|
||||||
|
|
||||||
- Fixed #257: Improving error messages for enum errors failed when the
|
- Fixed #257: Improving error messages for enum errors failed when the
|
||||||
|
|
|
@ -45,26 +45,23 @@ exports.sanitize = function (jsString) {
|
||||||
function next() { return jsString.charAt(i + 1); }
|
function next() { return jsString.charAt(i + 1); }
|
||||||
function prev() { return jsString.charAt(i - 1); }
|
function prev() { return jsString.charAt(i - 1); }
|
||||||
|
|
||||||
// test whether the last non-whitespace character was a brace-open '{'
|
// get the last parsed non-whitespace character
|
||||||
function prevIsBrace() {
|
function lastNonWhitespace () {
|
||||||
var ii = i - 1;
|
var p = chars.length - 1;
|
||||||
while (ii >= 0) {
|
|
||||||
var cc = jsString.charAt(ii);
|
while (p >= 0) {
|
||||||
if (cc === '{') {
|
var pp = chars[p];
|
||||||
return true;
|
if (pp !== ' ' && pp !== '\n' && pp !== '\r' && pp !== '\t') { // non whitespace
|
||||||
|
return pp;
|
||||||
}
|
}
|
||||||
else if (cc === ' ' || cc === '\n' || cc === '\r') { // whitespace
|
p--;
|
||||||
ii--;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return false;
|
return '';
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip a block comment '/* ... */'
|
// skip a block comment '/* ... */'
|
||||||
function skipComment () {
|
function skipBlockComment () {
|
||||||
i += 2;
|
i += 2;
|
||||||
while (i < jsString.length && (curr() !== '*' || next() !== '/')) {
|
while (i < jsString.length && (curr() !== '*' || next() !== '/')) {
|
||||||
i++;
|
i++;
|
||||||
|
@ -72,6 +69,14 @@ exports.sanitize = function (jsString) {
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip a comment '// ...'
|
||||||
|
function skipComment () {
|
||||||
|
i += 2;
|
||||||
|
while (i < jsString.length && (curr() !== '\n')) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// parse single or double quoted string
|
// parse single or double quoted string
|
||||||
function parseString(quote) {
|
function parseString(quote) {
|
||||||
chars.push('"');
|
chars.push('"');
|
||||||
|
@ -129,12 +134,15 @@ exports.sanitize = function (jsString) {
|
||||||
var c = curr();
|
var c = curr();
|
||||||
|
|
||||||
if (c === '/' && next() === '*') {
|
if (c === '/' && next() === '*') {
|
||||||
|
skipBlockComment();
|
||||||
|
}
|
||||||
|
else if (c === '/' && next() === '/') {
|
||||||
skipComment();
|
skipComment();
|
||||||
}
|
}
|
||||||
else if (c === '\'' || c === '"') {
|
else if (c === '\'' || c === '"') {
|
||||||
parseString(c);
|
parseString(c);
|
||||||
}
|
}
|
||||||
else if (/[a-zA-Z_$]/.test(c) && prevIsBrace()) {
|
else if (/[a-zA-Z_$]/.test(c) && ['{', ','].indexOf(lastNonWhitespace()) !== -1) {
|
||||||
// an unquoted object key (like a in '{a:2}')
|
// an unquoted object key (like a in '{a:2}')
|
||||||
parseKey();
|
parseKey();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ describe('util', function () {
|
||||||
assert.equal(util.sanitize('{a:2}'), '{"a":2}');
|
assert.equal(util.sanitize('{a:2}'), '{"a":2}');
|
||||||
assert.equal(util.sanitize('{\'a\':2}'), '{"a":2}');
|
assert.equal(util.sanitize('{\'a\':2}'), '{"a":2}');
|
||||||
assert.equal(util.sanitize('{a:\'foo\'}'), '{"a":"foo"}');
|
assert.equal(util.sanitize('{a:\'foo\'}'), '{"a":"foo"}');
|
||||||
|
assert.equal(util.sanitize('{a:\'foo\',b:\'bar\'}'), '{"a":"foo","b":"bar"}');
|
||||||
|
|
||||||
// should leave string content untouched
|
// should leave string content untouched
|
||||||
assert.equal(util.sanitize('"{a:b}"'), '"{a:b}"');
|
assert.equal(util.sanitize('"{a:b}"'), '"{a:b}"');
|
||||||
|
@ -28,6 +29,9 @@ describe('util', function () {
|
||||||
|
|
||||||
it('remove comments', function () {
|
it('remove comments', function () {
|
||||||
assert.equal(util.sanitize('/* foo */ {}'), ' {}');
|
assert.equal(util.sanitize('/* foo */ {}'), ' {}');
|
||||||
|
assert.equal(util.sanitize('/* foo */ {}'), ' {}');
|
||||||
|
assert.equal(util.sanitize('{a:\'foo\',/*hello*/b:\'bar\'}'), '{"a":"foo","b":"bar"}');
|
||||||
|
assert.equal(util.sanitize('{\na:\'foo\',//hello\nb:\'bar\'\n}'), '{\n"a":"foo",\n"b":"bar"\n}');
|
||||||
|
|
||||||
// should not remove comments in string
|
// should not remove comments in string
|
||||||
assert.equal(util.sanitize('{"str":"/* foo */"}'), '{"str":"/* foo */"}');
|
assert.equal(util.sanitize('{"str":"/* foo */"}'), '{"str":"/* foo */"}');
|
||||||
|
|
Loading…
Reference in New Issue