libgo: update to Go1.16 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/293793
This commit is contained in:
parent
af02782629
commit
13e6fadd96
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1 +1 @@
|
|||
go1.16rc1
|
||||
go1.16
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1808,7 +1808,7 @@
|
|||
// 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:
|
||||
|
@ -2410,6 +2410,17 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -2868,20 +2879,23 @@
|
|||
// 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.
|
||||
//
|
||||
|
@ -2889,7 +2903,7 @@
|
|||
//
|
||||
// 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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 "":
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
`,
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
//
|
||||
|
@ -51,12 +61,15 @@
|
|||
// 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 ‘_’
|
||||
|
@ -70,16 +83,13 @@
|
|||
//
|
||||
// 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
// except for the special case that the root directory is named “.”.
|
||||
//
|
||||
// Paths are slash-separated on all systems, even Windows.
|
||||
// Backslashes must not appear in path names.
|
||||
// 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.
|
||||
//
|
||||
// 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]
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -33,7 +33,7 @@ type Value struct {
|
|||
pointer unsafe.Pointer // contains non-scalar values.
|
||||
}
|
||||
|
||||
// Kind returns the a 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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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()
|
||||
}
|
Loading…
Reference in New Issue