Skip to content

Commit

Permalink
go/parser: don't accept trailing explicit semicolon
Browse files Browse the repository at this point in the history
Fixes golang#8207.

LGTM=gordon.klaus, bradfitz
R=golang-codereviews, wandakkelly, gordon.klaus, bradfitz
CC=golang-codereviews
https://golang.org/cl/106010046
  • Loading branch information
griesemer authored and wheatman committed Jun 20, 2018
1 parent 30cfb51 commit c20a169
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/pkg/go/parser/interface.go
Expand Up @@ -184,7 +184,7 @@ func ParseExpr(x string) (ast.Expr, error) {

// If a semicolon was inserted, consume it;
// report an error if there's more tokens.
if p.tok == token.SEMICOLON {
if p.tok == token.SEMICOLON && p.lit == "\n" {
p.next()
}
p.expect(token.EOF)
Expand Down
38 changes: 28 additions & 10 deletions src/pkg/go/parser/parser_test.go
Expand Up @@ -74,36 +74,54 @@ func TestParseExpr(t *testing.T) {
src := "a + b"
x, err := ParseExpr(src)
if err != nil {
t.Fatalf("ParseExpr(%s): %v", src, err)
t.Errorf("ParseExpr(%q): %v", src, err)
}
// sanity check
if _, ok := x.(*ast.BinaryExpr); !ok {
t.Errorf("ParseExpr(%s): got %T, want *ast.BinaryExpr", src, x)
t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x)
}

// a valid type expression
src = "struct{x *int}"
x, err = ParseExpr(src)
if err != nil {
t.Fatalf("ParseExpr(%s): %v", src, err)
t.Errorf("ParseExpr(%q): %v", src, err)
}
// sanity check
if _, ok := x.(*ast.StructType); !ok {
t.Errorf("ParseExpr(%s): got %T, want *ast.StructType", src, x)
t.Errorf("ParseExpr(%q): got %T, want *ast.StructType", src, x)
}

// an invalid expression
src = "a + *"
_, err = ParseExpr(src)
if err == nil {
t.Fatalf("ParseExpr(%s): got no error", src)
if _, err := ParseExpr(src); err == nil {
t.Errorf("ParseExpr(%q): got no error", src)
}

// a valid expression followed by extra tokens is invalid
src = "a[i] := x"
_, err = ParseExpr(src)
if err == nil {
t.Fatalf("ParseExpr(%s): got no error", src)
if _, err := ParseExpr(src); err == nil {
t.Errorf("ParseExpr(%q): got no error", src)
}

// a semicolon is not permitted unless automatically inserted
src = "a + b\n"
if _, err := ParseExpr(src); err != nil {
t.Errorf("ParseExpr(%q): got error %s", src, err)
}
src = "a + b;"
if _, err := ParseExpr(src); err == nil {
t.Errorf("ParseExpr(%q): got no error", src)
}

// various other stuff following a valid expression
const validExpr = "a + b"
const anything = "dh3*#D)#_"
for _, c := range "!)]};," {
src := validExpr + string(c) + anything
if _, err := ParseExpr(src); err == nil {
t.Errorf("ParseExpr(%q): got no error", src)
}
}

// ParseExpr must not crash
Expand Down

0 comments on commit c20a169

Please sign in to comment.