diff --git a/go/types/resolver.go b/go/types/resolver.go index c5ffce9e18..26e69bfae6 100644 --- a/go/types/resolver.go +++ b/go/types/resolver.go @@ -10,6 +10,8 @@ import ( "go/ast" "go/token" "strconv" + "strings" + "unicode" "code.google.com/p/go.tools/go/exact" ) @@ -93,6 +95,23 @@ func (check *checker) arityMatch(s, init *ast.ValueSpec) { } } +func (check *checker) validatedImportPath(path string) (string, error) { + s, err := strconv.Unquote(path) + if err != nil { + return "", err + } + if s == "" { + return "", fmt.Errorf("empty string") + } + const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" + for _, r := range s { + if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { + return s, fmt.Errorf("invalid character %#U", r) + } + } + return s, nil +} + // TODO(gri) Split resolveFiles into smaller components. func (check *checker) resolveFiles(files []*ast.File) { @@ -158,7 +177,11 @@ func (check *checker) resolveFiles(files []*ast.File) { case *ast.ImportSpec: // import package var imp *Package - path, _ := strconv.Unquote(s.Path.Value) + path, err := check.validatedImportPath(s.Path.Value) + if err != nil { + check.errorf(s.Path.Pos(), "invalid import path (%s)", err) + continue + } if path == "C" && check.conf.FakeImportC { // TODO(gri) shouldn't create a new one each time imp = NewPackage("C", "C", NewScope(nil)) diff --git a/go/types/testdata/importdecl0b.src b/go/types/testdata/importdecl0b.src index 2073d98cde..6844e70982 100644 --- a/go/types/testdata/importdecl0b.src +++ b/go/types/testdata/importdecl0b.src @@ -11,6 +11,15 @@ import . "testing" // declares T in file scope import . /* ERROR "imported but not used" */ "unsafe" import . "fmt" // declares Println in file scope +import ( + // TODO(gri) At the moment, 2 errors are reported because both go/parser + // and the type checker report it. Eventually, this test should not be + // done by the parser anymore. + "" /* ERROR invalid import path */ /* ERROR invalid import path */ + "a!b" /* ERROR invalid import path */ /* ERROR invalid import path */ + "abc\xffdef" /* ERROR invalid import path */ /* ERROR invalid import path */ +) + // using "math" in this file doesn't affect its use in other files const Pi0 = math.Pi const Pi1 = m.Pi