libgo: update to Go 1.16.2 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/301459
This commit is contained in:
parent
7b843d4716
commit
3a5bcac339
@ -1,4 +1,4 @@
|
||||
2f281eb24ef256a2d3bb9fc1a7ef964d82b40182
|
||||
10b00ad87303d37c68b2d54dd25d655bd316946e
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
@ -1,4 +1,4 @@
|
||||
f21be2fdc6f1becdbed1592ea0b245cdeedc5ac8
|
||||
3979fb9af9ccfc0b7ccb613dcf256b18c2c295f0
|
||||
|
||||
The first line of this file holds the git revision number of the
|
||||
last merge done from the master library sources.
|
||||
|
@ -1 +1 @@
|
||||
go1.16
|
||||
go1.16.2
|
||||
|
@ -664,7 +664,7 @@ func toValidName(name string) string {
|
||||
if strings.HasPrefix(p, "/") {
|
||||
p = p[len("/"):]
|
||||
}
|
||||
for strings.HasPrefix(name, "../") {
|
||||
for strings.HasPrefix(p, "../") {
|
||||
p = p[len("../"):]
|
||||
}
|
||||
return p
|
||||
|
@ -1081,3 +1081,38 @@ func TestFS(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCVE202127919(t *testing.T) {
|
||||
// Archive containing only the file "../test.txt"
|
||||
data := []byte{
|
||||
0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2e, 0x2e,
|
||||
0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
|
||||
0x74, 0x0a, 0xc9, 0xc8, 0x2c, 0x56, 0xc8, 0x2c,
|
||||
0x56, 0x48, 0x54, 0x28, 0x49, 0x2d, 0x2e, 0x51,
|
||||
0x28, 0x49, 0xad, 0x28, 0x51, 0x48, 0xcb, 0xcc,
|
||||
0x49, 0xd5, 0xe3, 0x02, 0x04, 0x00, 0x00, 0xff,
|
||||
0xff, 0x50, 0x4b, 0x07, 0x08, 0xc0, 0xd7, 0xed,
|
||||
0xc3, 0x20, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00,
|
||||
0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14,
|
||||
0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xd7, 0xed, 0xc3, 0x20, 0x00, 0x00,
|
||||
0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e,
|
||||
0x2e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
|
||||
0x78, 0x74, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x39, 0x00,
|
||||
0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
|
||||
if err != nil {
|
||||
t.Fatalf("Error reading the archive: %v", err)
|
||||
}
|
||||
_, err = r.Open("test.txt")
|
||||
if err != nil {
|
||||
t.Errorf("Error reading file: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ require (
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
|
||||
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||
golang.org/x/mod v0.4.1
|
||||
golang.org/x/mod v0.4.2-0.20210302225053-d515b24adc21
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
|
||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
|
||||
)
|
||||
|
@ -431,7 +431,7 @@ func downloadPackage(p *load.Package) error {
|
||||
}
|
||||
importPrefix = importPrefix[:slash]
|
||||
}
|
||||
if err := module.CheckImportPath(importPrefix); err != nil {
|
||||
if err := checkImportPath(importPrefix); err != nil {
|
||||
return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
|
||||
}
|
||||
security := web.SecureOnly
|
||||
@ -591,3 +591,31 @@ func selectTag(goVersion string, tags []string) (match string) {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// checkImportPath is like module.CheckImportPath, but it forbids leading dots
|
||||
// in path elements. This can lead to 'go get' creating .git and other VCS
|
||||
// directories in places we might run VCS tools later.
|
||||
func checkImportPath(path string) error {
|
||||
if err := module.CheckImportPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
checkElem := func(elem string) error {
|
||||
if elem[0] == '.' {
|
||||
return fmt.Errorf("malformed import path %q: leading dot in path element", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
elemStart := 0
|
||||
for i, r := range path {
|
||||
if r == '/' {
|
||||
if err := checkElem(path[elemStart:]); err != nil {
|
||||
return err
|
||||
}
|
||||
elemStart = i + 1
|
||||
}
|
||||
}
|
||||
if err := checkElem(path[elemStart:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
||||
ResolveMissingImports: true,
|
||||
LoadTests: true,
|
||||
AllowErrors: tidyE,
|
||||
SilenceMissingStdImports: true,
|
||||
}, "all")
|
||||
|
||||
modload.TidyBuildList()
|
||||
|
@ -68,6 +68,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
|
||||
ResolveMissingImports: true,
|
||||
UseVendorAll: true,
|
||||
AllowErrors: vendorE,
|
||||
SilenceMissingStdImports: true,
|
||||
}
|
||||
_, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
|
||||
|
||||
|
@ -1514,7 +1514,7 @@ func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns
|
||||
}
|
||||
}
|
||||
if retractPath != "" {
|
||||
fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest", retractPath)
|
||||
fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest\n", retractPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ func (q *query) validate() error {
|
||||
if q.pattern == "all" {
|
||||
// If there is no main module, "all" is not meaningful.
|
||||
if !modload.HasModRoot() {
|
||||
return fmt.Errorf(`cannot match "all": working directory is not part of a module`)
|
||||
return fmt.Errorf(`cannot match "all": %v`, modload.ErrNoModRoot)
|
||||
}
|
||||
if !versionOkForMainModule(q.version) {
|
||||
// TODO(bcmills): "all@none" seems like a totally reasonable way to
|
||||
|
@ -51,7 +51,7 @@ func (e *ImportMissingError) Error() string {
|
||||
if e.isStd {
|
||||
return fmt.Sprintf("package %s is not in GOROOT (%s)", e.Path, filepath.Join(cfg.GOROOT, "src", e.Path))
|
||||
}
|
||||
if e.QueryErr != nil {
|
||||
if e.QueryErr != nil && e.QueryErr != ErrNoModRoot {
|
||||
return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr)
|
||||
}
|
||||
if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && allowMissingModuleImports) {
|
||||
@ -66,13 +66,11 @@ func (e *ImportMissingError) Error() string {
|
||||
return fmt.Sprintf("module %s provides package %s and is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, e.Path, suggestArg)
|
||||
}
|
||||
|
||||
suggestion := ""
|
||||
if !HasModRoot() {
|
||||
suggestion = ": working directory is not part of a module"
|
||||
} else {
|
||||
suggestion = fmt.Sprintf("; to add it:\n\tgo get %s", e.Path)
|
||||
message := fmt.Sprintf("no required module provides package %s", e.Path)
|
||||
if e.QueryErr != nil {
|
||||
return fmt.Sprintf("%s: %v", message, e.QueryErr)
|
||||
}
|
||||
return fmt.Sprintf("no required module provides package %s%s", e.Path, suggestion)
|
||||
return fmt.Sprintf("%s; to add it:\n\tgo get %s", message, e.Path)
|
||||
}
|
||||
|
||||
if e.newMissingVersion != "" {
|
||||
@ -318,7 +316,11 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
|
||||
return mods[0], dirs[0], nil
|
||||
}
|
||||
|
||||
return module.Version{}, "", &ImportMissingError{Path: path, isStd: pathIsStd}
|
||||
var queryErr error
|
||||
if !HasModRoot() {
|
||||
queryErr = ErrNoModRoot
|
||||
}
|
||||
return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr, isStd: pathIsStd}
|
||||
}
|
||||
|
||||
// queryImport attempts to locate a module that can be added to the current
|
||||
|
@ -177,7 +177,7 @@ func Init() {
|
||||
base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.")
|
||||
}
|
||||
if RootMode == NeedRoot {
|
||||
base.Fatalf("go: cannot find main module; see 'go help modules'")
|
||||
base.Fatalf("go: %v", ErrNoModRoot)
|
||||
}
|
||||
if !mustUseModules {
|
||||
// GO111MODULE is 'auto', and we can't find a module root.
|
||||
@ -338,9 +338,11 @@ func die() {
|
||||
}
|
||||
base.Fatalf("go: cannot find main module, but found %s in %s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd)
|
||||
}
|
||||
base.Fatalf("go: cannot find main module; see 'go help modules'")
|
||||
base.Fatalf("go: %v", ErrNoModRoot)
|
||||
}
|
||||
|
||||
var ErrNoModRoot = errors.New("go.mod file not found in current directory or any parent directory; see 'go help modules'")
|
||||
|
||||
// LoadModFile sets Target and, if there is a main module, parses the initial
|
||||
// build list from its go.mod file.
|
||||
//
|
||||
@ -539,9 +541,10 @@ func fixVersion(ctx context.Context, fixed *bool) modfile.VersionFixer {
|
||||
}
|
||||
}
|
||||
if vers != "" && module.CanonicalVersion(vers) == vers {
|
||||
if err := module.CheckPathMajor(vers, pathMajor); err == nil {
|
||||
return vers, nil
|
||||
if err := module.CheckPathMajor(vers, pathMajor); err != nil {
|
||||
return "", module.VersionError(module.Version{Path: path, Version: vers}, err)
|
||||
}
|
||||
return vers, nil
|
||||
}
|
||||
|
||||
info, err := Query(ctx, path, vers, "", nil)
|
||||
|
@ -73,7 +73,7 @@ func listModules(ctx context.Context, args []string, listVersions, listRetracted
|
||||
base.Fatalf("go: cannot use relative path %s to specify module", arg)
|
||||
}
|
||||
if !HasModRoot() && (arg == "all" || strings.Contains(arg, "...")) {
|
||||
base.Fatalf("go: cannot match %q: working directory is not part of a module", arg)
|
||||
base.Fatalf("go: cannot match %q: %v", arg, ErrNoModRoot)
|
||||
}
|
||||
if i := strings.Index(arg, "@"); i >= 0 {
|
||||
path := arg[:i]
|
||||
|
@ -170,6 +170,12 @@ type PackageOpts struct {
|
||||
// that occur while loading packages. SilenceErrors implies AllowErrors.
|
||||
SilenceErrors bool
|
||||
|
||||
// SilenceMissingStdImports indicates that LoadPackages should not print
|
||||
// errors or terminate the process if an imported package is missing, and the
|
||||
// import path looks like it might be in the standard library (perhaps in a
|
||||
// future version).
|
||||
SilenceMissingStdImports bool
|
||||
|
||||
// SilenceUnmatchedWarnings suppresses the warnings normally emitted for
|
||||
// patterns that did not match any packages.
|
||||
SilenceUnmatchedWarnings bool
|
||||
@ -287,8 +293,13 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
|
||||
sumErr.importerIsTest = importer.testOf != nil
|
||||
}
|
||||
}
|
||||
silence := opts.SilenceErrors
|
||||
if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) &&
|
||||
stdErr.isStd && opts.SilenceMissingStdImports {
|
||||
silence = true
|
||||
}
|
||||
|
||||
if !opts.SilenceErrors {
|
||||
if !silence {
|
||||
if opts.AllowErrors {
|
||||
fmt.Fprintf(os.Stderr, "%s: %v\n", pkg.stackText(), pkg.err)
|
||||
} else {
|
||||
|
@ -96,28 +96,12 @@ func runRun(ctx context.Context, cmd *base.Command, args []string) {
|
||||
base.Fatalf("go run: no go files listed")
|
||||
}
|
||||
cmdArgs := args[i:]
|
||||
if p.Error != nil {
|
||||
base.Fatalf("%s", p.Error)
|
||||
}
|
||||
load.CheckPackageErrors([]*load.Package{p})
|
||||
|
||||
p.Internal.OmitDebug = true
|
||||
if len(p.DepsErrors) > 0 {
|
||||
// Since these are errors in dependencies,
|
||||
// the same error might show up multiple times,
|
||||
// once in each package that depends on it.
|
||||
// Only print each once.
|
||||
printed := map[*load.PackageError]bool{}
|
||||
for _, err := range p.DepsErrors {
|
||||
if !printed[err] {
|
||||
printed[err] = true
|
||||
base.Errorf("%s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
base.ExitIfErrors()
|
||||
if p.Name != "main" {
|
||||
base.Fatalf("go run: cannot run non-main package")
|
||||
}
|
||||
p.Internal.OmitDebug = true
|
||||
p.Target = "" // must build - not up to date
|
||||
if p.Internal.CmdlineFiles {
|
||||
//set executable name if go file is given as cmd-argument
|
||||
|
@ -18,7 +18,7 @@ stdout '^m$'
|
||||
# Test that we ignore directories when trying to find alternate config files.
|
||||
cd $WORK/gopkgdir/x
|
||||
! go list .
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! stderr 'Gopkg.lock'
|
||||
|
||||
-- $WORK/test/Gopkg.lock --
|
||||
|
16
libgo/go/cmd/go/testdata/script/mod_edit.txt
vendored
16
libgo/go/cmd/go/testdata/script/mod_edit.txt
vendored
@ -16,9 +16,9 @@ cmpenv go.mod $WORK/go.mod.init
|
||||
cmpenv go.mod $WORK/go.mod.init
|
||||
|
||||
# go mod edits
|
||||
go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
|
||||
go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -exclude=x.1@v2.0.0+incompatible -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0
|
||||
cmpenv go.mod $WORK/go.mod.edit1
|
||||
go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
|
||||
go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropexclude=x.1@v2.0.0+incompatible -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
|
||||
cmpenv go.mod $WORK/go.mod.edit2
|
||||
|
||||
# -exclude and -retract reject invalid versions.
|
||||
@ -27,6 +27,17 @@ stderr '^go mod: -exclude=example.com/m@bad: version "bad" invalid: must be of t
|
||||
! go mod edit -retract=bad
|
||||
stderr '^go mod: -retract=bad: version "bad" invalid: must be of the form v1.2.3$'
|
||||
|
||||
! go mod edit -exclude=example.com/m@v2.0.0
|
||||
stderr '^go mod: -exclude=example.com/m@v2\.0\.0: version "v2\.0\.0" invalid: should be v2\.0\.0\+incompatible \(or module example\.com/m/v2\)$'
|
||||
|
||||
! go mod edit -exclude=example.com/m/v2@v1.0.0
|
||||
stderr '^go mod: -exclude=example.com/m/v2@v1\.0\.0: version "v1\.0\.0" invalid: should be v2, not v1$'
|
||||
|
||||
! go mod edit -exclude=gopkg.in/example.v1@v2.0.0
|
||||
stderr '^go mod: -exclude=gopkg\.in/example\.v1@v2\.0\.0: version "v2\.0\.0" invalid: should be v1, not v2$'
|
||||
|
||||
cmpenv go.mod $WORK/go.mod.edit2
|
||||
|
||||
# go mod edit -json
|
||||
go mod edit -json
|
||||
cmpenv stdout $WORK/go.mod.json
|
||||
@ -88,6 +99,7 @@ require x.1 v1.0.0
|
||||
exclude (
|
||||
x.1 v1.2.0
|
||||
x.1 v1.2.1
|
||||
x.1 v2.0.0+incompatible
|
||||
)
|
||||
|
||||
replace (
|
||||
|
2
libgo/go/cmd/go/testdata/script/mod_find.txt
vendored
2
libgo/go/cmd/go/testdata/script/mod_find.txt
vendored
@ -49,7 +49,7 @@ rm go.mod
|
||||
# Test that we ignore directories when trying to find go.mod.
|
||||
cd $WORK/gomoddir
|
||||
! go list .
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
[!symlink] stop
|
||||
|
||||
|
52
libgo/go/cmd/go/testdata/script/mod_outside.txt
vendored
52
libgo/go/cmd/go/testdata/script/mod_outside.txt
vendored
@ -12,13 +12,13 @@ stdout 'NUL|/dev/null'
|
||||
# 'go list' without arguments implicitly operates on the current directory,
|
||||
# which is not in a module.
|
||||
! go list
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
go list -m
|
||||
stdout '^command-line-arguments$'
|
||||
# 'go list' in the working directory should fail even if there is a a 'package
|
||||
# main' present: without a main module, we do not know its package path.
|
||||
! go list ./needmod
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go list all' lists the transitive import graph of the main module,
|
||||
# which is empty if there is no main module.
|
||||
@ -41,7 +41,7 @@ stdout 'command-line-arguments'
|
||||
|
||||
# 'go list' on a package from a module should fail.
|
||||
! go list example.com/printversion
|
||||
stderr '^no required module provides package example.com/printversion: working directory is not part of a module$'
|
||||
stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go list -m' with an explicit version should resolve that version.
|
||||
@ -54,19 +54,19 @@ stdout 'v1.0.0\s+v1.0.1\s+v1.1.0'
|
||||
|
||||
# 'go list -m all' should fail. "all" is not meaningful outside of a module.
|
||||
! go list -m all
|
||||
stderr 'go: cannot match "all": working directory is not part of a module'
|
||||
stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go list -m <mods> all' should also fail.
|
||||
! go list -m example.com/printversion@v1.0.0 all
|
||||
stderr 'go: cannot match "all": working directory is not part of a module'
|
||||
stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! stdout 'example.com/version'
|
||||
|
||||
# 'go list -m' with wildcards should fail. Wildcards match modules in the
|
||||
# build list, so they aren't meaningful outside a module.
|
||||
! go list -m ...
|
||||
stderr 'go: cannot match "...": working directory is not part of a module'
|
||||
stderr 'go: cannot match "...": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! go list -m rsc.io/quote/...
|
||||
stderr 'go: cannot match "rsc.io/quote/...": working directory is not part of a module'
|
||||
stderr 'go: cannot match "rsc.io/quote/...": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go clean' should skip the current directory if it isn't in a module.
|
||||
@ -76,20 +76,20 @@ go clean -n
|
||||
|
||||
# 'go mod graph' should fail, since there's no module graph.
|
||||
! go mod graph
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go mod why' should fail, since there is no main module to depend on anything.
|
||||
! go mod why -m example.com/version
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go mod edit', 'go mod tidy', and 'go mod fmt' should fail:
|
||||
# there is no go.mod file to edit.
|
||||
! go mod tidy
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! go mod edit -fmt
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! go mod edit -require example.com/version@v1.0.0
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go mod download' without arguments should report an error.
|
||||
@ -104,33 +104,33 @@ exists $GOPATH/pkg/mod/cache/download/example.com/printversion/@v/v1.0.0.zip
|
||||
|
||||
# 'go mod download all' should fail. "all" is not meaningful outside of a module.
|
||||
! go mod download all
|
||||
stderr 'go: cannot match "all": working directory is not part of a module'
|
||||
stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go mod vendor' should fail: it starts by clearing the existing vendor
|
||||
# directory, and we don't know where that is.
|
||||
! go mod vendor
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go mod verify' should fail: we have no modules to verify.
|
||||
! go mod verify
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go get' without arguments implicitly operates on the main module, and thus
|
||||
# should fail.
|
||||
! go get
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! go get -u
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
! go get -u ./needmod
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go get -u all' upgrades the transitive import graph of the main module,
|
||||
# which is empty.
|
||||
! go get -u all
|
||||
stderr 'go get: cannot match "all": working directory is not part of a module'
|
||||
stderr '^go get: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go get' should check the proposed module graph for consistency,
|
||||
# even though we won't write it anywhere.
|
||||
@ -147,16 +147,16 @@ exists $GOPATH/pkg/mod/example.com/version@v1.0.0
|
||||
# 'go build' without arguments implicitly operates on the current directory, and should fail.
|
||||
cd needmod
|
||||
! go build
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
cd ..
|
||||
|
||||
# 'go build' of a non-module directory should fail too.
|
||||
! go build ./needmod
|
||||
stderr 'cannot find main module'
|
||||
stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go build' of source files should fail if they import anything outside std.
|
||||
! go build -n ./needmod/needmod.go
|
||||
stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module$'
|
||||
stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go build' of source files should succeed if they do not import anything outside std.
|
||||
go build -n -o ignore ./stdonly/stdonly.go
|
||||
@ -179,7 +179,7 @@ go doc fmt
|
||||
|
||||
# 'go doc' should fail for a package path outside a module.
|
||||
! go doc example.com/version
|
||||
stderr 'doc: no required module provides package example.com/version: working directory is not part of a module'
|
||||
stderr 'doc: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go install' with a version should succeed if all constraints are met.
|
||||
# See mod_install_pkg_version.
|
||||
@ -194,7 +194,7 @@ stderr '^go install: version is required when current directory is not in a modu
|
||||
# 'go install' should fail if a source file imports a package that must be
|
||||
# resolved to a module.
|
||||
! go install ./needmod/needmod.go
|
||||
stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module'
|
||||
stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go install' should succeed with a package in GOROOT.
|
||||
go install cmd/addr2line
|
||||
@ -206,12 +206,12 @@ stderr 'can only use path@version syntax with'
|
||||
|
||||
# 'go run' should fail if a package argument must be resolved to a module.
|
||||
! go run example.com/printversion
|
||||
stderr '^no required module provides package example.com/printversion: working directory is not part of a module$'
|
||||
stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
# 'go run' should fail if a source file imports a package that must be
|
||||
# resolved to a module.
|
||||
! go run ./needmod/needmod.go
|
||||
stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module$'
|
||||
stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
|
||||
|
||||
|
||||
# 'go fmt' should be able to format files outside of a module.
|
||||
|
@ -4,12 +4,12 @@ env GO111MODULE=on
|
||||
# 'go mod tidy' and 'go mod vendor' should not hide loading errors.
|
||||
|
||||
! go mod tidy
|
||||
stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)'
|
||||
! stderr 'package nonexist is not in GOROOT'
|
||||
stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
|
||||
stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
|
||||
|
||||
! go mod vendor
|
||||
stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)'
|
||||
! stderr 'package nonexist is not in GOROOT'
|
||||
stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
|
||||
stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
|
||||
|
||||
|
2
libgo/go/cmd/vendor/modules.txt
vendored
2
libgo/go/cmd/vendor/modules.txt
vendored
@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
|
||||
golang.org/x/crypto/ed25519
|
||||
golang.org/x/crypto/ed25519/internal/edwards25519
|
||||
golang.org/x/crypto/ssh/terminal
|
||||
# golang.org/x/mod v0.4.1
|
||||
# golang.org/x/mod v0.4.2-0.20210302225053-d515b24adc21
|
||||
## explicit
|
||||
golang.org/x/mod/internal/lazyregexp
|
||||
golang.org/x/mod/modfile
|
||||
|
@ -285,16 +285,17 @@ func (d *Decoder) Token() (Token, error) {
|
||||
if d.nextToken != nil {
|
||||
t = d.nextToken
|
||||
d.nextToken = nil
|
||||
} else if t, err = d.rawToken(); err != nil {
|
||||
switch {
|
||||
case err == io.EOF && d.t != nil:
|
||||
err = nil
|
||||
case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF:
|
||||
} else {
|
||||
if t, err = d.rawToken(); t == nil && err != nil {
|
||||
if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
|
||||
err = d.syntaxError("unexpected EOF")
|
||||
}
|
||||
return t, err
|
||||
return nil, err
|
||||
}
|
||||
// We still have a token to process, so clear any
|
||||
// errors (e.g. EOF) and proceed.
|
||||
err = nil
|
||||
}
|
||||
|
||||
if !d.Strict {
|
||||
if t1, ok := d.autoClose(t); ok {
|
||||
d.nextToken = t
|
||||
|
@ -33,30 +33,90 @@ func (t *toks) Token() (Token, error) {
|
||||
|
||||
func TestDecodeEOF(t *testing.T) {
|
||||
start := StartElement{Name: Name{Local: "test"}}
|
||||
t.Run("EarlyEOF", func(t *testing.T) {
|
||||
d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{
|
||||
tests := []struct {
|
||||
name string
|
||||
tokens []Token
|
||||
ok bool
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
tokens: []Token{
|
||||
start,
|
||||
start.End(),
|
||||
}})
|
||||
},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
name: "Malformed",
|
||||
tokens: []Token{
|
||||
start,
|
||||
StartElement{Name: Name{Local: "bad"}},
|
||||
start.End(),
|
||||
},
|
||||
ok: false,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
for _, eof := range []bool{true, false} {
|
||||
name := fmt.Sprintf("%s/earlyEOF=%v", tc.name, eof)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
d := NewTokenDecoder(&toks{
|
||||
earlyEOF: eof,
|
||||
t: tc.tokens,
|
||||
})
|
||||
err := d.Decode(&struct {
|
||||
XMLName Name `xml:"test"`
|
||||
}{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
if tc.ok && err != nil {
|
||||
t.Fatalf("d.Decode: expected nil error, got %v", err)
|
||||
}
|
||||
if _, ok := err.(*SyntaxError); !tc.ok && !ok {
|
||||
t.Errorf("d.Decode: expected syntax error, got %v", err)
|
||||
}
|
||||
})
|
||||
t.Run("LateEOF", func(t *testing.T) {
|
||||
d := NewTokenDecoder(&toks{t: []Token{
|
||||
start,
|
||||
start.End(),
|
||||
}})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type toksNil struct {
|
||||
returnEOF bool
|
||||
t []Token
|
||||
}
|
||||
|
||||
func (t *toksNil) Token() (Token, error) {
|
||||
if len(t.t) == 0 {
|
||||
if !t.returnEOF {
|
||||
// Return nil, nil before returning an EOF. It's legal, but
|
||||
// discouraged.
|
||||
t.returnEOF = true
|
||||
return nil, nil
|
||||
}
|
||||
return nil, io.EOF
|
||||
}
|
||||
var tok Token
|
||||
tok, t.t = t.t[0], t.t[1:]
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
func TestDecodeNilToken(t *testing.T) {
|
||||
for _, strict := range []bool{true, false} {
|
||||
name := fmt.Sprintf("Strict=%v", strict)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
start := StartElement{Name: Name{Local: "test"}}
|
||||
bad := StartElement{Name: Name{Local: "bad"}}
|
||||
d := NewTokenDecoder(&toksNil{
|
||||
// Malformed
|
||||
t: []Token{start, bad, start.End()},
|
||||
})
|
||||
d.Strict = strict
|
||||
err := d.Decode(&struct {
|
||||
XMLName Name `xml:"test"`
|
||||
}{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
if _, ok := err.(*SyntaxError); !ok {
|
||||
t.Errorf("d.Decode: expected syntax error, got %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const testInput = `
|
||||
|
@ -614,7 +614,7 @@ func TestImportPackageOutsideModule(t *testing.T) {
|
||||
ctxt.GOPATH = gopath
|
||||
ctxt.Dir = filepath.Join(gopath, "src/example.com/p")
|
||||
|
||||
want := "working directory is not part of a module"
|
||||
want := "go.mod file not found in current directory or any parent directory"
|
||||
if _, err := ctxt.Import("example.com/p", gopath, FindOnly); err == nil {
|
||||
t.Fatal("importing package when no go.mod is present succeeded unexpectedly")
|
||||
} else if errStr := err.Error(); !strings.Contains(errStr, want) {
|
||||
|
@ -125,6 +125,12 @@ func (f *File) AddComment(text string) {
|
||||
|
||||
type VersionFixer func(path, version string) (string, error)
|
||||
|
||||
// errDontFix is returned by a VersionFixer to indicate the version should be
|
||||
// left alone, even if it's not canonical.
|
||||
var dontFixRetract VersionFixer = func(_, vers string) (string, error) {
|
||||
return vers, nil
|
||||
}
|
||||
|
||||
// Parse parses the data, reported in errors as being from file,
|
||||
// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found.
|
||||
func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
|
||||
@ -142,7 +148,7 @@ func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) {
|
||||
return parseToFile(file, data, fix, false)
|
||||
}
|
||||
|
||||
func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File, error) {
|
||||
func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parsed *File, err error) {
|
||||
fs, err := parse(file, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -150,8 +156,18 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
|
||||
f := &File{
|
||||
Syntax: fs,
|
||||
}
|
||||
|
||||
var errs ErrorList
|
||||
|
||||
// fix versions in retract directives after the file is parsed.
|
||||
// We need the module path to fix versions, and it might be at the end.
|
||||
defer func() {
|
||||
oldLen := len(errs)
|
||||
f.fixRetract(fix, &errs)
|
||||
if len(errs) > oldLen {
|
||||
parsed, err = nil, errs
|
||||
}
|
||||
}()
|
||||
|
||||
for _, x := range fs.Stmt {
|
||||
switch x := x.(type) {
|
||||
case *Line:
|
||||
@ -370,7 +386,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
|
||||
|
||||
case "retract":
|
||||
rationale := parseRetractRationale(block, line)
|
||||
vi, err := parseVersionInterval(verb, &args, fix)
|
||||
vi, err := parseVersionInterval(verb, "", &args, dontFixRetract)
|
||||
if err != nil {
|
||||
if strict {
|
||||
wrapError(err)
|
||||
@ -397,6 +413,47 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
|
||||
}
|
||||
}
|
||||
|
||||
// fixRetract applies fix to each retract directive in f, appending any errors
|
||||
// to errs.
|
||||
//
|
||||
// Most versions are fixed as we parse the file, but for retract directives,
|
||||
// the relevant module path is the one specified with the module directive,
|
||||
// and that might appear at the end of the file (or not at all).
|
||||
func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) {
|
||||
if fix == nil {
|
||||
return
|
||||
}
|
||||
path := ""
|
||||
if f.Module != nil {
|
||||
path = f.Module.Mod.Path
|
||||
}
|
||||
var r *Retract
|
||||
wrapError := func(err error) {
|
||||
*errs = append(*errs, Error{
|
||||
Filename: f.Syntax.Name,
|
||||
Pos: r.Syntax.Start,
|
||||
Err: err,
|
||||
})
|
||||
}
|
||||
|
||||
for _, r = range f.Retract {
|
||||
if path == "" {
|
||||
wrapError(errors.New("no module directive found, so retract cannot be used"))
|
||||
return // only print the first one of these
|
||||
}
|
||||
|
||||
args := r.Syntax.Token
|
||||
if args[0] == "retract" {
|
||||
args = args[1:]
|
||||
}
|
||||
vi, err := parseVersionInterval("retract", path, &args, fix)
|
||||
if err != nil {
|
||||
wrapError(err)
|
||||
}
|
||||
r.VersionInterval = vi
|
||||
}
|
||||
}
|
||||
|
||||
// isIndirect reports whether line has a "// indirect" comment,
|
||||
// meaning it is in go.mod only for its effect on indirect dependencies,
|
||||
// so that it can be dropped entirely once the effective version of the
|
||||
@ -491,13 +548,13 @@ func AutoQuote(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (VersionInterval, error) {
|
||||
func parseVersionInterval(verb string, path string, args *[]string, fix VersionFixer) (VersionInterval, error) {
|
||||
toks := *args
|
||||
if len(toks) == 0 || toks[0] == "(" {
|
||||
return VersionInterval{}, fmt.Errorf("expected '[' or version")
|
||||
}
|
||||
if toks[0] != "[" {
|
||||
v, err := parseVersion(verb, "", &toks[0], fix)
|
||||
v, err := parseVersion(verb, path, &toks[0], fix)
|
||||
if err != nil {
|
||||
return VersionInterval{}, err
|
||||
}
|
||||
@ -509,7 +566,7 @@ func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (Versio
|
||||
if len(toks) == 0 {
|
||||
return VersionInterval{}, fmt.Errorf("expected version after '['")
|
||||
}
|
||||
low, err := parseVersion(verb, "", &toks[0], fix)
|
||||
low, err := parseVersion(verb, path, &toks[0], fix)
|
||||
if err != nil {
|
||||
return VersionInterval{}, err
|
||||
}
|
||||
@ -523,7 +580,7 @@ func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (Versio
|
||||
if len(toks) == 0 {
|
||||
return VersionInterval{}, fmt.Errorf("expected version after ','")
|
||||
}
|
||||
high, err := parseVersion(verb, "", &toks[0], fix)
|
||||
high, err := parseVersion(verb, path, &toks[0], fix)
|
||||
if err != nil {
|
||||
return VersionInterval{}, err
|
||||
}
|
||||
@ -631,8 +688,7 @@ func parseVersion(verb string, path string, s *string, fix VersionFixer) (string
|
||||
}
|
||||
}
|
||||
if fix != nil {
|
||||
var err error
|
||||
t, err = fix(path, t)
|
||||
fixed, err := fix(path, t)
|
||||
if err != nil {
|
||||
if err, ok := err.(*module.ModuleError); ok {
|
||||
return "", &Error{
|
||||
@ -643,11 +699,10 @@ func parseVersion(verb string, path string, s *string, fix VersionFixer) (string
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if v := module.CanonicalVersion(t); v != "" {
|
||||
*s = v
|
||||
return *s, nil
|
||||
}
|
||||
t = fixed
|
||||
} else {
|
||||
cv := module.CanonicalVersion(t)
|
||||
if cv == "" {
|
||||
return "", &Error{
|
||||
Verb: verb,
|
||||
ModPath: path,
|
||||
@ -656,6 +711,11 @@ func parseVersion(verb string, path string, s *string, fix VersionFixer) (string
|
||||
Err: errors.New("must be of the form v1.2.3"),
|
||||
},
|
||||
}
|
||||
}
|
||||
t = cv
|
||||
}
|
||||
*s = t
|
||||
return *s, nil
|
||||
}
|
||||
|
||||
func modulePathMajor(path string) (string, error) {
|
||||
@ -835,11 +895,8 @@ func (f *File) DropRequire(path string) error {
|
||||
// AddExclude adds a exclude statement to the mod file. Errors if the provided
|
||||
// version is not a canonical version string
|
||||
func (f *File) AddExclude(path, vers string) error {
|
||||
if !isCanonicalVersion(vers) {
|
||||
return &module.InvalidVersionError{
|
||||
Version: vers,
|
||||
Err: errors.New("must be of the form v1.2.3"),
|
||||
}
|
||||
if err := checkCanonicalVersion(path, vers); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hint *Line
|
||||
@ -916,17 +973,15 @@ func (f *File) DropReplace(oldPath, oldVers string) error {
|
||||
// AddRetract adds a retract statement to the mod file. Errors if the provided
|
||||
// version interval does not consist of canonical version strings
|
||||
func (f *File) AddRetract(vi VersionInterval, rationale string) error {
|
||||
if !isCanonicalVersion(vi.High) {
|
||||
return &module.InvalidVersionError{
|
||||
Version: vi.High,
|
||||
Err: errors.New("must be of the form v1.2.3"),
|
||||
var path string
|
||||
if f.Module != nil {
|
||||
path = f.Module.Mod.Path
|
||||
}
|
||||
if err := checkCanonicalVersion(path, vi.High); err != nil {
|
||||
return err
|
||||
}
|
||||
if !isCanonicalVersion(vi.Low) {
|
||||
return &module.InvalidVersionError{
|
||||
Version: vi.Low,
|
||||
Err: errors.New("must be of the form v1.2.3"),
|
||||
}
|
||||
if err := checkCanonicalVersion(path, vi.Low); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := &Retract{
|
||||
@ -1086,8 +1141,40 @@ func lineRetractLess(li, lj *Line) bool {
|
||||
return semver.Compare(vii.High, vij.High) > 0
|
||||
}
|
||||
|
||||
// isCanonicalVersion tests if the provided version string represents a valid
|
||||
// canonical version.
|
||||
func isCanonicalVersion(vers string) bool {
|
||||
return vers != "" && semver.Canonical(vers) == vers
|
||||
// checkCanonicalVersion returns a non-nil error if vers is not a canonical
|
||||
// version string or does not match the major version of path.
|
||||
//
|
||||
// If path is non-empty, the error text suggests a format with a major version
|
||||
// corresponding to the path.
|
||||
func checkCanonicalVersion(path, vers string) error {
|
||||
_, pathMajor, pathMajorOk := module.SplitPathVersion(path)
|
||||
|
||||
if vers == "" || vers != module.CanonicalVersion(vers) {
|
||||
if pathMajor == "" {
|
||||
return &module.InvalidVersionError{
|
||||
Version: vers,
|
||||
Err: fmt.Errorf("must be of the form v1.2.3"),
|
||||
}
|
||||
}
|
||||
return &module.InvalidVersionError{
|
||||
Version: vers,
|
||||
Err: fmt.Errorf("must be of the form %s.2.3", module.PathMajorPrefix(pathMajor)),
|
||||
}
|
||||
}
|
||||
|
||||
if pathMajorOk {
|
||||
if err := module.CheckPathMajor(vers, pathMajor); err != nil {
|
||||
if pathMajor == "" {
|
||||
// In this context, the user probably wrote "v2.3.4" when they meant
|
||||
// "v2.3.4+incompatible". Suggest that instead of "v0 or v1".
|
||||
return &module.InvalidVersionError{
|
||||
Version: vers,
|
||||
Err: fmt.Errorf("should be %s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)),
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ func fileNameOK(r rune) bool {
|
||||
|
||||
// CheckPath checks that a module path is valid.
|
||||
// A valid module path is a valid import path, as checked by CheckImportPath,
|
||||
// with two additional constraints.
|
||||
// with three additional constraints.
|
||||
// First, the leading path element (up to the first slash, if any),
|
||||
// by convention a domain name, must contain only lower-case ASCII letters,
|
||||
// ASCII digits, dots (U+002E), and dashes (U+002D);
|
||||
@ -280,8 +280,9 @@ func fileNameOK(r rune) bool {
|
||||
// and must not contain any dots. For paths beginning with "gopkg.in/",
|
||||
// this second requirement is replaced by a requirement that the path
|
||||
// follow the gopkg.in server's conventions.
|
||||
// Third, no path element may begin with a dot.
|
||||
func CheckPath(path string) error {
|
||||
if err := checkPath(path, false); err != nil {
|
||||
if err := checkPath(path, modulePath); err != nil {
|
||||
return fmt.Errorf("malformed module path %q: %v", path, err)
|
||||
}
|
||||
i := strings.Index(path, "/")
|
||||
@ -315,7 +316,7 @@ func CheckPath(path string) error {
|
||||
//
|
||||
// A valid path element is a non-empty string made up of
|
||||
// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
|
||||
// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
|
||||
// It must not end with a dot (U+002E), nor contain two dots in a row.
|
||||
//
|
||||
// The element prefix up to the first dot must not be a reserved file name
|
||||
// on Windows, regardless of case (CON, com1, NuL, and so on). The element
|
||||
@ -326,19 +327,29 @@ func CheckPath(path string) error {
|
||||
// top-level package documentation for additional information about
|
||||
// subtleties of Unicode.
|
||||
func CheckImportPath(path string) error {
|
||||
if err := checkPath(path, false); err != nil {
|
||||
if err := checkPath(path, importPath); err != nil {
|
||||
return fmt.Errorf("malformed import path %q: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// pathKind indicates what kind of path we're checking. Module paths,
|
||||
// import paths, and file paths have different restrictions.
|
||||
type pathKind int
|
||||
|
||||
const (
|
||||
modulePath pathKind = iota
|
||||
importPath
|
||||
filePath
|
||||
)
|
||||
|
||||
// checkPath checks that a general path is valid.
|
||||
// It returns an error describing why but not mentioning path.
|
||||
// Because these checks apply to both module paths and import paths,
|
||||
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
||||
// fileName indicates whether the final element of the path is a file name
|
||||
// (as opposed to a directory name).
|
||||
func checkPath(path string, fileName bool) error {
|
||||
func checkPath(path string, kind pathKind) error {
|
||||
if !utf8.ValidString(path) {
|
||||
return fmt.Errorf("invalid UTF-8")
|
||||
}
|
||||
@ -357,35 +368,34 @@ func checkPath(path string, fileName bool) error {
|
||||
elemStart := 0
|
||||
for i, r := range path {
|
||||
if r == '/' {
|
||||
if err := checkElem(path[elemStart:i], fileName); err != nil {
|
||||
if err := checkElem(path[elemStart:i], kind); err != nil {
|
||||
return err
|
||||
}
|
||||
elemStart = i + 1
|
||||
}
|
||||
}
|
||||
if err := checkElem(path[elemStart:], fileName); err != nil {
|
||||
if err := checkElem(path[elemStart:], kind); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkElem checks whether an individual path element is valid.
|
||||
// fileName indicates whether the element is a file name (not a directory name).
|
||||
func checkElem(elem string, fileName bool) error {
|
||||
func checkElem(elem string, kind pathKind) error {
|
||||
if elem == "" {
|
||||
return fmt.Errorf("empty path element")
|
||||
}
|
||||
if strings.Count(elem, ".") == len(elem) {
|
||||
return fmt.Errorf("invalid path element %q", elem)
|
||||
}
|
||||
if elem[0] == '.' && !fileName {
|
||||
if elem[0] == '.' && kind == modulePath {
|
||||
return fmt.Errorf("leading dot in path element")
|
||||
}
|
||||
if elem[len(elem)-1] == '.' {
|
||||
return fmt.Errorf("trailing dot in path element")
|
||||
}
|
||||
charOK := pathOK
|
||||
if fileName {
|
||||
if kind == filePath {
|
||||
charOK = fileNameOK
|
||||
}
|
||||
for _, r := range elem {
|
||||
@ -406,7 +416,7 @@ func checkElem(elem string, fileName bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if fileName {
|
||||
if kind == filePath {
|
||||
// don't check for Windows short-names in file names. They're
|
||||
// only an issue for import paths.
|
||||
return nil
|
||||
@ -444,7 +454,7 @@ func checkElem(elem string, fileName bool) error {
|
||||
// top-level package documentation for additional information about
|
||||
// subtleties of Unicode.
|
||||
func CheckFilePath(path string) error {
|
||||
if err := checkPath(path, true); err != nil {
|
||||
if err := checkPath(path, filePath); err != nil {
|
||||
return fmt.Errorf("malformed file path %q: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
@ -647,7 +657,7 @@ func EscapePath(path string) (escaped string, err error) {
|
||||
// Versions are allowed to be in non-semver form but must be valid file names
|
||||
// and not contain exclamation marks.
|
||||
func EscapeVersion(v string) (escaped string, err error) {
|
||||
if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
|
||||
if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") {
|
||||
return "", &InvalidVersionError{
|
||||
Version: v,
|
||||
Err: fmt.Errorf("disallowed version string"),
|
||||
@ -706,7 +716,7 @@ func UnescapeVersion(escaped string) (v string, err error) {
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid escaped version %q", escaped)
|
||||
}
|
||||
if err := checkElem(v, true); err != nil {
|
||||
if err := checkElem(v, filePath); err != nil {
|
||||
return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
|
||||
}
|
||||
return v, nil
|
||||
|
@ -377,8 +377,10 @@ func tzsetOffset(s string) (offset int, rest string, ok bool) {
|
||||
neg = true
|
||||
}
|
||||
|
||||
// The tzdata code permits values up to 24 * 7 here,
|
||||
// although POSIX does not.
|
||||
var hours int
|
||||
hours, s, ok = tzsetNum(s, 0, 24)
|
||||
hours, s, ok = tzsetNum(s, 0, 24*7)
|
||||
if !ok {
|
||||
return 0, "", false
|
||||
}
|
||||
@ -487,7 +489,7 @@ func tzsetRule(s string) (rule, string, bool) {
|
||||
}
|
||||
|
||||
offset, s, ok := tzsetOffset(s[1:])
|
||||
if !ok || offset < 0 {
|
||||
if !ok {
|
||||
return rule{}, "", false
|
||||
}
|
||||
r.time = offset
|
||||
|
@ -189,22 +189,50 @@ func TestMalformedTZData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadLocationFromTZDataSlim(t *testing.T) {
|
||||
// A 2020b slim tzdata for Europe/Berlin
|
||||
tzData := "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n"
|
||||
var slimTests = []struct {
|
||||
zoneName string
|
||||
tzData string
|
||||
wantName string
|
||||
wantOffset int
|
||||
}{
|
||||
{
|
||||
// 2020b slim tzdata for Europe/Berlin.
|
||||
zoneName: "Europe/Berlin",
|
||||
tzData: "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n",
|
||||
wantName: "CET",
|
||||
wantOffset: 3600,
|
||||
},
|
||||
{
|
||||
// 2021a slim tzdata for America/Nuuk.
|
||||
zoneName: "America/Nuuk",
|
||||
tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\n",
|
||||
wantName: "-03",
|
||||
wantOffset: -10800,
|
||||
},
|
||||
{
|
||||
// 2021a slim tzdata for Asia/Gaza.
|
||||
zoneName: "Asia/Gaza",
|
||||
tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
|
||||
wantName: "EET",
|
||||
wantOffset: 7200,
|
||||
},
|
||||
}
|
||||
|
||||
reference, err := time.LoadLocationFromTZData("Europe/Berlin", []byte(tzData))
|
||||
func TestLoadLocationFromTZDataSlim(t *testing.T) {
|
||||
for _, test := range slimTests {
|
||||
reference, err := time.LoadLocationFromTZData(test.zoneName, []byte(test.tzData))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
|
||||
tzName, tzOffset := d.Zone()
|
||||
if want := "CET"; tzName != want {
|
||||
t.Errorf("Zone name == %s, want %s", tzName, want)
|
||||
if tzName != test.wantName {
|
||||
t.Errorf("Zone name == %s, want %s", tzName, test.wantName)
|
||||
}
|
||||
if tzOffset != test.wantOffset {
|
||||
t.Errorf("Zone offset == %d, want %d", tzOffset, test.wantOffset)
|
||||
}
|
||||
if want := 3600; tzOffset != want {
|
||||
t.Errorf("Zone offset == %d, want %d", tzOffset, want)
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +297,8 @@ func TestTzsetOffset(t *testing.T) {
|
||||
{"+08", 8 * 60 * 60, "", true},
|
||||
{"-01:02:03", -1*60*60 - 2*60 - 3, "", true},
|
||||
{"01", 1 * 60 * 60, "", true},
|
||||
{"100", 0, "", false},
|
||||
{"100", 100 * 60 * 60, "", true},
|
||||
{"1000", 0, "", false},
|
||||
{"8PDT", 8 * 60 * 60, "PDT", true},
|
||||
} {
|
||||
off, out, ok := time.TzsetOffset(test.in)
|
||||
@ -294,6 +323,7 @@ func TestTzsetRule(t *testing.T) {
|
||||
{"30/03:00:00", time.Rule{Kind: time.RuleDOY, Day: 30, Time: 3 * 60 * 60}, "", true},
|
||||
{"M4.5.6/03:00:00", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, Week: 5, Day: 6, Time: 3 * 60 * 60}, "", true},
|
||||
{"M4.5.7/03:00:00", time.Rule{}, "", false},
|
||||
{"M4.5.6/-04", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, Week: 5, Day: 6, Time: -4 * 60 * 60}, "", true},
|
||||
} {
|
||||
r, out, ok := time.TzsetRule(test.in)
|
||||
if r != test.r || out != test.out || ok != test.ok {
|
||||
|
@ -201,12 +201,11 @@ func TestMethod(t *testing.T) {
|
||||
// Exported symbol's method must be live.
|
||||
goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
|
||||
goCmd(t, "build", "-o", "method.exe", "./method/main.go")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "./method.exe")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
|
||||
}
|
||||
run(t, "./method.exe")
|
||||
}
|
||||
|
||||
func TestMethod2(t *testing.T) {
|
||||
goCmd(t, "build", "-buildmode=plugin", "-o", "method2.so", "./method2/plugin.go")
|
||||
goCmd(t, "build", "-o", "method2.exe", "./method2/main.go")
|
||||
run(t, "./method2.exe")
|
||||
}
|
||||
|
32
libgo/misc/cgo/testplugin/testdata/method2/main.go
vendored
Normal file
32
libgo/misc/cgo/testplugin/testdata/method2/main.go
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// A type can be passed to a plugin and converted to interface
|
||||
// there. So its methods need to be live.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"plugin"
|
||||
|
||||
"testplugin/method2/p"
|
||||
)
|
||||
|
||||
var t p.T
|
||||
|
||||
type I interface { M() }
|
||||
|
||||
func main() {
|
||||
pl, err := plugin.Open("method2.so")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f, err := pl.Lookup("F")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f.(func(p.T) interface{})(t).(I).M()
|
||||
}
|
9
libgo/misc/cgo/testplugin/testdata/method2/p/p.go
vendored
Normal file
9
libgo/misc/cgo/testplugin/testdata/method2/p/p.go
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
type T int
|
||||
|
||||
func (T) M() { println("M") }
|
11
libgo/misc/cgo/testplugin/testdata/method2/plugin.go
vendored
Normal file
11
libgo/misc/cgo/testplugin/testdata/method2/plugin.go
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import "testplugin/method2/p"
|
||||
|
||||
func main() {}
|
||||
|
||||
func F(t p.T) interface{} { return t }
|
Loading…
Reference in New Issue
Block a user