Browse Source

Do not hang when opening backtick is the last character. Fixes #351

Dmitry Panov 3 years ago
parent
commit
e42ffa0493
3 changed files with 30 additions and 7 deletions
  1. 7 7
      parser/expression.go
  2. 1 0
      parser/lexer.go
  3. 22 0
      parser/parser_test.go

+ 7 - 7
parser/expression.go

@@ -469,25 +469,25 @@ func (self *_parser) parseTemplateLiteral(tagged bool) *ast.TemplateLiteral {
 	res := &ast.TemplateLiteral{
 		OpenQuote: self.idx,
 	}
-	for self.chr != -1 {
-		start := self.idx + 1
+	for {
+		start := self.offset
 		literal, parsed, finished, parseErr, err := self.parseTemplateCharacters()
 		if err != "" {
-			self.error(self.idx, err)
+			self.error(self.offset, err)
 		}
 		res.Elements = append(res.Elements, &ast.TemplateElement{
-			Idx:     start,
+			Idx:     self.idxOf(start),
 			Literal: literal,
 			Parsed:  parsed,
 			Valid:   parseErr == "",
 		})
 		if !tagged && parseErr != "" {
-			self.error(self.idx, parseErr)
+			self.error(self.offset, parseErr)
 		}
-		end := self.idx + 1
+		end := self.chrOffset - 1
 		self.next()
 		if finished {
-			res.CloseQuote = end
+			res.CloseQuote = self.idxOf(end)
 			break
 		}
 		expr := self.parseExpression()

+ 1 - 0
parser/lexer.go

@@ -832,6 +832,7 @@ func (self *_parser) parseTemplateCharacters() (literal string, parsed unistring
 	return
 unterminated:
 	err = err_UnexpectedEndOfInput
+	finished = true
 	return
 }
 

+ 22 - 0
parser/parser_test.go

@@ -494,6 +494,9 @@ func TestParserErr(t *testing.T) {
 		}
 		test(`0, { get a(param = null) {} };`, "(anonymous): Line 1:11 Getter must not have any formal parameters.")
 		test(`let{f(`, "(anonymous): Line 1:7 Unexpected end of input")
+		test("`", "(anonymous): Line 1:2 Unexpected end of input")
+		test(" `", "(anonymous): Line 1:3 Unexpected end of input")
+		test("` ", "(anonymous): Line 1:3 Unexpected end of input")
 	})
 }
 
@@ -1174,3 +1177,22 @@ func TestParseTemplateLiteral(t *testing.T) {
 		t.Fatal(prg.Body[0])
 	}
 }
+
+func TestParseTemplateLiteralWithTail(t *testing.T) {
+	parser := newParser("", "f()\n`test${a}tail` ")
+	prg, err := parser.parse()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if st, ok := prg.Body[0].(*ast.ExpressionStatement); ok {
+		if expr, ok := st.Expression.(*ast.TemplateLiteral); ok {
+			if expr.CloseQuote != 18 {
+				t.Fatalf("CloseQuote: %d", expr.CloseQuote)
+			}
+		} else {
+			t.Fatal(st)
+		}
+	} else {
+		t.Fatal(prg.Body[0])
+	}
+}