libgo: update to Go1.16 release
authorIan Lance Taylor <iant@golang.org>
Fri, 19 Feb 2021 02:54:38 +0000 (18:54 -0800)
committerIan Lance Taylor <iant@golang.org>
Fri, 19 Feb 2021 20:33:25 +0000 (12:33 -0800)
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/293793

39 files changed:
gcc/go/gofrontend/MERGE
libgo/MERGE
libgo/VERSION
libgo/go/archive/tar/strconv.go
libgo/go/archive/tar/strconv_test.go
libgo/go/cmd/go/alldocs.go
libgo/go/cmd/go/internal/help/helpdoc.go
libgo/go/cmd/go/internal/load/pkg.go
libgo/go/cmd/go/internal/modget/get.go
libgo/go/cmd/go/internal/modload/help.go
libgo/go/cmd/go/internal/vet/vetflag.go
libgo/go/cmd/go/testdata/script/build_trimpath.txt
libgo/go/cmd/go/testdata/script/help.txt
libgo/go/embed/embed.go
libgo/go/internal/poll/copy_file_range_linux.go
libgo/go/internal/poll/sendfile_bsd.go
libgo/go/internal/poll/sendfile_glibc.go
libgo/go/internal/poll/sendfile_solaris.go
libgo/go/io/fs/fs.go
libgo/go/io/fs/fs_test.go
libgo/go/io/fs/glob.go
libgo/go/io/fs/glob_test.go
libgo/go/math/big/nat.go
libgo/go/net/sendfile_test.go
libgo/go/os/file.go
libgo/go/os/os_test.go
libgo/go/os/readfrom_linux_test.go
libgo/go/runtime/histogram.go
libgo/go/runtime/metrics/doc.go
libgo/go/runtime/metrics/example_test.go
libgo/go/runtime/metrics/sample.go
libgo/go/runtime/metrics/value.go
libgo/go/runtime/stubs.go
libgo/go/testing/fstest/testfs.go
libgo/go/testing/fstest/testfs_test.go [new file with mode: 0644]
libgo/misc/cgo/testshared/shared_test.go
libgo/misc/cgo/testshared/testdata/issue44031/a/a.go [new file with mode: 0644]
libgo/misc/cgo/testshared/testdata/issue44031/b/b.go [new file with mode: 0644]
libgo/misc/cgo/testshared/testdata/issue44031/main/main.go [new file with mode: 0644]

index eed9ce01905a6e635be3c00b7215d47a9f040e64..217bdd55f1d50a6e35c90eab3550296c07a1b1e9 100644 (file)
@@ -1,4 +1,4 @@
-c406de0594782b1d6782a732a50f5b76387852dc
+78a840e4940159a66072237f6b002ab79f441b79
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index b2fc633f06cfb530b2ae3cc72a2276094158aa43..183b0245ee233b02959b97e8ca3f628a5e2186f6 100644 (file)
@@ -1,4 +1,4 @@
-3e06467282c6d5678a6273747658c04314e013ef
+f21be2fdc6f1becdbed1592ea0b245cdeedc5ac8
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
index a19294250b3652ca9af6a0e6c4b257982a4d6268..4befab24bc93533736e826ed74e0d9693aa7762a 100644 (file)
@@ -1 +1 @@
-go1.16rc1
+go1.16
index 6d0a40380828454bfe1563416a934f5482db0693..f0b61e6dba69a4fb393c8c92c694713c9defd4d6 100644 (file)
@@ -265,8 +265,27 @@ func parsePAXRecord(s string) (k, v, r string, err error) {
                return "", "", s, ErrHeader
        }
 
+       afterSpace := int64(sp + 1)
+       beforeLastNewLine := n - 1
+       // In some cases, "length" was perhaps padded/malformed, and
+       // trying to index past where the space supposedly is goes past
+       // the end of the actual record.
+       // For example:
+       //    "0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319"
+       //                                  ^     ^
+       //                                  |     |
+       //                                  |  afterSpace=35
+       //                                  |
+       //                          beforeLastNewLine=29
+       // yet indexOf(firstSpace) MUST BE before endOfRecord.
+       //
+       // See https://golang.org/issues/40196.
+       if afterSpace >= beforeLastNewLine {
+               return "", "", s, ErrHeader
+       }
+
        // Extract everything between the space and the final newline.
-       rec, nl, rem := s[sp+1:n-1], s[n-1:n], s[n:]
+       rec, nl, rem := s[afterSpace:beforeLastNewLine], s[beforeLastNewLine:n], s[n:]
        if nl != "\n" {
                return "", "", s, ErrHeader
        }
index dd3505a758af8d5d17ceae4ecd1c11652952f6b0..add65e272ae6d776eecc97dd163f3988cddf23ce 100644 (file)
@@ -368,6 +368,13 @@ func TestParsePAXRecord(t *testing.T) {
                {"16 longkeyname=hahaha\n", "16 longkeyname=hahaha\n", "", "", false},
                {"3 somelongkey=\n", "3 somelongkey=\n", "", "", false},
                {"50 tooshort=\n", "50 tooshort=\n", "", "", false},
+               {"0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319", "0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319", "mtime", "1432668921.098285006", false},
+               {"06 k=v\n", "06 k=v\n", "", "", false},
+               {"00006 k=v\n", "00006 k=v\n", "", "", false},
+               {"000006 k=v\n", "000006 k=v\n", "", "", false},
+               {"000000 k=v\n", "000000 k=v\n", "", "", false},
+               {"0 k=v\n", "0 k=v\n", "", "", false},
+               {"+0000005 x=\n", "+0000005 x=\n", "", "", false},
        }
 
        for _, v := range vectors {
index 49d390297cdc508135437283e4670e9824c86cd4..e7c63f0749d695c91d863b18f76184f420995df2 100644 (file)
 //             The directory where the go command will write
 //             temporary source files, packages, and binaries.
 //     GOVCS
-//       Lists version control commands that may be used with matching servers.
+//             Lists version control commands that may be used with matching servers.
 //             See 'go help vcs'.
 //
 // Environment variables for use with cgo:
 //
 // For a detailed reference on modules, see https://golang.org/ref/mod.
 //
+// By default, the go command may download modules from https://proxy.golang.org.
+// It may authenticate modules using the checksum database at
+// https://sum.golang.org. Both services are operated by the Go team at Google.
+// The privacy policies for these services are available at
+// https://proxy.golang.org/privacy and https://sum.golang.org/privacy,
+// respectively.
+//
+// The go command's download behavior may be configured using GOPROXY, GOSUMDB,
+// GOPRIVATE, and other environment variables. See 'go help environment'
+// and https://golang.org/ref/mod#private-module-privacy for more information.
+//
 //
 // Module authentication using go.sum
 //
 // legal reasons). Therefore, clients can still access public code served from
 // Bazaar, Fossil, or Subversion repositories by default, because those downloads
 // use the Go module mirror, which takes on the security risk of running the
-// version control commands, using a custom sandbox.
+// version control commands using a custom sandbox.
 //
 // The GOVCS variable can be used to change the allowed version control systems
 // for specific packages (identified by a module or import path).
-// The GOVCS variable applies both when using modules and when using GOPATH.
-// When using modules, the patterns match against the module path.
-// When using GOPATH, the patterns match against the import path
-// corresponding to the root of the version control repository.
+// The GOVCS variable applies when building package in both module-aware mode
+// and GOPATH mode. When using modules, the patterns match against the module path.
+// When using GOPATH, the patterns match against the import path corresponding to
+// the root of the version control repository.
 //
 // The general form of the GOVCS setting is a comma-separated list of
 // pattern:vcslist rules. The pattern is a glob pattern that must match
 // one or more leading elements of the module or import path. The vcslist
 // is a pipe-separated list of allowed version control commands, or "all"
-// to allow use of any known command, or "off" to allow nothing.
+// to allow use of any known command, or "off" to disallow all commands.
+// Note that if a module matches a pattern with vcslist "off", it may still be
+// downloaded if the origin server uses the "mod" scheme, which instructs the
+// go command to download the module using the GOPROXY protocol.
 // The earliest matching pattern in the list applies, even if later patterns
 // might also match.
 //
 //
 //     GOVCS=github.com:git,evil.com:off,*:git|hg
 //
-// With this setting, code with an module or import path beginning with
+// With this setting, code with a module or import path beginning with
 // github.com/ can only use git; paths on evil.com cannot use any version
 // control command, and all other paths (* matches everything) can use
 // only git or hg.
index e07ad0e1db10b102d4f494016e049f179f5a65a1..57cee4ff96c1acc42c01d69483bc630d86e8b750 100644 (file)
@@ -542,7 +542,7 @@ General-purpose environment variables:
                The directory where the go command will write
                temporary source files, packages, and binaries.
        GOVCS
-         Lists version control commands that may be used with matching servers.
+               Lists version control commands that may be used with matching servers.
                See 'go help vcs'.
 
 Environment variables for use with cgo:
index 8757d666fb234b4bb5af717a68eca7527e0404dd..e83f1d2cea9e8a4630a612d828c4c32874bcb4ce 100644 (file)
@@ -36,6 +36,8 @@ import (
        "cmd/go/internal/str"
        "cmd/go/internal/trace"
        "cmd/internal/sys"
+
+       "golang.org/x/mod/module"
 )
 
 var IgnoreImports bool // control whether we ignore imports in packages
@@ -2096,6 +2098,9 @@ func validEmbedPattern(pattern string) bool {
 // can't or won't be included in modules and therefore shouldn't be treated
 // as existing for embedding.
 func isBadEmbedName(name string) bool {
+       if err := module.CheckFilePath(name); err != nil {
+               return true
+       }
        switch name {
        // Empty string should be impossible but make it bad.
        case "":
index 574f3e194d168ed6c2cda6c9d2a64b2cd2fb98ed..dccacd3d1ee933c2f2796660e0d9a5748fbc3d73 100644 (file)
@@ -176,20 +176,23 @@ packages or when the mirror refuses to serve a public package (typically for
 legal reasons). Therefore, clients can still access public code served from
 Bazaar, Fossil, or Subversion repositories by default, because those downloads
 use the Go module mirror, which takes on the security risk of running the
-version control commands, using a custom sandbox.
+version control commands using a custom sandbox.
 
 The GOVCS variable can be used to change the allowed version control systems
 for specific packages (identified by a module or import path).
-The GOVCS variable applies both when using modules and when using GOPATH.
-When using modules, the patterns match against the module path.
-When using GOPATH, the patterns match against the import path
-corresponding to the root of the version control repository.
+The GOVCS variable applies when building package in both module-aware mode
+and GOPATH mode. When using modules, the patterns match against the module path.
+When using GOPATH, the patterns match against the import path corresponding to
+the root of the version control repository.
 
 The general form of the GOVCS setting is a comma-separated list of
 pattern:vcslist rules. The pattern is a glob pattern that must match
 one or more leading elements of the module or import path. The vcslist
 is a pipe-separated list of allowed version control commands, or "all"
-to allow use of any known command, or "off" to allow nothing.
+to allow use of any known command, or "off" to disallow all commands.
+Note that if a module matches a pattern with vcslist "off", it may still be
+downloaded if the origin server uses the "mod" scheme, which instructs the
+go command to download the module using the GOPROXY protocol.
 The earliest matching pattern in the list applies, even if later patterns
 might also match.
 
@@ -197,7 +200,7 @@ For example, consider:
 
        GOVCS=github.com:git,evil.com:off,*:git|hg
 
-With this setting, code with an module or import path beginning with
+With this setting, code with a module or import path beginning with
 github.com/ can only use git; paths on evil.com cannot use any version
 control command, and all other paths (* matches everything) can use
 only git or hg.
@@ -380,10 +383,9 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
                pkgs := load.PackagesAndErrors(ctx, pkgPatterns)
                load.CheckPackageErrors(pkgs)
                work.InstallPackages(ctx, pkgPatterns, pkgs)
-               // TODO(#40276): After Go 1.16, print a deprecation notice when building
-               // and installing main packages. 'go install pkg' or
-               // 'go install pkg@version' should be used instead.
-               // Give the specific argument to use if possible.
+               // TODO(#40276): After Go 1.16, print a deprecation notice when building and
+               // installing main packages. 'go install pkg' or 'go install pkg@version'
+               // should be used instead. Give the specific argument to use if possible.
        }
 
        if !modload.HasModRoot() {
@@ -1453,7 +1455,18 @@ func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns
                        }
                }
                for _, pkg := range pkgs {
-                       if _, _, err := modload.Lookup("", false, pkg); err != nil {
+                       if dir, _, err := modload.Lookup("", false, pkg); err != nil {
+                               if dir != "" && errors.Is(err, imports.ErrNoGo) {
+                                       // Since dir is non-empty, we must have located source files
+                                       // associated with either the package or its test — ErrNoGo must
+                                       // indicate that none of those source files happen to apply in this
+                                       // configuration. If we are actually building the package (no -d
+                                       // flag), the compiler will report the problem; otherwise, assume that
+                                       // the user is going to build or test it in some other configuration
+                                       // and suppress the error.
+                                       continue
+                               }
+
                                base.SetExitStatus(1)
                                if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) {
                                        for _, m := range ambiguousErr.Modules {
index 1cb58961bed43f6bffd61fbe6f65bea18ced9b7c..fd39ddd94ec62d6f21533a7ea7dff02c8eeb2ecb 100644 (file)
@@ -6,8 +6,6 @@ package modload
 
 import "cmd/go/internal/base"
 
-// TODO(rsc): The "module code layout" section needs to be written.
-
 var HelpModules = &base.Command{
        UsageLine: "modules",
        Short:     "modules, module versions, and more",
@@ -22,6 +20,17 @@ For a series of tutorials on modules, see
 https://golang.org/doc/tutorial/create-module.
 
 For a detailed reference on modules, see https://golang.org/ref/mod.
+
+By default, the go command may download modules from https://proxy.golang.org.
+It may authenticate modules using the checksum database at
+https://sum.golang.org. Both services are operated by the Go team at Google.
+The privacy policies for these services are available at
+https://proxy.golang.org/privacy and https://sum.golang.org/privacy,
+respectively.
+
+The go command's download behavior may be configured using GOPROXY, GOSUMDB,
+GOPRIVATE, and other environment variables. See 'go help environment'
+and https://golang.org/ref/mod#private-module-privacy for more information.
        `,
 }
 
index 5bf5cf44467f144f27df7a267203c9745e1645e5..b5b3c462ff2acced306e495a173b43be76fd579b 100644 (file)
@@ -184,7 +184,8 @@ func exitWithUsage() {
        if vetTool != "" {
                cmd = vetTool
        }
-       fmt.Fprintf(os.Stderr, "Run '%s -help' for the vet tool's flags.\n", cmd)
+       fmt.Fprintf(os.Stderr, "Run '%s help' for a full list of flags and analyzers.\n", cmd)
+       fmt.Fprintf(os.Stderr, "Run '%s -help' for an overview.\n", cmd)
 
        base.SetExitStatus(2)
        base.Exit()
index e1ea0a48b2acfec72a585b6d31cb05718dc9c42b..2c3bee8fdc7a925bb9bd9bdcee078a36b0ed9581 100644 (file)
@@ -121,6 +121,7 @@ package main
 import (
        "bytes"
        "fmt"
+       "io/ioutil"
        "log"
        "os"
        "os/exec"
@@ -130,7 +131,7 @@ import (
 
 func main() {
        exe := os.Args[1]
-       data, err := os.ReadFile(exe)
+       data, err := ioutil.ReadFile(exe)
        if err != nil {
                log.Fatal(err)
        }
index 9752ede2e372830eabca429fdbc1ae67fa16d0d9..26a0194be5603e9195356981ce83923de430fc94 100644 (file)
@@ -34,9 +34,10 @@ stderr 'Run ''go help mod'' for usage.'
 # Earlier versions of Go printed the same as 'go -h' here.
 # Also make sure we print the short help line.
 ! go vet -h
-stderr 'usage: go vet'
-stderr 'Run ''go help vet'' for details'
-stderr 'Run ''go tool vet -help'' for the vet tool''s flags'
+stderr 'usage: go vet .*'
+stderr 'Run ''go help vet'' for details.'
+stderr 'Run ''go tool vet help'' for a full list of flags and analyzers.'
+stderr 'Run ''go tool vet -help'' for an overview.'
 
 # Earlier versions of Go printed a large document here, instead of these two
 # lines.
index cc6855e6a5b0cc740a5893d12d045a761a061756..98da870ac6b00a8a224584fb4c734eb181184c46 100644 (file)
@@ -9,18 +9,28 @@
 // files read from the package directory or subdirectories at compile time.
 //
 // For example, here are three ways to embed a file named hello.txt
-// and then print its contents at run time:
+// and then print its contents at run time.
 //
-//     import "embed"
+// Embedding one file into a string:
+//
+//     import _ "embed"
 //
 //     //go:embed hello.txt
 //     var s string
 //     print(s)
 //
+// Embedding one file into a slice of bytes:
+//
+//     import _ "embed"
+//
 //     //go:embed hello.txt
 //     var b []byte
 //     print(string(b))
 //
+// Embedded one or more files into a file system:
+//
+//     import "embed"
+//
 //     //go:embed hello.txt
 //     var f embed.FS
 //     data, _ := f.ReadFile("hello.txt")
@@ -34,8 +44,8 @@
 // The directive must immediately precede a line containing the declaration of a single variable.
 // Only blank lines and ‘//’ line comments are permitted between the directive and the declaration.
 //
-// The variable must be of type string, []byte, or FS exactly. Named types or type aliases
-// derived from those types are not allowed.
+// The type of the variable must be a string type, or a slice of a byte type,
+// or FS (or an alias of FS).
 //
 // For example:
 //
 // The Go build system will recognize the directives and arrange for the declared variable
 // (in the example above, content) to be populated with the matching files from the file system.
 //
-// The //go:embed directive accepts multiple space-separated patterns for brevity,
-// but it can also be repeated, to avoid very long lines when there are many patterns.
-// The patterns are interpreted relative to the package directory containing the source file.
-// The path separator is a forward slash, even on Windows systems.
-// To allow for naming files with spaces in their names, patterns can be written
-// as Go double-quoted or back-quoted string literals.
+// The //go:embed directive accepts multiple space-separated patterns for
+// brevity, but it can also be repeated, to avoid very long lines when there are
+// many patterns. The patterns are interpreted relative to the package directory
+// containing the source file. The path separator is a forward slash, even on
+// Windows systems. Patterns may not contain ‘.’ or ‘..’ or empty path elements,
+// nor may they begin or end with a slash. To match everything in the current
+// directory, use ‘*’ instead of ‘.’. To allow for naming files with spaces in
+// their names, patterns can be written as Go double-quoted or back-quoted
+// string literals.
 //
 // If a pattern names a directory, all files in the subtree rooted at that directory are
 // embedded (recursively), except that files with names beginning with ‘.’ or ‘_’
 //
 // The //go:embed directive can be used with both exported and unexported variables,
 // depending on whether the package wants to make the data available to other packages.
-// Similarly, it can be used with both global and function-local variables,
-// depending on what is more convenient in context.
+// It can only be used with global variables at package scope,
+// not with local variables.
 //
 // Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links.
 // Matches for empty directories are ignored. After that, each pattern in a //go:embed line
 // must match at least one file or non-empty directory.
 //
-// Patterns must not contain ‘.’ or ‘..’ path elements nor begin with a leading slash.
-// To match everything in the current directory, use ‘*’ instead of ‘.’.
-//
 // If any patterns are invalid or have invalid matches, the build will fail.
 //
 // Strings and Bytes
index fc34aef4cba0e4320bba3e51f1be3677ab590870..01b242a4ea4e8d8fe147fbd9b3fc785d81796e13 100644 (file)
@@ -112,7 +112,15 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err
                        return 0, false, nil
                case nil:
                        if n == 0 {
-                               // src is at EOF, which means we are done.
+                               // If we did not read any bytes at all,
+                               // then this file may be in a file system
+                               // where copy_file_range silently fails.
+                               // https://lore.kernel.org/linux-fsdevel/20210126233840.GG4626@dread.disaster.area/T/#m05753578c7f7882f6e9ffe01f981bc223edef2b0
+                               if written == 0 {
+                                       return 0, false, nil
+                               }
+                               // Otherwise src is at EOF, which means
+                               // we are done.
                                return written, true, nil
                        }
                        remain -= n
index a24e41dcaa8742c8104e5071455e9e83cb92ee84..66005a9f5c952a68574a50d64cecab36b13728f1 100644 (file)
@@ -18,6 +18,10 @@ func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error) {
                return 0, err
        }
        defer dstFD.writeUnlock()
+       if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
+               return 0, err
+       }
+
        dst := int(dstFD.Sysfd)
        var written int64
        var err error
index 6652e3fedc104a99f1e4c782eb96025726962be3..d95e496a265cb117b330fe956149382a49b6e0f9 100644 (file)
@@ -18,6 +18,9 @@ func SendFile(dstFD *FD, src int, remain int64) (int64, error) {
                return 0, err
        }
        defer dstFD.writeUnlock()
+       if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
+               return 0, err
+       }
 
        dst := int(dstFD.Sysfd)
        var written int64
@@ -34,6 +37,9 @@ func SendFile(dstFD *FD, src int, remain int64) (int64, error) {
                } else if n == 0 && err1 == nil {
                        break
                }
+               if err1 == syscall.EINTR {
+                       continue
+               }
                if err1 == syscall.EAGAIN {
                        if err1 = dstFD.pd.waitWrite(dstFD.isFile); err1 == nil {
                                continue
index 762992e9eb398eac2b0ec7ec9eda78466a831ab4..748c85131e688da0c42eb4d8f8fd65195a587a77 100644 (file)
@@ -20,6 +20,9 @@ func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error) {
                return 0, err
        }
        defer dstFD.writeUnlock()
+       if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
+               return 0, err
+       }
 
        dst := int(dstFD.Sysfd)
        var written int64
index b691a860498a2136cf97a56905739555bf4946f5..3d2e2ee2ac953020780614885c0279705f56dbbe 100644 (file)
@@ -10,6 +10,7 @@ package fs
 import (
        "internal/oserror"
        "time"
+       "unicode/utf8"
 )
 
 // An FS provides access to a hierarchical file system.
@@ -32,14 +33,22 @@ type FS interface {
 
 // ValidPath reports whether the given path name
 // is valid for use in a call to Open.
-// Path names passed to open are unrooted, slash-separated
-// sequences of path elements, like “x/y/z”.
-// Path names must not contain a “.” or “..” or empty element,
+//
+// Path names passed to open are UTF-8-encoded,
+// unrooted, slash-separated sequences of path elements, like “x/y/z”.
+// Path names must not contain an element that is “.” or “..” or the empty string,
 // except for the special case that the root directory is named “.”.
+// Paths must not start or end with a slash: “/x” and “x/” are invalid.
 //
-// Paths are slash-separated on all systems, even Windows.
-// Backslashes must not appear in path names.
+// Note that paths are slash-separated on all systems, even Windows.
+// Paths containing other characters such as backslash and colon
+// are accepted as valid, but those characters must never be
+// interpreted by an FS implementation as path element separators.
 func ValidPath(name string) bool {
+       if !utf8.ValidString(name) {
+               return false
+       }
+
        if name == "." {
                // special case
                return true
@@ -49,9 +58,6 @@ func ValidPath(name string) bool {
        for {
                i := 0
                for i < len(name) && name[i] != '/' {
-                       if name[i] == '\\' {
-                               return false
-                       }
                        i++
                }
                elem := name[:i]
index 8d395fc0db1d248ca70706b81a88edb590eec019..aae1a7606f45a6f16c36f2e7c58a5925c153c443 100644 (file)
@@ -33,9 +33,10 @@ var isValidPathTests = []struct {
        {"x/..", false},
        {"x/../y", false},
        {"x//y", false},
-       {`x\`, false},
-       {`x\y`, false},
-       {`\x`, false},
+       {`x\`, true},
+       {`x\y`, true},
+       {`x:y`, true},
+       {`\x`, true},
 }
 
 func TestValidPath(t *testing.T) {
index 549f217542967500bf6f8a96599a234da49bb13a..45d9cb61b9632af83bf9834ef99d47e6133b193b 100644 (file)
@@ -6,7 +6,6 @@ package fs
 
 import (
        "path"
-       "runtime"
 )
 
 // A GlobFS is a file system with a Glob method.
@@ -111,8 +110,8 @@ func glob(fs FS, dir, pattern string, matches []string) (m []string, e error) {
 // recognized by path.Match.
 func hasMeta(path string) bool {
        for i := 0; i < len(path); i++ {
-               c := path[i]
-               if c == '*' || c == '?' || c == '[' || runtime.GOOS == "windows" && c == '\\' {
+               switch path[i] {
+               case '*', '?', '[', '\\':
                        return true
                }
        }
index 440ebd6bf4bd93bf9a2df3de2b001c1e1f20840f..bcd2e1bfae958c9b05d821f834ffad12a56df5b2 100644 (file)
@@ -17,6 +17,7 @@ var globTests = []struct {
 }{
        {os.DirFS("."), "glob.go", "glob.go"},
        {os.DirFS("."), "gl?b.go", "glob.go"},
+       {os.DirFS("."), `gl\ob.go`, "glob.go"},
        {os.DirFS("."), "*", "glob.go"},
        // This test fails on gofrontend because the directory structure
        // is different.
@@ -34,7 +35,7 @@ func TestGlob(t *testing.T) {
                        t.Errorf("Glob(%#q) = %#v want %v", tt.pattern, matches, tt.result)
                }
        }
-       for _, pattern := range []string{"no_match", "../*/no_match"} {
+       for _, pattern := range []string{"no_match", "../*/no_match", `\*`} {
                matches, err := Glob(os.DirFS("."), pattern)
                if err != nil {
                        t.Errorf("Glob error for %q: %s", pattern, err)
index 068176e1c1a18c59a8a8bb0a0a13f644a140e4cd..bbd6c8850b604b365011144e9ab8e6744ee27354 100644 (file)
@@ -881,7 +881,7 @@ func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) {
                // then floor(u1/v1) >= floor(u/v)
                //
                // Moreover, the difference is at most 2 if len(v1) >= len(u/v)
-               // We choose s = B-1 since len(v)-B >= B+1 >= len(u/v)
+               // We choose s = B-1 since len(v)-s >= B+1 >= len(u/v)
                s := (B - 1)
                // Except for the first step, the top bits are always
                // a division remainder, so the quotient length is <= n.
index 657a36599f943e9f6bdf09f9c28cea0883d1c203..d6057fd83912872791a2284f8f5d026b1a17fb81 100644 (file)
@@ -10,8 +10,10 @@ import (
        "bytes"
        "crypto/sha256"
        "encoding/hex"
+       "errors"
        "fmt"
        "io"
+       "io/ioutil"
        "os"
        "runtime"
        "sync"
@@ -313,3 +315,66 @@ func TestSendfilePipe(t *testing.T) {
 
        wg.Wait()
 }
+
+// Issue 43822: tests that returns EOF when conn write timeout.
+func TestSendfileOnWriteTimeoutExceeded(t *testing.T) {
+       ln, err := newLocalListener("tcp")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer ln.Close()
+
+       errc := make(chan error, 1)
+       go func(ln Listener) (retErr error) {
+               defer func() {
+                       errc <- retErr
+                       close(errc)
+               }()
+
+               conn, err := ln.Accept()
+               if err != nil {
+                       return err
+               }
+               defer conn.Close()
+
+               // Set the write deadline in the past(1h ago). It makes
+               // sure that it is always write timeout.
+               if err := conn.SetWriteDeadline(time.Now().Add(-1 * time.Hour)); err != nil {
+                       return err
+               }
+
+               f, err := os.Open(newton)
+               if err != nil {
+                       return err
+               }
+               defer f.Close()
+
+               _, err = io.Copy(conn, f)
+               if errors.Is(err, os.ErrDeadlineExceeded) {
+                       return nil
+               }
+
+               if err == nil {
+                       err = fmt.Errorf("expected ErrDeadlineExceeded, but got nil")
+               }
+               return err
+       }(ln)
+
+       conn, err := Dial("tcp", ln.Addr().String())
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer conn.Close()
+
+       n, err := io.Copy(ioutil.Discard, conn)
+       if err != nil {
+               t.Fatalf("expected nil error, but got %v", err)
+       }
+       if n != 0 {
+               t.Fatalf("expected receive zero, but got %d byte(s)", n)
+       }
+
+       if err := <-errc; err != nil {
+               t.Fatal(err)
+       }
+}
index 416bc0efa62bfc1d62fc9469d92d90b93abec920..52dd94339b8ffbed5ceaffaec3edd002c19ca36d 100644 (file)
@@ -620,10 +620,21 @@ func DirFS(dir string) fs.FS {
        return dirFS(dir)
 }
 
+func containsAny(s, chars string) bool {
+       for i := 0; i < len(s); i++ {
+               for j := 0; j < len(chars); j++ {
+                       if s[i] == chars[j] {
+                               return true
+                       }
+               }
+       }
+       return false
+}
+
 type dirFS string
 
 func (dir dirFS) Open(name string) (fs.File, error) {
-       if !fs.ValidPath(name) {
+       if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
                return nil, &PathError{Op: "open", Path: name, Err: ErrInvalid}
        }
        f, err := Open(string(dir) + "/" + name)
index 40ba05697b679efb42f0d62c2cd0bbce2e06048a..734c655e6f7df13fdd34902431229d8215194c85 100644 (file)
@@ -2721,6 +2721,40 @@ func TestDirFS(t *testing.T) {
        if err := fstest.TestFS(DirFS("./testdata/dirfs"), "a", "b", "dir/x"); err != nil {
                t.Fatal(err)
        }
+
+       // Test that Open does not accept backslash as separator.
+       d := DirFS(".")
+       _, err := d.Open(`testdata\dirfs`)
+       if err == nil {
+               t.Fatalf(`Open testdata\dirfs succeeded`)
+       }
+}
+
+func TestDirFSPathsValid(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skipf("skipping on Windows")
+       }
+
+       d := t.TempDir()
+       if err := os.WriteFile(filepath.Join(d, "control.txt"), []byte(string("Hello, world!")), 0644); err != nil {
+               t.Fatal(err)
+       }
+       if err := os.WriteFile(filepath.Join(d, `e:xperi\ment.txt`), []byte(string("Hello, colon and backslash!")), 0644); err != nil {
+               t.Fatal(err)
+       }
+
+       fsys := os.DirFS(d)
+       err := fs.WalkDir(fsys, ".", func(path string, e fs.DirEntry, err error) error {
+               if fs.ValidPath(e.Name()) {
+                       t.Logf("%q ok", e.Name())
+               } else {
+                       t.Errorf("%q INVALID", e.Name())
+               }
+               return nil
+       })
+       if err != nil {
+               t.Fatal(err)
+       }
 }
 
 func TestReadFileProc(t *testing.T) {
index 37047175e6fde50a8aec15a723e5e42a2c712412..1d145dadb0870dea710871a360d68125d37cd5c7 100644 (file)
@@ -361,3 +361,35 @@ func (h *copyFileRangeHook) install() {
 func (h *copyFileRangeHook) uninstall() {
        *PollCopyFileRangeP = h.original
 }
+
+// On some kernels copy_file_range fails on files in /proc.
+func TestProcCopy(t *testing.T) {
+       const cmdlineFile = "/proc/self/cmdline"
+       cmdline, err := os.ReadFile(cmdlineFile)
+       if err != nil {
+               t.Skipf("can't read /proc file: %v", err)
+       }
+       in, err := os.Open(cmdlineFile)
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer in.Close()
+       outFile := filepath.Join(t.TempDir(), "cmdline")
+       out, err := os.Create(outFile)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if _, err := io.Copy(out, in); err != nil {
+               t.Fatal(err)
+       }
+       if err := out.Close(); err != nil {
+               t.Fatal(err)
+       }
+       copy, err := os.ReadFile(outFile)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if !bytes.Equal(cmdline, copy) {
+               t.Errorf("copy of %q got %q want %q\n", cmdlineFile, copy, cmdline)
+       }
+}
index 42baa6c5e2c0df3765e21e307bfdc4c1c808a92d..da4910d341cbcf861059f292eb4576a8e762e75a 100644 (file)
@@ -26,7 +26,7 @@ const (
        // The number of super-buckets (timeHistNumSuperBuckets), on the
        // other hand, defines the range. To reserve room for sub-buckets,
        // bit timeHistSubBucketBits is the first bit considered for
-       // super-buckets, so super-bucket indicies are adjusted accordingly.
+       // super-buckets, so super-bucket indices are adjusted accordingly.
        //
        // As an example, consider 45 super-buckets with 16 sub-buckets.
        //
index 021a0bddcaf3527b85a60a6e35bd807ad33f6c5e..7f790afc12eeabcdda78f0d01a0d83003155d18a 100644 (file)
@@ -16,13 +16,12 @@ Interface
 Metrics are designated by a string key, rather than, for example, a field name in
 a struct. The full list of supported metrics is always available in the slice of
 Descriptions returned by All. Each Description also includes useful information
-about the metric, such as how to display it (e.g. gauge vs. counter) and how difficult
-or disruptive it is to obtain it (e.g. do you need to stop the world?).
+about the metric.
 
 Thus, users of this API are encouraged to sample supported metrics defined by the
 slice returned by All to remain compatible across Go versions. Of course, situations
 arise where reading specific metrics is critical. For these cases, users are
-encouranged to use build tags, and although metrics may be deprecated and removed,
+encouraged to use build tags, and although metrics may be deprecated and removed,
 users should consider this to be an exceptional and rare event, coinciding with a
 very large change in a particular Go implementation.
 
index cade0c38bfde62c046d3e7c9332cff9163b4c23b..624d9d8a6bd1ec9d09c00172866b741efbd7470f 100644 (file)
@@ -88,7 +88,7 @@ func medianBucket(h *metrics.Float64Histogram) float64 {
        total = 0
        for i, count := range h.Counts {
                total += count
-               if total > thresh {
+               if total >= thresh {
                        return h.Buckets[i]
                }
        }
index 35534dd70da50f6cf05cc21845f24e781e8dd1ad..4cf8cdf79942820e6f0acf6b20adc71144fcd95a 100644 (file)
@@ -14,7 +14,7 @@ type Sample struct {
        // Name is the name of the metric sampled.
        //
        // It must correspond to a name in one of the metric descriptions
-       // returned by Descriptions.
+       // returned by All.
        Name string
 
        // Value is the value of the metric sample.
@@ -32,9 +32,9 @@ func runtime_readMetrics(unsafe.Pointer, int, int)
 //
 // Note that re-use has some caveats. Notably, Values should not be read or
 // manipulated while a Read with that value is outstanding; that is a data race.
-// This property includes pointer-typed Values (e.g. Float64Histogram) whose
-// underlying storage will be reused by Read when possible. To safely use such
-// values in a concurrent setting, all data must be deep-copied.
+// This property includes pointer-typed Values (for example, Float64Histogram)
+// whose underlying storage will be reused by Read when possible. To safely use
+// such values in a concurrent setting, all data must be deep-copied.
 //
 // It is safe to execute multiple Read calls concurrently, but their arguments
 // must share no underlying memory. When in doubt, create a new []Sample from
index 61e8a192a30d424b6cf57ddd58e73b769f073c2e..ed9a33d87cc64e126f68f165e20411aa7cd7a813 100644 (file)
@@ -33,7 +33,7 @@ type Value struct {
        pointer unsafe.Pointer // contains non-scalar values.
 }
 
-// Kind returns the tag representing the kind of value this is.
+// Kind returns the tag representing the kind of value this is.
 func (v Value) Kind() ValueKind {
        return v.kind
 }
index b0c5b38e56ad1f97e7350054892ede8af763987d..6d20c38433085ae7a3966ed9ef336f446cfc3424 100644 (file)
@@ -89,7 +89,15 @@ func badsystemstack() {
 // *ptr is uninitialized memory (e.g., memory that's being reused
 // for a new allocation) and hence contains only "junk".
 //
+// memclrNoHeapPointers ensures that if ptr is pointer-aligned, and n
+// is a multiple of the pointer size, then any pointer-aligned,
+// pointer-sized portion is cleared atomically. Despite the function
+// name, this is necessary because this function is the underlying
+// implementation of typedmemclr and memclrHasPointers. See the doc of
+// memmove for more details.
+//
 // The (CPU-specific) implementations of this function are in memclr_*.s.
+//
 //go:noescape
 func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
 
index a7f8007333e310eef526c61e667b789b2f125301..8fc8acaaf3bf1bb88fda7138002f5678a8266178 100644 (file)
@@ -403,9 +403,10 @@ func (t *fsTester) checkStat(path string, entry fs.DirEntry) {
                return
        }
        fentry := formatEntry(entry)
-       finfo := formatInfoEntry(info)
-       if fentry != finfo {
-               t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, finfo)
+       fientry := formatInfoEntry(info)
+       // Note: mismatch here is OK for symlink, because Open dereferences symlink.
+       if fentry != fientry && entry.Type()&fs.ModeSymlink == 0 {
+               t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, fientry)
        }
 
        einfo, err := entry.Info()
@@ -413,12 +414,22 @@ func (t *fsTester) checkStat(path string, entry fs.DirEntry) {
                t.errorf("%s: entry.Info: %v", path, err)
                return
        }
-       fentry = formatInfo(einfo)
-       finfo = formatInfo(info)
-       if fentry != finfo {
-               t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, fentry, finfo)
+       finfo := formatInfo(info)
+       if entry.Type()&fs.ModeSymlink != 0 {
+               // For symlink, just check that entry.Info matches entry on common fields.
+               // Open deferences symlink, so info itself may differ.
+               feentry := formatInfoEntry(einfo)
+               if fentry != feentry {
+                       t.errorf("%s: mismatch\n\tentry = %s\n\tentry.Info() = %s\n", path, fentry, feentry)
+               }
+       } else {
+               feinfo := formatInfo(einfo)
+               if feinfo != finfo {
+                       t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, feinfo, finfo)
+               }
        }
 
+       // Stat should be the same as Open+Stat, even for symlinks.
        info2, err := fs.Stat(t.fsys, path)
        if err != nil {
                t.errorf("%s: fs.Stat: %v", path, err)
diff --git a/libgo/go/testing/fstest/testfs_test.go b/libgo/go/testing/fstest/testfs_test.go
new file mode 100644 (file)
index 0000000..5b8813c
--- /dev/null
@@ -0,0 +1,31 @@
+// 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 fstest
+
+import (
+       "internal/testenv"
+       "os"
+       "path/filepath"
+       "testing"
+)
+
+func TestSymlink(t *testing.T) {
+       testenv.MustHaveSymlink(t)
+
+       tmp := t.TempDir()
+       tmpfs := os.DirFS(tmp)
+
+       if err := os.WriteFile(filepath.Join(tmp, "hello"), []byte("hello, world\n"), 0644); err != nil {
+               t.Fatal(err)
+       }
+
+       if err := os.Symlink(filepath.Join(tmp, "hello"), filepath.Join(tmp, "hello.link")); err != nil {
+               t.Fatal(err)
+       }
+
+       if err := TestFS(tmpfs, "hello", "hello.link"); err != nil {
+               t.Fatal(err)
+       }
+}
index 5e0893784b69d74cca9350719c313748121c2230..f52391c6f6c6ab1750fce523ad87606f25a5c708 100644 (file)
@@ -1063,3 +1063,11 @@ func TestGCData(t *testing.T) {
        goCmd(t, "build", "-linkshared", "./gcdata/main")
        runWithEnv(t, "running gcdata/main", []string{"GODEBUG=clobberfree=1"}, "./main")
 }
+
+// Test that we don't decode type symbols from shared libraries (which has no data,
+// causing panic). See issue 44031.
+func TestIssue44031(t *testing.T) {
+       goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/a")
+       goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/b")
+       goCmd(t, "run", "-linkshared", "./issue44031/main")
+}
diff --git a/libgo/misc/cgo/testshared/testdata/issue44031/a/a.go b/libgo/misc/cgo/testshared/testdata/issue44031/a/a.go
new file mode 100644 (file)
index 0000000..48827e6
--- /dev/null
@@ -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 a
+
+type ATypeWithALoooooongName interface { // a long name, so the type descriptor symbol name is mangled
+       M()
+}
diff --git a/libgo/misc/cgo/testshared/testdata/issue44031/b/b.go b/libgo/misc/cgo/testshared/testdata/issue44031/b/b.go
new file mode 100644 (file)
index 0000000..ad3ebec
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 b
+
+import "testshared/issue44031/a"
+
+type T int
+
+func (T) M() {}
+
+var i = a.ATypeWithALoooooongName(T(0))
+
+func F() {
+       i.M()
+}
diff --git a/libgo/misc/cgo/testshared/testdata/issue44031/main/main.go b/libgo/misc/cgo/testshared/testdata/issue44031/main/main.go
new file mode 100644 (file)
index 0000000..47f2e3a
--- /dev/null
@@ -0,0 +1,20 @@
+// 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 "testshared/issue44031/b"
+
+type t int
+
+func (t) m() {}
+
+type i interface{ m() } // test that unexported method is correctly marked
+
+var v interface{} = t(0)
+
+func main() {
+       b.F()
+       v.(i).m()
+}