@@ -435,70 +435,160 @@ class JSON5Lexer(private val source: String) {
435435 val startColumn = column
436436 val startLine = line
437437
438- // Verify that the characters spell "null"
439- if (source.substring(pos, minOf(pos + 4 , source.length)) == " null" ) {
440- repeat(4 ) { advance() }
441- return Token .NullToken (startLine, startColumn)
438+ // Check each character of "null" individually
439+ if (currentChar != ' n' ) {
440+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
441+ }
442+ advance()
443+
444+ if (currentChar != ' u' ) {
445+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
446+ }
447+ advance()
448+
449+ if (currentChar != ' l' ) {
450+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
451+ }
452+ advance()
453+
454+ if (currentChar != ' l' ) {
455+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
442456 }
457+ advance()
443458
444- throw JSON5Exception ( " Unexpected identifier " , startLine, startColumn)
459+ return Token . NullToken ( startLine, startColumn)
445460 }
446461
447462 private fun readTrue (): Token {
448463 val startColumn = column
449464 val startLine = line
450465
451- // Verify that the characters spell "true"
452- if (source.substring(pos, minOf(pos + 4 , source.length)) == " true" ) {
453- repeat(4 ) { advance() }
454- return Token .BooleanToken (true , startLine, startColumn)
455- } else {
456- val c = source.getOrNull(pos + 3 )
457- if (c != null && pos + 3 < source.length) {
458- throw JSON5Exception .invalidChar(c, line, column + 3 )
459- }
466+ // Check each character of "true" individually
467+ if (currentChar != ' t' ) {
468+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
469+ }
470+ advance()
471+
472+ if (currentChar != ' r' ) {
473+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
460474 }
475+ advance()
461476
462- throw JSON5Exception (" Unexpected identifier" , startLine, startColumn)
477+ if (currentChar != ' u' ) {
478+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
479+ }
480+ advance()
481+
482+ if (currentChar != ' e' ) {
483+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
484+ }
485+ advance()
486+
487+ return Token .BooleanToken (true , startLine, startColumn)
463488 }
464489
465490 private fun readFalse (): Token {
466491 val startColumn = column
467492 val startLine = line
468493
469- // Verify that the characters spell "false"
470- if (source.substring(pos, minOf(pos + 5 , source.length)) == " false" ) {
471- repeat(5 ) { advance() }
472- return Token .BooleanToken (false , startLine, startColumn)
494+ // Check each character of "false" individually
495+ if (currentChar != ' f' ) {
496+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
497+ }
498+ advance()
499+
500+ if (currentChar != ' a' ) {
501+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
502+ }
503+ advance()
504+
505+ if (currentChar != ' l' ) {
506+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
507+ }
508+ advance()
509+
510+ if (currentChar != ' s' ) {
511+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
512+ }
513+ advance()
514+
515+ if (currentChar != ' e' ) {
516+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
473517 }
518+ advance()
474519
475- throw JSON5Exception ( " Unexpected identifier " , startLine, startColumn)
520+ return Token . BooleanToken ( false , startLine, startColumn)
476521 }
477522
478523 private fun readInfinity (): Token {
479524 val startColumn = column
480525 val startLine = line
481526
482- // Verify that the characters spell "Infinity"
483- if (source.substring(pos, minOf(pos + 8 , source.length)) == " Infinity" ) {
484- repeat(8 ) { advance() }
485- return Token .NumericToken (Double .POSITIVE_INFINITY , startLine, startColumn)
527+ // Check each character of "Infinity" individually
528+ if (currentChar != ' I' ) {
529+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
530+ }
531+ advance()
532+
533+ if (currentChar != ' n' ) {
534+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
535+ }
536+ advance()
537+
538+ if (currentChar != ' f' ) {
539+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
540+ }
541+ advance()
542+
543+ if (currentChar != ' i' ) {
544+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
545+ }
546+ advance()
547+
548+ if (currentChar != ' n' ) {
549+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
550+ }
551+ advance()
552+
553+ if (currentChar != ' i' ) {
554+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
555+ }
556+ advance()
557+
558+ if (currentChar != ' t' ) {
559+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
560+ }
561+ advance()
562+
563+ if (currentChar != ' y' ) {
564+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
486565 }
566+ advance()
487567
488- throw JSON5Exception ( " Unexpected identifier " , startLine, startColumn)
568+ return Token . NumericToken ( Double . POSITIVE_INFINITY , startLine, startColumn)
489569 }
490570
491571 private fun readNaN (): Token {
492572 val startColumn = column
493573 val startLine = line
494574
495- // Verify that the characters spell "NaN"
496- if (source.substring(pos, minOf(pos + 3 , source.length)) == " NaN" ) {
497- repeat(3 ) { advance() }
498- return Token .NumericToken (Double .NaN , startLine, startColumn)
575+ // Check each character of "NaN" individually
576+ if (currentChar != ' N' ) {
577+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
578+ }
579+ advance()
580+
581+ if (currentChar != ' a' ) {
582+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
583+ }
584+ advance()
585+
586+ if (currentChar != ' N' ) {
587+ throw JSON5Exception .invalidChar(currentChar ? : ' ' , line, column)
499588 }
589+ advance()
500590
501- throw JSON5Exception ( " Unexpected identifier " , startLine, startColumn)
591+ return Token . NumericToken ( Double . NaN , startLine, startColumn)
502592 }
503593
504594 private fun readNumber (): Token .NumericToken {
0 commit comments