From 5a4dc7e3310740e1b8aa0019ce093152dfdd4270 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Mon, 25 Mar 2024 12:21:47 -0400 Subject: [PATCH] [gopls-release-branch.0.15] internal/imports: fix two "nil pointer in interface" bugs CL 559635 changed newModuleResolver so that it can return (nil, err). That means it is no longer safe to unconditionally convert the first result to a Resolver interface, but we forgot to check in two places, causing a crash that was reported by telemetry. This change adds the two checks. Updates golang/go#66490 Updates golang/go#66730 Change-Id: I3f2b84ed792b1eea179fc0d4d5ee9843281506fc Reviewed-on: https://go-review.googlesource.com/c/tools/+/574136 Reviewed-by: Peter Weinberger LUCI-TryBot-Result: Go LUCI (cherry picked from commit 63b3b5af27310e1ad7822eb366ce29a17fe25699) Reviewed-on: https://go-review.googlesource.com/c/tools/+/577297 Reviewed-by: Alan Donovan --- internal/imports/fix.go | 4 +++- internal/imports/mod.go | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/internal/imports/fix.go b/internal/imports/fix.go index 6a18f63a44d..a9784f4252c 100644 --- a/internal/imports/fix.go +++ b/internal/imports/fix.go @@ -988,8 +988,10 @@ func (e *ProcessEnv) GetResolver() (Resolver, error) { // already know the view type. if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 { e.resolver = newGopathResolver(e) + } else if r, err := newModuleResolver(e, e.ModCache); err != nil { + e.resolverErr = err } else { - e.resolver, e.resolverErr = newModuleResolver(e, e.ModCache) + e.resolver = Resolver(r) } } diff --git a/internal/imports/mod.go b/internal/imports/mod.go index 3d0f38f6c23..4a034828406 100644 --- a/internal/imports/mod.go +++ b/internal/imports/mod.go @@ -313,15 +313,19 @@ func (r *ModuleResolver) ClearForNewScan() Resolver { // TODO(rfindley): move this to a new env.go, consolidating ProcessEnv methods. func (e *ProcessEnv) ClearModuleInfo() { if r, ok := e.resolver.(*ModuleResolver); ok { - resolver, resolverErr := newModuleResolver(e, e.ModCache) - if resolverErr == nil { - <-r.scanSema // acquire (guards caches) - resolver.moduleCacheCache = r.moduleCacheCache - resolver.otherCache = r.otherCache - r.scanSema <- struct{}{} // release - } - e.resolver = resolver - e.resolverErr = resolverErr + resolver, err := newModuleResolver(e, e.ModCache) + if err != nil { + e.resolver = nil + e.resolverErr = err + return + } + + <-r.scanSema // acquire (guards caches) + resolver.moduleCacheCache = r.moduleCacheCache + resolver.otherCache = r.otherCache + r.scanSema <- struct{}{} // release + + e.UpdateResolver(resolver) } }