Update to go1.24.0

This commit is contained in:
Vorapol Rinsatitnon
2025-02-14 12:42:07 +07:00
parent 25e497e367
commit bf266cebe6
3169 changed files with 236789 additions and 60275 deletions

View File

@@ -15,6 +15,7 @@ import (
"fmt"
"internal/godebug"
"io/fs"
"maps"
"math"
"path"
"reflect"
@@ -696,24 +697,14 @@ func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) {
h.Gname = sys.Gname
h.AccessTime = sys.AccessTime
h.ChangeTime = sys.ChangeTime
if sys.Xattrs != nil {
h.Xattrs = make(map[string]string)
for k, v := range sys.Xattrs {
h.Xattrs[k] = v
}
}
h.Xattrs = maps.Clone(sys.Xattrs)
if sys.Typeflag == TypeLink {
// hard link
h.Typeflag = TypeLink
h.Size = 0
h.Linkname = sys.Linkname
}
if sys.PAXRecords != nil {
h.PAXRecords = make(map[string]string)
for k, v := range sys.PAXRecords {
h.PAXRecords[k] = v
}
}
h.PAXRecords = maps.Clone(sys.PAXRecords)
}
var doNameLookups = true
if iface, ok := fi.(FileInfoNames); ok {

View File

@@ -7,14 +7,16 @@ package tar
import (
"bytes"
"compress/bzip2"
"crypto/md5"
"errors"
"fmt"
"hash/crc32"
"io"
"maps"
"math"
"os"
"path"
"reflect"
"slices"
"strconv"
"strings"
"testing"
@@ -25,7 +27,7 @@ func TestReader(t *testing.T) {
vectors := []struct {
file string // Test input file
headers []*Header // Expected output headers
chksums []string // MD5 checksum of files, leave as nil if not checked
chksums []string // CRC32 checksum of files, leave as nil if not checked
err error // Expected error to occur
}{{
file: "testdata/gnu.tar",
@@ -53,8 +55,8 @@ func TestReader(t *testing.T) {
Format: FormatGNU,
}},
chksums: []string{
"e38b27eaccb4391bdec553a7f3ae6b2f",
"c65bd2e50a56a2138bf1716f2fd56fe9",
"6cbd88fc",
"ddac04b3",
},
}, {
file: "testdata/sparse-formats.tar",
@@ -147,11 +149,11 @@ func TestReader(t *testing.T) {
Format: FormatGNU,
}},
chksums: []string{
"6f53234398c2449fe67c1812d993012f",
"6f53234398c2449fe67c1812d993012f",
"6f53234398c2449fe67c1812d993012f",
"6f53234398c2449fe67c1812d993012f",
"b0061974914468de549a2af8ced10316",
"5375e1d2",
"5375e1d2",
"5375e1d2",
"5375e1d2",
"8eb179ba",
},
}, {
file: "testdata/star.tar",
@@ -268,7 +270,7 @@ func TestReader(t *testing.T) {
Format: FormatPAX,
}},
chksums: []string{
"0afb597b283fe61b5d4879669a350556",
"5fd7e86a",
},
}, {
file: "testdata/pax-records.tar",
@@ -655,7 +657,7 @@ func TestReader(t *testing.T) {
if v.chksums == nil {
continue
}
h := md5.New()
h := crc32.NewIEEE()
_, err = io.CopyBuffer(h, tr, rdbuf) // Effectively an incremental read
if err != nil {
break
@@ -1017,7 +1019,7 @@ func TestParsePAX(t *testing.T) {
for i, v := range vectors {
r := strings.NewReader(v.in)
got, err := parsePAX(r)
if !reflect.DeepEqual(got, v.want) && !(len(got) == 0 && len(v.want) == 0) {
if !maps.Equal(got, v.want) && !(len(got) == 0 && len(v.want) == 0) {
t.Errorf("test %d, parsePAX():\ngot %v\nwant %v", i, got, v.want)
}
if ok := err == nil; ok != v.ok {
@@ -1134,7 +1136,7 @@ func TestReadOldGNUSparseMap(t *testing.T) {
v.input = v.input[copy(blk[:], v.input):]
tr := Reader{r: bytes.NewReader(v.input)}
got, err := tr.readOldGNUSparseMap(&hdr, &blk)
if !equalSparseEntries(got, v.wantMap) {
if !slices.Equal(got, v.wantMap) {
t.Errorf("test %d, readOldGNUSparseMap(): got %v, want %v", i, got, v.wantMap)
}
if err != v.wantErr {
@@ -1325,7 +1327,7 @@ func TestReadGNUSparsePAXHeaders(t *testing.T) {
r := strings.NewReader(v.inputData + "#") // Add canary byte
tr := Reader{curr: &regFileReader{r, int64(r.Len())}}
got, err := tr.readGNUSparsePAXHeaders(&hdr)
if !equalSparseEntries(got, v.wantMap) {
if !slices.Equal(got, v.wantMap) {
t.Errorf("test %d, readGNUSparsePAXHeaders(): got %v, want %v", i, got, v.wantMap)
}
if err != v.wantErr {

View File

@@ -11,11 +11,13 @@ import (
"internal/testenv"
"io"
"io/fs"
"maps"
"math"
"os"
"path"
"path/filepath"
"reflect"
"slices"
"strings"
"testing"
"time"
@@ -98,10 +100,6 @@ func (f *testFile) Seek(pos int64, whence int) (int64, error) {
return f.pos, nil
}
func equalSparseEntries(x, y []sparseEntry) bool {
return (len(x) == 0 && len(y) == 0) || reflect.DeepEqual(x, y)
}
func TestSparseEntries(t *testing.T) {
vectors := []struct {
in []sparseEntry
@@ -198,11 +196,11 @@ func TestSparseEntries(t *testing.T) {
continue
}
gotAligned := alignSparseEntries(append([]sparseEntry{}, v.in...), v.size)
if !equalSparseEntries(gotAligned, v.wantAligned) {
if !slices.Equal(gotAligned, v.wantAligned) {
t.Errorf("test %d, alignSparseEntries():\ngot %v\nwant %v", i, gotAligned, v.wantAligned)
}
gotInverted := invertSparseEntries(append([]sparseEntry{}, v.in...), v.size)
if !equalSparseEntries(gotInverted, v.wantInverted) {
if !slices.Equal(gotInverted, v.wantInverted) {
t.Errorf("test %d, inverseSparseEntries():\ngot %v\nwant %v", i, gotInverted, v.wantInverted)
}
}
@@ -744,7 +742,7 @@ func TestHeaderAllowedFormats(t *testing.T) {
if formats != v.formats {
t.Errorf("test %d, allowedFormats(): got %v, want %v", i, formats, v.formats)
}
if formats&FormatPAX > 0 && !reflect.DeepEqual(paxHdrs, v.paxHdrs) && !(len(paxHdrs) == 0 && len(v.paxHdrs) == 0) {
if formats&FormatPAX > 0 && !maps.Equal(paxHdrs, v.paxHdrs) && !(len(paxHdrs) == 0 && len(v.paxHdrs) == 0) {
t.Errorf("test %d, allowedFormats():\ngot %v\nwant %s", i, paxHdrs, v.paxHdrs)
}
if (formats != FormatUnknown) && (err != nil) {

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"io/fs"
"maps"
"path"
"slices"
"strings"
@@ -169,16 +170,10 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
// Write PAX records to the output.
isGlobal := hdr.Typeflag == TypeXGlobalHeader
if len(paxHdrs) > 0 || isGlobal {
// Sort keys for deterministic ordering.
var keys []string
for k := range paxHdrs {
keys = append(keys, k)
}
slices.Sort(keys)
// Write each record to a buffer.
var buf strings.Builder
for _, k := range keys {
// Sort keys for deterministic ordering.
for _, k := range slices.Sorted(maps.Keys(paxHdrs)) {
rec, err := formatPAXRecord(k, paxHdrs[k])
if err != nil {
return err
@@ -413,7 +408,7 @@ func (tw *Writer) AddFS(fsys fs.FS) error {
if err != nil {
return err
}
if d.IsDir() {
if name == "." {
return nil
}
info, err := d.Info()
@@ -421,7 +416,7 @@ func (tw *Writer) AddFS(fsys fs.FS) error {
return err
}
// TODO(#49580): Handle symlinks when fs.ReadLinkFS is available.
if !info.Mode().IsRegular() {
if !d.IsDir() && !info.Mode().IsRegular() {
return errors.New("tar: cannot add non-regular file")
}
h, err := FileInfoHeader(info, "")
@@ -429,9 +424,15 @@ func (tw *Writer) AddFS(fsys fs.FS) error {
return err
}
h.Name = name
if d.IsDir() {
h.Name += "/"
}
if err := tw.WriteHeader(h); err != nil {
return err
}
if d.IsDir() {
return nil
}
f, err := fsys.Open(name)
if err != nil {
return err
@@ -668,6 +669,7 @@ func (sw *sparseFileWriter) ReadFrom(r io.Reader) (n int64, err error) {
func (sw sparseFileWriter) logicalRemaining() int64 {
return sw.sp[len(sw.sp)-1].endOffset() - sw.pos
}
func (sw sparseFileWriter) physicalRemaining() int64 {
return sw.fw.physicalRemaining()
}

View File

@@ -10,10 +10,11 @@ import (
"errors"
"io"
"io/fs"
"maps"
"os"
"path"
"reflect"
"slices"
"sort"
"strings"
"testing"
"testing/fstest"
@@ -702,7 +703,7 @@ func TestPaxXattrs(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
if !maps.Equal(hdr.Xattrs, xattrs) {
t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
hdr.Xattrs, xattrs)
}
@@ -1338,29 +1339,40 @@ func TestFileWriter(t *testing.T) {
func TestWriterAddFS(t *testing.T) {
fsys := fstest.MapFS{
"emptyfolder": {Mode: 0o755 | os.ModeDir},
"file.go": {Data: []byte("hello")},
"subfolder/another.go": {Data: []byte("world")},
// Notably missing here is the "subfolder" directory. This makes sure even
// if we don't have a subfolder directory listed.
}
var buf bytes.Buffer
tw := NewWriter(&buf)
if err := tw.AddFS(fsys); err != nil {
t.Fatal(err)
}
if err := tw.Close(); err != nil {
t.Fatal(err)
}
// Add subfolder into fsys to match what we'll read from the tar.
fsys["subfolder"] = &fstest.MapFile{Mode: 0o555 | os.ModeDir}
// Test that we can get the files back from the archive
tr := NewReader(&buf)
entries, err := fsys.ReadDir(".")
if err != nil {
t.Fatal(err)
names := make([]string, 0, len(fsys))
for name := range fsys {
names = append(names, name)
}
sort.Strings(names)
var curfname string
for _, entry := range entries {
curfname = entry.Name()
if entry.IsDir() {
curfname += "/"
continue
entriesLeft := len(fsys)
for _, name := range names {
entriesLeft--
entryInfo, err := fsys.Stat(name)
if err != nil {
t.Fatalf("getting entry info error: %v", err)
}
hdr, err := tr.Next()
if err == io.EOF {
@@ -1370,22 +1382,37 @@ func TestWriterAddFS(t *testing.T) {
t.Fatal(err)
}
tmpName := name
if entryInfo.IsDir() {
tmpName += "/"
}
if hdr.Name != tmpName {
t.Errorf("test fs has filename %v; archive header has %v",
name, hdr.Name)
}
if entryInfo.Mode() != hdr.FileInfo().Mode() {
t.Errorf("%s: test fs has mode %v; archive header has %v",
name, entryInfo.Mode(), hdr.FileInfo().Mode())
}
if entryInfo.IsDir() {
continue
}
data, err := io.ReadAll(tr)
if err != nil {
t.Fatal(err)
}
if hdr.Name != curfname {
t.Fatalf("got filename %v, want %v",
curfname, hdr.Name)
}
origdata := fsys[curfname].Data
origdata := fsys[name].Data
if string(data) != string(origdata) {
t.Fatalf("got file content %v, want %v",
t.Fatalf("test fs has file content %v; archive header has %v",
data, origdata)
}
}
if entriesLeft > 0 {
t.Fatalf("not all entries are in the archive")
}
}
func TestWriterAddFSNonRegularFiles(t *testing.T) {

View File

@@ -902,14 +902,8 @@ func (r *Reader) Open(name string) (fs.File, error) {
}
func split(name string) (dir, elem string, isDir bool) {
if len(name) > 0 && name[len(name)-1] == '/' {
isDir = true
name = name[:len(name)-1]
}
i := len(name) - 1
for i >= 0 && name[i] != '/' {
i--
}
name, isDir = strings.CutSuffix(name, "/")
i := strings.LastIndexByte(name, '/')
if i < 0 {
return ".", name, isDir
}

View File

@@ -13,8 +13,8 @@ import (
"io/fs"
"os"
"path/filepath"
"reflect"
"regexp"
"slices"
"strings"
"testing"
"testing/fstest"
@@ -1274,7 +1274,7 @@ func TestFSWalk(t *testing.T) {
} else if !test.wantErr && sawErr {
t.Error("unexpected error")
}
if test.want != nil && !reflect.DeepEqual(files, test.want) {
if test.want != nil && !slices.Equal(files, test.want) {
t.Errorf("got %v want %v", files, test.want)
}
})
@@ -1580,7 +1580,7 @@ func TestCVE202141772(t *testing.T) {
t.Errorf("Opening %q with fs.FS API succeeded", f.Name)
}
}
if !reflect.DeepEqual(names, entryNames) {
if !slices.Equal(names, entryNames) {
t.Errorf("Unexpected file entries: %q", names)
}
if _, err := r.Open(""); err == nil {
@@ -1693,7 +1693,7 @@ func TestInsecurePaths(t *testing.T) {
for _, f := range zr.File {
gotPaths = append(gotPaths, f.Name)
}
if !reflect.DeepEqual(gotPaths, []string{path}) {
if !slices.Equal(gotPaths, []string{path}) {
t.Errorf("NewReader for archive with file %q: got files %q", path, gotPaths)
continue
}
@@ -1718,7 +1718,7 @@ func TestDisableInsecurePathCheck(t *testing.T) {
for _, f := range zr.File {
gotPaths = append(gotPaths, f.Name)
}
if want := []string{name}; !reflect.DeepEqual(gotPaths, want) {
if want := []string{name}; !slices.Equal(gotPaths, want) {
t.Errorf("NewReader with zipinsecurepath=1: got files %q, want %q", gotPaths, want)
}
}

View File

@@ -505,14 +505,14 @@ func (w *Writer) AddFS(fsys fs.FS) error {
if err != nil {
return err
}
if d.IsDir() {
if name == "." {
return nil
}
info, err := d.Info()
if err != nil {
return err
}
if !info.Mode().IsRegular() {
if !d.IsDir() && !info.Mode().IsRegular() {
return errors.New("zip: cannot add non-regular file")
}
h, err := FileInfoHeader(info)
@@ -520,11 +520,17 @@ func (w *Writer) AddFS(fsys fs.FS) error {
return err
}
h.Name = name
if d.IsDir() {
h.Name += "/"
}
h.Method = Deflate
fw, err := w.CreateHeader(h)
if err != nil {
return err
}
if d.IsDir() {
return nil
}
f, err := fsys.Open(name)
if err != nil {
return err

View File

@@ -108,7 +108,7 @@ func TestWriter(t *testing.T) {
// TestWriterComment is test for EOCD comment read/write.
func TestWriterComment(t *testing.T) {
var tests = []struct {
tests := []struct {
comment string
ok bool
}{
@@ -158,7 +158,7 @@ func TestWriterComment(t *testing.T) {
}
func TestWriterUTF8(t *testing.T) {
var utf8Tests = []struct {
utf8Tests := []struct {
name string
comment string
nonUTF8 bool
@@ -619,32 +619,32 @@ func TestWriterAddFS(t *testing.T) {
buf := new(bytes.Buffer)
w := NewWriter(buf)
tests := []WriteTest{
{
Name: "file.go",
Data: []byte("hello"),
Mode: 0644,
},
{
Name: "subfolder/another.go",
Data: []byte("world"),
Mode: 0644,
},
{Name: "emptyfolder", Mode: 0o755 | os.ModeDir},
{Name: "file.go", Data: []byte("hello"), Mode: 0644},
{Name: "subfolder/another.go", Data: []byte("world"), Mode: 0644},
// Notably missing here is the "subfolder" directory. This makes sure even
// if we don't have a subfolder directory listed.
}
err := w.AddFS(writeTestsToFS(tests))
if err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
// Add subfolder into fsys to match what we'll read from the zip.
tests = append(tests[:2:2], WriteTest{Name: "subfolder", Mode: 0o555 | os.ModeDir}, tests[2])
// read it back
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
t.Fatal(err)
}
for i, wt := range tests {
if wt.Mode.IsDir() {
wt.Name += "/"
}
testReadFile(t, r.File[i], &wt)
}
}