From 9f574694fd3c1e3093ecf38f8e506dc6c1dc24d1 Mon Sep 17 00:00:00 2001 From: Heschi Kreinick Date: Wed, 5 Feb 2020 16:34:39 -0500 Subject: [PATCH] internal/imports: prevent self-imports in the stdlib goimports has a fast path for stdlib imports that was not checking for import cycles. Add the check. Fixes golang/go#37063. Change-Id: I46c98c317d8f06f83018fef9ef7edf9222e6b3f3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/217958 Run-TryBot: Heschi Kreinick TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/imports/fix.go | 9 ++++++--- internal/imports/fix_test.go | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/internal/imports/fix.go b/internal/imports/fix.go index ac8f6b153d3..f95d0f44092 100644 --- a/internal/imports/fix.go +++ b/internal/imports/fix.go @@ -537,7 +537,7 @@ func getFixes(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv // derive package names from import paths, see if the file is already // complete. We can't add any imports yet, because we don't know // if missing references are actually package vars. - p := &pass{fset: fset, f: f, srcDir: srcDir} + p := &pass{fset: fset, f: f, srcDir: srcDir, env: env} if fixes, done := p.load(); done { return fixes, nil } @@ -559,8 +559,7 @@ func getFixes(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv } // Third pass: get real package names where we had previously used - // the naive algorithm. This is the first step that will use the - // environment, so we provide it here for the first time. + // the naive algorithm. p = &pass{fset: fset, f: f, srcDir: srcDir, env: env} p.loadRealPackageNames = true p.otherFiles = otherFiles @@ -853,6 +852,10 @@ func cmdDebugStr(cmd *exec.Cmd) string { func addStdlibCandidates(pass *pass, refs references) { add := func(pkg string) { + // Prevent self-imports. + if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.env.GOROOT, "src", pkg) == pass.srcDir { + return + } exports := copyExports(stdlib[pkg]) pass.addCandidate( &ImportInfo{ImportPath: pkg}, diff --git a/internal/imports/fix_test.go b/internal/imports/fix_test.go index 6e83527d31a..f2bc5b639a2 100644 --- a/internal/imports/fix_test.go +++ b/internal/imports/fix_test.go @@ -1577,6 +1577,27 @@ var _ = bytes.Buffer }) } +func TestStdlibSelfImports(t *testing.T) { + const input = `package ecdsa + +var _ = ecdsa.GenerateKey +` + + testConfig{ + module: packagestest.Module{ + Name: "ignored.com", + }, + }.test(t, func(t *goimportTest) { + got, err := t.processNonModule(filepath.Join(t.env.GOROOT, "src/crypto/ecdsa/foo.go"), []byte(input), nil) + if err != nil { + t.Fatalf("Process() = %v", err) + } + if string(got) != input { + t.Errorf("Got:\n%s\nWant:\n%s", got, input) + } + }) +} + type testConfig struct { gopathOnly bool module packagestest.Module