Skip to content

Commit 962753b

Browse files
committed
go/build: check for invalid import paths again
The go parser previously checked for invalid import paths, go/build, seeing the parse error would put files with invalid import paths into InvalidGoFiles. golang.org/cl/424855 removed that check from the parser, which meant files with invalid import paths not have any parse errors on them and not be put into InvalidGoFiles. Do a check for invalid import paths in go/build soon after parsing so we can make sure files with invalid import paths go into InvalidGoFiles. This fixes an issue where the Go command assumed that if a file wasn't invalid it had non empty import paths, leading to a panic. Fixes #60230 Fixes #60686 Change-Id: I33c1dc9304649536834939cef7c689940236ee20 Reviewed-on: https://go-review.googlesource.com/c/go/+/502615 Reviewed-by: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Michael Matloob <[email protected]> Run-TryBot: Michael Matloob <[email protected]>
1 parent a674c63 commit 962753b

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
! go list a.go
2+
! stdout .
3+
stderr 'invalid import path'
4+
! stderr panic
5+
6+
-- a.go --
7+
package a
8+
9+
import ""

src/go/build/read.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"go/ast"
1313
"go/parser"
14+
"go/scanner"
1415
"go/token"
1516
"io"
1617
"strconv"
@@ -459,6 +460,13 @@ func readGoInfo(f io.Reader, info *fileInfo) error {
459460
if err != nil {
460461
return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted)
461462
}
463+
if !isValidImport(path) {
464+
// The parser used to return a parse error for invalid import paths, but
465+
// no longer does, so check for and create the error here instead.
466+
info.parseErr = scanner.Error{Pos: info.fset.Position(spec.Pos()), Msg: "invalid import path: " + path}
467+
info.imports = nil
468+
return nil
469+
}
462470
if path == "embed" {
463471
hasEmbed = true
464472
}
@@ -516,6 +524,20 @@ func readGoInfo(f io.Reader, info *fileInfo) error {
516524
return nil
517525
}
518526

527+
// isValidImport checks if the import is a valid import using the more strict
528+
// checks allowed by the implementation restriction in https://go.dev/ref/spec#Import_declarations.
529+
// It was ported from the function of the same name that was removed from the
530+
// parser in CL 424855, when the parser stopped doing these checks.
531+
func isValidImport(s string) bool {
532+
const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
533+
for _, r := range s {
534+
if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
535+
return false
536+
}
537+
}
538+
return s != ""
539+
}
540+
519541
// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
520542
// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
521543
// This is based on a similar function in cmd/compile/internal/gc/noder.go;

0 commit comments

Comments
 (0)