Browse Source

Fixed panics in parser on some invalid inputs. Fixes #318.

Dmitry Panov 4 years ago
parent
commit
c04c643130
2 changed files with 13 additions and 12 deletions
  1. 12 12
      parser/expression.go
  2. 1 0
      parser/parser_test.go

+ 12 - 12
parser/expression.go

@@ -931,14 +931,14 @@ func (self *_parser) checkComma(from, to file.Idx) {
 	}
 }
 
-func (self *_parser) reinterpretAsArrayAssignmentPattern(left *ast.ArrayLiteral) *ast.ArrayPattern {
+func (self *_parser) reinterpretAsArrayAssignmentPattern(left *ast.ArrayLiteral) ast.Expression {
 	value := left.Value
 	var rest ast.Expression
 	for i, item := range value {
 		if spread, ok := item.(*ast.SpreadElement); ok {
 			if i != len(value)-1 {
 				self.error(item.Idx0(), "Rest element must be last element")
-				return nil
+				return &ast.BadExpression{From: left.Idx0(), To: left.Idx1()}
 			}
 			self.checkComma(spread.Expression.Idx1(), left.RightBracket)
 			rest = self.reinterpretAsDestructAssignTarget(spread.Expression)
@@ -965,14 +965,14 @@ func (self *_parser) reinterpretArrayAssignPatternAsBinding(pattern *ast.ArrayPa
 	return pattern
 }
 
-func (self *_parser) reinterpretAsArrayBindingPattern(left *ast.ArrayLiteral) *ast.ArrayPattern {
+func (self *_parser) reinterpretAsArrayBindingPattern(left *ast.ArrayLiteral) ast.BindingTarget {
 	value := left.Value
 	var rest ast.Expression
 	for i, item := range value {
 		if spread, ok := item.(*ast.SpreadElement); ok {
 			if i != len(value)-1 {
 				self.error(item.Idx0(), "Rest element must be last element")
-				return nil
+				return &ast.BadExpression{From: left.Idx0(), To: left.Idx1()}
 			}
 			self.checkComma(spread.Expression.Idx1(), left.RightBracket)
 			rest = self.reinterpretAsDestructBindingTarget(spread.Expression)
@@ -989,11 +989,11 @@ func (self *_parser) reinterpretAsArrayBindingPattern(left *ast.ArrayLiteral) *a
 	}
 }
 
-func (self *_parser) parseArrayBindingPattern() *ast.ArrayPattern {
+func (self *_parser) parseArrayBindingPattern() ast.BindingTarget {
 	return self.reinterpretAsArrayBindingPattern(self.parseArrayLiteral())
 }
 
-func (self *_parser) parseObjectBindingPattern() *ast.ObjectPattern {
+func (self *_parser) parseObjectBindingPattern() ast.BindingTarget {
 	return self.reinterpretAsObjectBindingPattern(self.parseObjectLiteral())
 }
 
@@ -1009,7 +1009,7 @@ func (self *_parser) reinterpretArrayObjectPatternAsBinding(pattern *ast.ObjectP
 	return pattern
 }
 
-func (self *_parser) reinterpretAsObjectBindingPattern(expr *ast.ObjectLiteral) *ast.ObjectPattern {
+func (self *_parser) reinterpretAsObjectBindingPattern(expr *ast.ObjectLiteral) ast.BindingTarget {
 	var rest ast.Expression
 	value := expr.Value
 	for i, prop := range value {
@@ -1025,7 +1025,7 @@ func (self *_parser) reinterpretAsObjectBindingPattern(expr *ast.ObjectLiteral)
 		case *ast.SpreadElement:
 			if i != len(expr.Value)-1 {
 				self.error(prop.Idx0(), "Rest element must be last element")
-				return nil
+				return &ast.BadExpression{From: expr.Idx0(), To: expr.Idx1()}
 			}
 			// TODO make sure there is no trailing comma
 			rest = self.reinterpretAsBindingRestElement(prop.Expression)
@@ -1034,7 +1034,7 @@ func (self *_parser) reinterpretAsObjectBindingPattern(expr *ast.ObjectLiteral)
 		}
 		if !ok {
 			self.error(prop.Idx0(), "Invalid destructuring binding target")
-			return nil
+			return &ast.BadExpression{From: expr.Idx0(), To: expr.Idx1()}
 		}
 	}
 	return &ast.ObjectPattern{
@@ -1045,7 +1045,7 @@ func (self *_parser) reinterpretAsObjectBindingPattern(expr *ast.ObjectLiteral)
 	}
 }
 
-func (self *_parser) reinterpretAsObjectAssignmentPattern(l *ast.ObjectLiteral) *ast.ObjectPattern {
+func (self *_parser) reinterpretAsObjectAssignmentPattern(l *ast.ObjectLiteral) ast.Expression {
 	var rest ast.Expression
 	value := l.Value
 	for i, prop := range value {
@@ -1061,7 +1061,7 @@ func (self *_parser) reinterpretAsObjectAssignmentPattern(l *ast.ObjectLiteral)
 		case *ast.SpreadElement:
 			if i != len(l.Value)-1 {
 				self.error(prop.Idx0(), "Rest element must be last element")
-				return nil
+				return &ast.BadExpression{From: l.Idx0(), To: l.Idx1()}
 			}
 			// TODO make sure there is no trailing comma
 			rest = prop.Expression
@@ -1070,7 +1070,7 @@ func (self *_parser) reinterpretAsObjectAssignmentPattern(l *ast.ObjectLiteral)
 		}
 		if !ok {
 			self.error(prop.Idx0(), "Invalid destructuring assignment target")
-			return nil
+			return &ast.BadExpression{From: l.Idx0(), To: l.Idx1()}
 		}
 	}
 	return &ast.ObjectPattern{

+ 1 - 0
parser/parser_test.go

@@ -486,6 +486,7 @@ func TestParserErr(t *testing.T) {
 			test(`var yield;`, nil)
 		}
 		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")
 	})
 }