Skip to content

Commit

Permalink
Fix two bugs with ident parsing (#32)
Browse files Browse the repository at this point in the history
This PR fixes two bugs where the fql-ts behaves differently from the
go library.

1. Leading escape sequences (e.g. `\$foo`) would report lex error
2. Leading underscore characters (e.g. `_foo`) would report lex error

Some customers have written in because the app reports a valid
destination filter created via Config API could not be parsed:
https://segment.atlassian.net/browse/PROT-3118
  • Loading branch information
Steve van Loben Sels authored Apr 21, 2021
1 parent cc06bb4 commit 752993c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/lexer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ test('Lexer passes ident fixtures', () => {

// Escaped idents
fix('a\\ b\\$c\\.', [t.Ident('a b$c.'), t.EOS()], false),
fix('\\$a\\ b\\$c\\.', [t.Ident('$a b$c.'), t.EOS()], false),

// Underscores
fix('_a_b_c', [t.Ident('_a_b_c'), t.EOS()], false),
])
})

Expand Down
17 changes: 13 additions & 4 deletions src/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class Lexer {
}
}

if (isAlpha(char) || char === '!' || char === '=' || char === '>' || char === '<') {
if (isAlpha(char) || char === '!' || char === '=' || char === '>' || char === '<' || char === '\\' || char === '_') {
tokens.push(this.lexOperatorOrConditional(char))
continue
}
Expand Down Expand Up @@ -235,9 +235,13 @@ export class Lexer {
}

private lexIdent(previous: string): Token {
/* this function differs from the go implementation in that the go impl
hasn't yet advanced the character so will do a peek/next loop. here we
have already done a next() so need to check to see if the first char is
an escape sequence */
let str = ''
while (isIdent(this.peek())) {
let { char } = this.next()
let char = previous
while (true) {

// Allow escaping of any character except EOS
if (char === '\\') {
Expand All @@ -252,6 +256,11 @@ export class Lexer {
if (str.length >= MAXIMUM_INDENT_LENGTH) {
throw new LexerError('unreasonable literal length', this.cursor)
}

if (!isIdent(this.peek())) {
break
}
char = this.next().char
}

const comingUp: string = this.peek()
Expand All @@ -271,7 +280,7 @@ export class Lexer {
)
}

return t.Ident(previous + str)
return t.Ident(str)
}

/**
Expand Down

0 comments on commit 752993c

Please sign in to comment.