Skip to content

Commit df91e0d

Browse files
Make the JavaScript parser compliant with JSON5 specs
1 parent 64d25da commit df91e0d

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

lib/serde-fallback.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,16 @@ Parser.prototype.parseValue = function() {
283283
this.skipClutter();
284284

285285
const look = this.lookahead();
286-
if (this.isInitialDigit(look)) {
287-
return this.parseNumber();
288-
} else if (this.isLetter(look)) {
286+
if (this.isLetter(look)) {
289287
return this.parseIdentifier();
290288
} else if (this.isQuoteCharacter(look)) {
291289
return this.parseString();
292290
} else if (look === '[') {
293291
return this.parseArray();
294292
} else if (look === '{') {
295293
return this.parseObject();
294+
} else if (this.isInitialDigit(look) || look === 'I' || 'N') {
295+
return this.parseNumber();
296296
} else {
297297
return this.throwUnexpected();
298298
}
@@ -319,13 +319,13 @@ Parser.prototype.parseNumber = function() {
319319

320320
if (this.isDecimalDigit(look)) {
321321
this.throwError('Use new octal literals syntax');
322-
} else if (look === 'b') {
322+
} else if (look === 'b' || look === 'B') {
323323
base = 2;
324324
this.advance();
325-
} else if (look === 'o') {
325+
} else if (look === 'o' || look === 'O') {
326326
base = 8;
327327
this.advance();
328-
} else if (look === 'x') {
328+
} else if (look === 'x' || look === 'X') {
329329
base = 16;
330330
this.advance();
331331
} else {
@@ -341,6 +341,10 @@ Parser.prototype.parseNumber = function() {
341341
this.throwError('Invalid number format');
342342
}
343343

344+
if (value === Infinity) {
345+
this.throwError('Invalid number format');
346+
}
347+
344348
return negateResult ? -value : value;
345349
};
346350

@@ -470,6 +474,17 @@ Parser.prototype.parseString = function() {
470474
} else if (look === 'u') {
471475
this.retreat();
472476
string += this.parseUnicodeCharacter();
477+
} else if (controlCharacter === undefined) {
478+
if (string.slice(-1) !== ' ') {
479+
if (this.advance() === ' ') {
480+
string += ' ';
481+
this.retreat();
482+
} else {
483+
this.retreat();
484+
string += look;
485+
}
486+
}
487+
this.skipWhitespace();
473488
} else {
474489
string += look;
475490
}
@@ -659,15 +674,21 @@ Parser.prototype.parseObjectKey = function() {
659674
return this.parseString();
660675
}
661676

677+
if (this.isInitialDigit(this.lookahead())) {
678+
return this.parseNumber();
679+
}
662680
if (!this.isInitialIdentifierCharacter(this.lookahead())) {
663681
this.throwExpected('String or identifier');
664682
}
665683

666684
let key = '';
667685
while (this.isIdentifierCharacter(this.lookahead())) {
668686
key += this.advance();
687+
while (this.lookahead() === '\\') {
688+
this.advance();
689+
key += this.parseUnicodeCharacter();
690+
}
669691
}
670-
671692
return key;
672693
};
673694

lib/stringify.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ const STRINGIFIERS = {
7676
continue;
7777
}
7878

79-
if (!/^[a-zA-Z_$][\w$]*$/.test(key)) {
79+
if (/^[a-zA-Z_$][/\w$]*$/.test(key)) {
8080
key = STRINGIFIERS.string(key);
81+
} else {
82+
key = STRINGIFIERS.number(key);
8183
}
8284

8385
if (firstKey) {
@@ -126,7 +128,6 @@ function stringifyInternal(value, replacer, space, indent, key = '', holder) {
126128
} else {
127129
type = typeof value;
128130
}
129-
130131
const stringifier = STRINGIFIERS[type];
131132
if (stringifier) return stringifier(value, replacer, space, indent);
132133

0 commit comments

Comments
 (0)