mirror of
https://github.com/golang/go
synced 2024-11-22 21:00:04 -07:00
cmd/go: in 'go list -m', ignore "not found" errors loading updates
"Not found" and "no matching version" errors usually indicate the user is offline or the proxy doesn't have a version of go.mod that could provide retractions. 'go list -m -u' should still succeed. We should still report unclassified errors though. Previously, we reported most errors loading retractions but did not report errors loading updates. This change makes those operations more consistent. Fixes #45305 Change-Id: I2f23a566c9481bc7ff229a177f39d78f6a8aae77 Reviewed-on: https://go-review.googlesource.com/c/go/+/306572 Trust: Jay Conrod <jayconrod@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com> Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
0e09e4143e
commit
23e1d36a87
@ -11,6 +11,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/goroot"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -108,7 +109,26 @@ func addUpdate(ctx context.Context, m *modinfo.ModulePublic) {
|
||||
return
|
||||
}
|
||||
|
||||
if info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed); err == nil && semver.Compare(info.Version, m.Version) > 0 {
|
||||
info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed)
|
||||
var noVersionErr *NoMatchingVersionError
|
||||
if errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
|
||||
// Ignore "not found" and "no matching version" errors. This usually means
|
||||
// the user is offline or the proxy doesn't have a matching version.
|
||||
//
|
||||
// We should report other errors though. An attacker that controls the
|
||||
// network shouldn't be able to hide versions by interfering with
|
||||
// the HTTPS connection. An attacker that controls the proxy may still
|
||||
// hide versions, since the "list" and "latest" endpoints are not
|
||||
// authenticated.
|
||||
return
|
||||
} else if err != nil {
|
||||
if m.Error == nil {
|
||||
m.Error = &modinfo.ModuleError{Err: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if semver.Compare(info.Version, m.Version) > 0 {
|
||||
m.Update = &modinfo.ModulePublic{
|
||||
Path: m.Path,
|
||||
Version: info.Version,
|
||||
@ -140,14 +160,26 @@ func addRetraction(ctx context.Context, m *modinfo.ModulePublic) {
|
||||
}
|
||||
|
||||
err := CheckRetractions(ctx, module.Version{Path: m.Path, Version: m.Version})
|
||||
var rerr *ModuleRetractedError
|
||||
if errors.As(err, &rerr) {
|
||||
if len(rerr.Rationale) == 0 {
|
||||
var noVersionErr *NoMatchingVersionError
|
||||
var retractErr *ModuleRetractedError
|
||||
if err == nil || errors.Is(err, fs.ErrNotExist) || errors.As(err, &noVersionErr) {
|
||||
// Ignore "not found" and "no matching version" errors. This usually means
|
||||
// the user is offline or the proxy doesn't have a go.mod file that could
|
||||
// contain retractions.
|
||||
//
|
||||
// We should report other errors though. An attacker that controls the
|
||||
// network shouldn't be able to hide versions by interfering with
|
||||
// the HTTPS connection. An attacker that controls the proxy may still
|
||||
// hide versions, since the "list" and "latest" endpoints are not
|
||||
// authenticated.
|
||||
return
|
||||
} else if errors.As(err, &retractErr) {
|
||||
if len(retractErr.Rationale) == 0 {
|
||||
m.Retracted = []string{"retracted by module author"}
|
||||
} else {
|
||||
m.Retracted = rerr.Rationale
|
||||
m.Retracted = retractErr.Rationale
|
||||
}
|
||||
} else if err != nil && m.Error == nil {
|
||||
} else if m.Error == nil {
|
||||
m.Error = &modinfo.ModuleError{Err: err.Error()}
|
||||
}
|
||||
}
|
||||
|
12
src/cmd/go/testdata/script/mod_list_retract.txt
vendored
12
src/cmd/go/testdata/script/mod_list_retract.txt
vendored
@ -29,12 +29,12 @@ go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retra
|
||||
go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused
|
||||
! stdout .
|
||||
|
||||
# 'go list -m -retracted mod@version' shows an error if the go.mod that should
|
||||
# contain the retractions is not available.
|
||||
! go list -m -retracted example.com/retract/missingmod@v1.0.0
|
||||
stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
|
||||
go list -e -m -retracted -f '{{.Error.Err}}' example.com/retract/missingmod@v1.0.0
|
||||
stdout '^loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
|
||||
# 'go list -m -retracted mod@version' does not show an error if the module
|
||||
# that would contain the retraction is unavailable. See #45305.
|
||||
go list -m -retracted -f '{{.Path}} {{.Version}} {{.Error}}' example.com/retract/missingmod@v1.0.0
|
||||
stdout '^example.com/retract/missingmod v1.0.0 <nil>$'
|
||||
exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info
|
||||
! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod
|
||||
|
||||
# 'go list -m -retracted mod@version' shows retractions.
|
||||
go list -m -retracted example.com/retract@v1.0.0-unused
|
||||
|
55
src/cmd/go/testdata/script/mod_list_update_nolatest.txt
vendored
Normal file
55
src/cmd/go/testdata/script/mod_list_update_nolatest.txt
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
# Check that if a proxy does not have a version of a module that could be
|
||||
# an upgrade, 'go list -m -u' still succeeds.
|
||||
# We use a local file proxy, since our test proxy doesn't have the behavior
|
||||
# we want to test, and we don't want it to be too clever.
|
||||
# Verifies #45305, where proxy.golang.org serves an empty /@v/list (200)
|
||||
# but has no /@latest (410) because the go.mod at the tip of the default
|
||||
# branch has a different major version suffix.
|
||||
env testproxy=$GOPROXY
|
||||
env GOPROXY=file://$WORK/proxy
|
||||
env GOSUMDB=off
|
||||
|
||||
# If the proxy does not return a list of versions (404/410)
|
||||
# or a latest version (404/410), we should see no error.
|
||||
go list -m example.com/noversion
|
||||
stdout '^example.com/noversion v0.0.0$'
|
||||
go list -m -u example.com/noversion
|
||||
stdout '^example.com/noversion v0.0.0$'
|
||||
|
||||
# If the proxy returns an empty list of versions (200, not 404/410)
|
||||
# but does not have a latest version (404/410), we should see no error.
|
||||
go list -m example.com/nolatest
|
||||
stdout '^example.com/nolatest v0.0.0$'
|
||||
go list -m -u example.com/nolatest
|
||||
stdout '^example.com/nolatest v0.0.0$'
|
||||
|
||||
# If proxy returns an invalid response, we should see an error.
|
||||
env GOPROXY=$testproxy/invalid
|
||||
! go list -m -u example.com/nolatest
|
||||
stderr '^go list -m: loading module retractions for example.com/nolatest@v0.0.0: invalid response from proxy "[^"]*": invalid character ''i'' looking for beginning of value$'
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
example.com/nolatest v0.0.0
|
||||
example.com/noversion v0.0.0
|
||||
)
|
||||
-- go.sum --
|
||||
example.com/nolatest v0.0.0/go.mod h1:HnLrCt6SJga5tCtJ7IzG9dOOCniY3G5C0VT7jfMdS0M=
|
||||
example.com/noversion v0.0.0/go.mod h1:2RUfWiCYsygSXPM2Igxx0FD3Kq33OnVdxm34eDDhXbQ=
|
||||
-- $WORK/proxy/example.com/nolatest/@v/list --
|
||||
-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.info --
|
||||
{"Version":"v0.0.0"}
|
||||
-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.mod --
|
||||
module example.com/nolatest
|
||||
|
||||
go 1.17
|
||||
-- $WORK/proxy/example.com/noversion/@v/v0.0.0.info --
|
||||
{"Version":"v0.0.0"}
|
||||
-- $WORK/proxy/example.com/noversion/@v/v0.0.0.mod --
|
||||
module example.com/noversion
|
||||
|
||||
go 1.17
|
@ -5,8 +5,10 @@
|
||||
go get -d
|
||||
|
||||
# The latest version, v1.9.0, is not available on the proxy.
|
||||
! go list -m -retracted example.com/retract/missingmod
|
||||
stderr '^go list -m: loading module retractions for example.com/retract/missingmod@v1.0.0: .*404 Not Found$'
|
||||
go list -m -retracted example.com/retract/missingmod
|
||||
stdout '^example.com/retract/missingmod v1.0.0$'
|
||||
exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info
|
||||
! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod
|
||||
|
||||
# If we replace that version, we should see retractions.
|
||||
go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0
|
||||
|
Loading…
Reference in New Issue
Block a user