Fixed #610: JSON Repair now removes trailing commas

This commit is contained in:
jos 2018-12-06 20:15:14 +01:00
parent 550e0a2c4e
commit 6551701153
3 changed files with 34 additions and 3 deletions

View File

@ -5,6 +5,7 @@ https://github.com/josdejong/jsoneditor
## not yet released, version 5.26.3 ## not yet released, version 5.26.3
- Fixed #610: JSON Repair now removes trailing commas.
- Upgraded devDependency `gulp` to v4. Thanks @maestr0. - Upgraded devDependency `gulp` to v4. Thanks @maestr0.

View File

@ -65,13 +65,17 @@ 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); }
function isWhiteSpace(c) {
return c === ' ' || c === '\n' || c === '\r' || c === '\t';
}
// get the last parsed non-whitespace character // get the last parsed non-whitespace character
function lastNonWhitespace () { function lastNonWhitespace () {
var p = chars.length - 1; var p = chars.length - 1;
while (p >= 0) { while (p >= 0) {
var pp = chars[p]; var pp = chars[p];
if (pp !== ' ' && pp !== '\n' && pp !== '\r' && pp !== '\t') { // non whitespace if (!isWhiteSpace(pp)) {
return pp; return pp;
} }
p--; p--;
@ -80,6 +84,16 @@ exports.sanitize = function (jsString) {
return ''; return '';
} }
// get at the first next non-white space character
function nextNonWhiteSpace() {
var iNext = i + 1;
while (iNext < jsString.length && isWhiteSpace(jsString[iNext])) {
iNext++;
}
return jsString[iNext];
}
// skip a block comment '/* ... */' // skip a block comment '/* ... */'
function skipBlockComment () { function skipBlockComment () {
i += 2; i += 2;
@ -166,7 +180,7 @@ exports.sanitize = function (jsString) {
} }
else if (c === '\u00A0' || (c >= '\u2000' && c <= '\u200A') || c === '\u202F' || c === '\u205F' || c === '\u3000') { else if (c === '\u00A0' || (c >= '\u2000' && c <= '\u200A') || c === '\u202F' || c === '\u205F' || c === '\u3000') {
// special white spaces (like non breaking space) // special white spaces (like non breaking space)
chars.push(' ') chars.push(' ');
i++ i++
} }
else if (c === quote) { else if (c === quote) {
@ -184,6 +198,10 @@ exports.sanitize = function (jsString) {
else if (c === quoteDblLeft) { else if (c === quoteDblLeft) {
parseString(quoteDblRight); parseString(quoteDblRight);
} }
else if (c === ',' && [']', '}'].indexOf(nextNonWhiteSpace()) !== -1) {
// skip trailing commas
i++;
}
else if (/[a-zA-Z_$]/.test(c) && ['{', ','].indexOf(lastNonWhitespace()) !== -1) { 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();

View File

@ -50,7 +50,7 @@ describe('util', function () {
assert.equal(util.sanitize('\u2018foo\u2019'), '"foo"') assert.equal(util.sanitize('\u2018foo\u2019'), '"foo"')
assert.equal(util.sanitize('\u201Cfoo\u201D'), '"foo"') assert.equal(util.sanitize('\u201Cfoo\u201D'), '"foo"')
assert.equal(util.sanitize('\u0060foo\u00B4'), '"foo"') assert.equal(util.sanitize('\u0060foo\u00B4'), '"foo"')
}) });
it('remove comments', function () { it('remove comments', function () {
assert.equal(util.sanitize('/* foo */ {}'), ' {}'); assert.equal(util.sanitize('/* foo */ {}'), ' {}');
@ -84,6 +84,18 @@ describe('util', function () {
assert.equal(util.sanitize('callback({}'), 'callback({}'); assert.equal(util.sanitize('callback({}'), 'callback({}');
}); });
it('should strip trailing zeros', function () {
// matching
assert.equal(util.sanitize('[1,2,3,]'), '[1,2,3]');
assert.equal(util.sanitize('[1,2,3,\n]'), '[1,2,3\n]');
assert.equal(util.sanitize('[1,2,3, \n ]'), '[1,2,3 \n ]');
assert.equal(util.sanitize('{"a":2,}'), '{"a":2}');
// not matching
assert.equal(util.sanitize('"[1,2,3,]"'), '"[1,2,3,]"');
assert.equal(util.sanitize('"{a:2,}"'), '"{a:2,}"');
});
}); });
describe('jsonPath', function () { describe('jsonPath', function () {