updating to upstream go1.2, with notes on two upstream issues
This builds fine for f19, f20 and el6 too, and should be tested now that go.tools is packaged bz#1022983
This commit is contained in:
parent
4e1713bb7e
commit
5a84c902e7
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/go1.1.1.src.tar.gz
|
/go1.1.1.src.tar.gz
|
||||||
/go1.1.2.src.tar.gz
|
/go1.1.2.src.tar.gz
|
||||||
|
/go1.2.src.tar.gz
|
||||||
|
@ -1,510 +0,0 @@
|
|||||||
Index: src/pkg/archive/tar/common.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/common.go
|
|
||||||
+++ b/src/pkg/archive/tar/common.go
|
|
||||||
@@ -13,6 +13,7 @@
|
|
||||||
package tar
|
|
||||||
|
|
||||||
import (
|
|
||||||
+ "bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
@@ -174,6 +175,23 @@
|
|
||||||
c_ISSOCK = 0140000 // Socket
|
|
||||||
)
|
|
||||||
|
|
||||||
+// Keywords for the PAX Extended Header
|
|
||||||
+const (
|
|
||||||
+ paxAtime = "atime"
|
|
||||||
+ paxCharset = "charset"
|
|
||||||
+ paxComment = "comment"
|
|
||||||
+ paxCtime = "ctime" // please note that ctime is not a valid pax header.
|
|
||||||
+ paxGid = "gid"
|
|
||||||
+ paxGname = "gname"
|
|
||||||
+ paxLinkpath = "linkpath"
|
|
||||||
+ paxMtime = "mtime"
|
|
||||||
+ paxPath = "path"
|
|
||||||
+ paxSize = "size"
|
|
||||||
+ paxUid = "uid"
|
|
||||||
+ paxUname = "uname"
|
|
||||||
+ paxNone = ""
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
// FileInfoHeader creates a partially-populated Header from fi.
|
|
||||||
// If fi describes a symlink, FileInfoHeader records link as the link target.
|
|
||||||
// If fi describes a directory, a slash is appended to the name.
|
|
||||||
@@ -257,3 +275,25 @@
|
|
||||||
b, *sp = s[0:n], s[n:]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func isASCII(s string) bool {
|
|
||||||
+ for _, c := range s {
|
|
||||||
+ if c >= 0x80 {
|
|
||||||
+ return false
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return true
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func toASCII(s string) string {
|
|
||||||
+ if isASCII(s) {
|
|
||||||
+ return s
|
|
||||||
+ }
|
|
||||||
+ var buf bytes.Buffer
|
|
||||||
+ for _, c := range s {
|
|
||||||
+ if c < 0x80 {
|
|
||||||
+ buf.WriteByte(byte(c))
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return buf.String()
|
|
||||||
+}
|
|
||||||
Index: src/pkg/archive/tar/reader.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/reader.go
|
|
||||||
+++ b/src/pkg/archive/tar/reader.go
|
|
||||||
@@ -95,45 +95,45 @@
|
|
||||||
func mergePAX(hdr *Header, headers map[string]string) error {
|
|
||||||
for k, v := range headers {
|
|
||||||
switch k {
|
|
||||||
- case "path":
|
|
||||||
+ case paxPath:
|
|
||||||
hdr.Name = v
|
|
||||||
- case "linkpath":
|
|
||||||
+ case paxLinkpath:
|
|
||||||
hdr.Linkname = v
|
|
||||||
- case "gname":
|
|
||||||
+ case paxGname:
|
|
||||||
hdr.Gname = v
|
|
||||||
- case "uname":
|
|
||||||
+ case paxUname:
|
|
||||||
hdr.Uname = v
|
|
||||||
- case "uid":
|
|
||||||
+ case paxUid:
|
|
||||||
uid, err := strconv.ParseInt(v, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.Uid = int(uid)
|
|
||||||
- case "gid":
|
|
||||||
+ case paxGid:
|
|
||||||
gid, err := strconv.ParseInt(v, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.Gid = int(gid)
|
|
||||||
- case "atime":
|
|
||||||
+ case paxAtime:
|
|
||||||
t, err := parsePAXTime(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.AccessTime = t
|
|
||||||
- case "mtime":
|
|
||||||
+ case paxMtime:
|
|
||||||
t, err := parsePAXTime(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.ModTime = t
|
|
||||||
- case "ctime":
|
|
||||||
+ case paxCtime:
|
|
||||||
t, err := parsePAXTime(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
hdr.ChangeTime = t
|
|
||||||
- case "size":
|
|
||||||
+ case paxSize:
|
|
||||||
size, err := strconv.ParseInt(v, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
Index: src/pkg/archive/tar/writer.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/writer.go
|
|
||||||
+++ b/src/pkg/archive/tar/writer.go
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
ErrFieldTooLong = errors.New("archive/tar: header field too long")
|
|
||||||
ErrWriteAfterClose = errors.New("archive/tar: write after close")
|
|
||||||
errNameTooLong = errors.New("archive/tar: name too long")
|
|
||||||
+ errInvalidHeader = errors.New("archive/tar: header field too long or contains invalid values")
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Writer provides sequential writing of a tar archive in POSIX.1 format.
|
|
||||||
@@ -37,6 +38,7 @@
|
|
||||||
pad int64 // amount of padding to write after current file entry
|
|
||||||
closed bool
|
|
||||||
usedBinary bool // whether the binary numeric field extension was used
|
|
||||||
+ preferPax bool // use pax header instead of binary numeric header
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWriter creates a new Writer writing to w.
|
|
||||||
@@ -65,16 +67,23 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write s into b, terminating it with a NUL if there is room.
|
|
||||||
-func (tw *Writer) cString(b []byte, s string) {
|
|
||||||
+// If the value is too long for the field and allowPax is true add a paxheader record instead
|
|
||||||
+func (tw *Writer) cString(b []byte, s string, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
|
|
||||||
+ needsPaxHeader := allowPax && len(s) > len(b) || !isASCII(s)
|
|
||||||
+ if needsPaxHeader {
|
|
||||||
+ paxHeaders[paxKeyword] = s
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
if len(s) > len(b) {
|
|
||||||
if tw.err == nil {
|
|
||||||
tw.err = ErrFieldTooLong
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
- copy(b, s)
|
|
||||||
- if len(s) < len(b) {
|
|
||||||
- b[len(s)] = 0
|
|
||||||
+ ascii := toASCII(s)
|
|
||||||
+ copy(b, ascii)
|
|
||||||
+ if len(ascii) < len(b) {
|
|
||||||
+ b[len(ascii)] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -85,17 +94,27 @@
|
|
||||||
for len(s)+1 < len(b) {
|
|
||||||
s = "0" + s
|
|
||||||
}
|
|
||||||
- tw.cString(b, s)
|
|
||||||
+ tw.cString(b, s, false, paxNone, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write x into b, either as octal or as binary (GNUtar/star extension).
|
|
||||||
-func (tw *Writer) numeric(b []byte, x int64) {
|
|
||||||
+// If the value is too long for the field and writingPax is enabled both for the field and the add a paxheader record instead
|
|
||||||
+func (tw *Writer) numeric(b []byte, x int64, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
|
|
||||||
// Try octal first.
|
|
||||||
s := strconv.FormatInt(x, 8)
|
|
||||||
if len(s) < len(b) {
|
|
||||||
tw.octal(b, x)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ // If it is too long for octal, and pax is preferred, use a pax header
|
|
||||||
+ if allowPax && tw.preferPax {
|
|
||||||
+ tw.octal(b, 0)
|
|
||||||
+ s := strconv.FormatInt(x, 10)
|
|
||||||
+ paxHeaders[paxKeyword] = s
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Too big: use binary (big-endian).
|
|
||||||
tw.usedBinary = true
|
|
||||||
for i := len(b) - 1; x > 0 && i >= 0; i-- {
|
|
||||||
@@ -115,6 +134,15 @@
|
|
||||||
// WriteHeader calls Flush if it is not the first header.
|
|
||||||
// Calling after a Close will return ErrWriteAfterClose.
|
|
||||||
func (tw *Writer) WriteHeader(hdr *Header) error {
|
|
||||||
+ return tw.writeHeader(hdr, true)
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+// WriteHeader writes hdr and prepares to accept the file's contents.
|
|
||||||
+// WriteHeader calls Flush if it is not the first header.
|
|
||||||
+// Calling after a Close will return ErrWriteAfterClose.
|
|
||||||
+// As this method is called internally by writePax header to allow it to
|
|
||||||
+// suppress writing the pax header.
|
|
||||||
+func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
|
|
||||||
if tw.closed {
|
|
||||||
return ErrWriteAfterClose
|
|
||||||
}
|
|
||||||
@@ -124,31 +152,21 @@
|
|
||||||
if tw.err != nil {
|
|
||||||
return tw.err
|
|
||||||
}
|
|
||||||
- // Decide whether or not to use PAX extensions
|
|
||||||
+
|
|
||||||
+ // a map to hold pax header records, if any are needed
|
|
||||||
+ paxHeaders := make(map[string]string)
|
|
||||||
+
|
|
||||||
// TODO(shanemhansen): we might want to use PAX headers for
|
|
||||||
// subsecond time resolution, but for now let's just capture
|
|
||||||
- // the long name/long symlink use case.
|
|
||||||
- suffix := hdr.Name
|
|
||||||
- prefix := ""
|
|
||||||
- if len(hdr.Name) > fileNameSize || len(hdr.Linkname) > fileNameSize {
|
|
||||||
- var err error
|
|
||||||
- prefix, suffix, err = tw.splitUSTARLongName(hdr.Name)
|
|
||||||
- // Either we were unable to pack the long name into ustar format
|
|
||||||
- // or the link name is too long; use PAX headers.
|
|
||||||
- if err == errNameTooLong || len(hdr.Linkname) > fileNameSize {
|
|
||||||
- if err := tw.writePAXHeader(hdr); err != nil {
|
|
||||||
- return err
|
|
||||||
- }
|
|
||||||
- } else if err != nil {
|
|
||||||
- return err
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- tw.nb = int64(hdr.Size)
|
|
||||||
- tw.pad = -tw.nb & (blockSize - 1) // blockSize is a power of two
|
|
||||||
+ // too long fields or non ascii characters
|
|
||||||
|
|
||||||
header := make([]byte, blockSize)
|
|
||||||
s := slicer(header)
|
|
||||||
- tw.cString(s.next(fileNameSize), suffix)
|
|
||||||
+
|
|
||||||
+ // keep a reference to the filename to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
|
|
||||||
+ pathHeaderBytes := s.next(fileNameSize)
|
|
||||||
+
|
|
||||||
+ tw.cString(pathHeaderBytes, hdr.Name, true, paxPath, paxHeaders)
|
|
||||||
|
|
||||||
// Handle out of range ModTime carefully.
|
|
||||||
var modTime int64
|
|
||||||
@@ -156,27 +174,55 @@
|
|
||||||
modTime = hdr.ModTime.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
- tw.octal(s.next(8), hdr.Mode) // 100:108
|
|
||||||
- tw.numeric(s.next(8), int64(hdr.Uid)) // 108:116
|
|
||||||
- tw.numeric(s.next(8), int64(hdr.Gid)) // 116:124
|
|
||||||
- tw.numeric(s.next(12), hdr.Size) // 124:136
|
|
||||||
- tw.numeric(s.next(12), modTime) // 136:148
|
|
||||||
- s.next(8) // chksum (148:156)
|
|
||||||
- s.next(1)[0] = hdr.Typeflag // 156:157
|
|
||||||
- tw.cString(s.next(100), hdr.Linkname) // linkname (157:257)
|
|
||||||
- copy(s.next(8), []byte("ustar\x0000")) // 257:265
|
|
||||||
- tw.cString(s.next(32), hdr.Uname) // 265:297
|
|
||||||
- tw.cString(s.next(32), hdr.Gname) // 297:329
|
|
||||||
- tw.numeric(s.next(8), hdr.Devmajor) // 329:337
|
|
||||||
- tw.numeric(s.next(8), hdr.Devminor) // 337:345
|
|
||||||
- tw.cString(s.next(155), prefix) // 345:500
|
|
||||||
+ tw.octal(s.next(8), hdr.Mode) // 100:108
|
|
||||||
+ tw.numeric(s.next(8), int64(hdr.Uid), true, paxUid, paxHeaders) // 108:116
|
|
||||||
+ tw.numeric(s.next(8), int64(hdr.Gid), true, paxGid, paxHeaders) // 116:124
|
|
||||||
+ tw.numeric(s.next(12), hdr.Size, true, paxSize, paxHeaders) // 124:136
|
|
||||||
+ tw.numeric(s.next(12), modTime, false, paxNone, nil) // 136:148 --- consider using pax for finer granularity
|
|
||||||
+ s.next(8) // chksum (148:156)
|
|
||||||
+ s.next(1)[0] = hdr.Typeflag // 156:157
|
|
||||||
+
|
|
||||||
+ tw.cString(s.next(100), hdr.Linkname, true, paxLinkpath, paxHeaders)
|
|
||||||
+
|
|
||||||
+ copy(s.next(8), []byte("ustar\x0000")) // 257:265
|
|
||||||
+ tw.cString(s.next(32), hdr.Uname, true, paxUname, paxHeaders) // 265:297
|
|
||||||
+ tw.cString(s.next(32), hdr.Gname, true, paxGname, paxHeaders) // 297:329
|
|
||||||
+ tw.numeric(s.next(8), hdr.Devmajor, false, paxNone, nil) // 329:337
|
|
||||||
+ tw.numeric(s.next(8), hdr.Devminor, false, paxNone, nil) // 337:345
|
|
||||||
+
|
|
||||||
+ // keep a reference to the prefix to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
|
|
||||||
+ prefixHeaderBytes := s.next(155)
|
|
||||||
+ tw.cString(prefixHeaderBytes, "", false, paxNone, nil) // 345:500 prefix
|
|
||||||
+
|
|
||||||
// Use the GNU magic instead of POSIX magic if we used any GNU extensions.
|
|
||||||
if tw.usedBinary {
|
|
||||||
copy(header[257:265], []byte("ustar \x00"))
|
|
||||||
}
|
|
||||||
- // Use the ustar magic if we used ustar long names.
|
|
||||||
- if len(prefix) > 0 {
|
|
||||||
- copy(header[257:265], []byte("ustar\000"))
|
|
||||||
+
|
|
||||||
+ _, paxPathUsed := paxHeaders[paxPath]
|
|
||||||
+ // try to use a ustar header when only the name is too long
|
|
||||||
+ if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
|
|
||||||
+ suffix := hdr.Name
|
|
||||||
+ prefix := ""
|
|
||||||
+ if len(hdr.Name) > fileNameSize && isASCII(hdr.Name) {
|
|
||||||
+ var err error
|
|
||||||
+ prefix, suffix, err = tw.splitUSTARLongName(hdr.Name)
|
|
||||||
+ if err == nil {
|
|
||||||
+ // ok we can use a ustar long name instead of pax, now correct the fields
|
|
||||||
+
|
|
||||||
+ // remove the path field from the pax header. this will suppress the pax header
|
|
||||||
+ delete(paxHeaders, paxPath)
|
|
||||||
+
|
|
||||||
+ // update the path fields
|
|
||||||
+ tw.cString(pathHeaderBytes, suffix, false, paxNone, nil)
|
|
||||||
+ tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
|
|
||||||
+
|
|
||||||
+ // Use the ustar magic if we used ustar long names.
|
|
||||||
+ if len(prefix) > 0 {
|
|
||||||
+ copy(header[257:265], []byte("ustar\000"))
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
// The chksum field is terminated by a NUL and a space.
|
|
||||||
@@ -190,8 +236,18 @@
|
|
||||||
return tw.err
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if len(paxHeaders) > 0 {
|
|
||||||
+ if !allowPax {
|
|
||||||
+ return errInvalidHeader
|
|
||||||
+ }
|
|
||||||
+ if err := tw.writePAXHeader(hdr, paxHeaders); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ tw.nb = int64(hdr.Size)
|
|
||||||
+ tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize
|
|
||||||
+
|
|
||||||
_, tw.err = tw.w.Write(header)
|
|
||||||
-
|
|
||||||
return tw.err
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -218,7 +274,7 @@
|
|
||||||
|
|
||||||
// writePaxHeader writes an extended pax header to the
|
|
||||||
// archive.
|
|
||||||
-func (tw *Writer) writePAXHeader(hdr *Header) error {
|
|
||||||
+func (tw *Writer) writePAXHeader(hdr *Header, paxHeaders map[string]string) error {
|
|
||||||
// Prepare extended header
|
|
||||||
ext := new(Header)
|
|
||||||
ext.Typeflag = TypeXHeader
|
|
||||||
@@ -229,18 +285,23 @@
|
|
||||||
// with the current pid.
|
|
||||||
pid := os.Getpid()
|
|
||||||
dir, file := path.Split(hdr.Name)
|
|
||||||
- ext.Name = path.Join(dir,
|
|
||||||
- fmt.Sprintf("PaxHeaders.%d", pid), file)[0:100]
|
|
||||||
+ fullName := path.Join(dir,
|
|
||||||
+ fmt.Sprintf("PaxHeaders.%d", pid), file)
|
|
||||||
+
|
|
||||||
+ ascii := toASCII(fullName)
|
|
||||||
+ if len(ascii) > 100 {
|
|
||||||
+ ascii = ascii[:100]
|
|
||||||
+ }
|
|
||||||
+ ext.Name = ascii
|
|
||||||
// Construct the body
|
|
||||||
var buf bytes.Buffer
|
|
||||||
- if len(hdr.Name) > fileNameSize {
|
|
||||||
- fmt.Fprint(&buf, paxHeader("path="+hdr.Name))
|
|
||||||
+
|
|
||||||
+ for k, v := range paxHeaders {
|
|
||||||
+ fmt.Fprint(&buf, paxHeader(k+"="+v))
|
|
||||||
}
|
|
||||||
- if len(hdr.Linkname) > fileNameSize {
|
|
||||||
- fmt.Fprint(&buf, paxHeader("linkpath="+hdr.Linkname))
|
|
||||||
- }
|
|
||||||
+
|
|
||||||
ext.Size = int64(len(buf.Bytes()))
|
|
||||||
- if err := tw.WriteHeader(ext); err != nil {
|
|
||||||
+ if err := tw.writeHeader(ext, false); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := tw.Write(buf.Bytes()); err != nil {
|
|
||||||
Index: src/pkg/archive/tar/writer_test.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/writer_test.go
|
|
||||||
+++ b/src/pkg/archive/tar/writer_test.go
|
|
||||||
@@ -243,15 +243,110 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+func TestPaxSymlink(t *testing.T) {
|
|
||||||
+ // Create an archive with a large linkname
|
|
||||||
+ fileinfo, err := os.Stat("testdata/small.txt")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ hdr, err := FileInfoHeader(fileinfo, "")
|
|
||||||
+ hdr.Typeflag = TypeSymlink
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatalf("os.Stat:1 %v", err)
|
|
||||||
+ }
|
|
||||||
+ // Force a PAX long linkname to be written
|
|
||||||
+ longLinkname := strings.Repeat("1234567890/1234567890", 10)
|
|
||||||
+ hdr.Linkname = longLinkname
|
|
||||||
+
|
|
||||||
+ hdr.Size = 0
|
|
||||||
+ var buf bytes.Buffer
|
|
||||||
+ writer := NewWriter(&buf)
|
|
||||||
+ if err := writer.WriteHeader(hdr); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if err := writer.Close(); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ // Simple test to make sure PAX extensions are in effect
|
|
||||||
+ if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
|
|
||||||
+ t.Fatal("Expected at least one PAX header to be written.")
|
|
||||||
+ }
|
|
||||||
+ // Test that we can get a long name back out of the archive.
|
|
||||||
+ reader := NewReader(&buf)
|
|
||||||
+ hdr, err = reader.Next()
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if hdr.Linkname != longLinkname {
|
|
||||||
+ t.Fatal("Couldn't recover long link name")
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func TestPaxNonAscii(t *testing.T) {
|
|
||||||
+ // Create an archive with non ascii. These should trigger a pax header
|
|
||||||
+ // because pax headers have a defined utf-8 encoding.
|
|
||||||
+ fileinfo, err := os.Stat("testdata/small.txt")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ hdr, err := FileInfoHeader(fileinfo, "")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatalf("os.Stat:1 %v", err)
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // some sample data
|
|
||||||
+ chineseFilename := "文件名"
|
|
||||||
+ chineseGroupname := "組"
|
|
||||||
+ chineseUsername := "用戶名"
|
|
||||||
+
|
|
||||||
+ hdr.Name = chineseFilename
|
|
||||||
+ hdr.Gname = chineseGroupname
|
|
||||||
+ hdr.Uname = chineseUsername
|
|
||||||
+
|
|
||||||
+ contents := strings.Repeat(" ", int(hdr.Size))
|
|
||||||
+
|
|
||||||
+ var buf bytes.Buffer
|
|
||||||
+ writer := NewWriter(&buf)
|
|
||||||
+ if err := writer.WriteHeader(hdr); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if _, err = writer.Write([]byte(contents)); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if err := writer.Close(); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ // Simple test to make sure PAX extensions are in effect
|
|
||||||
+ if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
|
|
||||||
+ t.Fatal("Expected at least one PAX header to be written.")
|
|
||||||
+ }
|
|
||||||
+ // Test that we can get a long name back out of the archive.
|
|
||||||
+ reader := NewReader(&buf)
|
|
||||||
+ hdr, err = reader.Next()
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if hdr.Name != chineseFilename {
|
|
||||||
+ t.Fatal("Couldn't recover unicode name")
|
|
||||||
+ }
|
|
||||||
+ if hdr.Gname != chineseGroupname {
|
|
||||||
+ t.Fatal("Couldn't recover unicode group")
|
|
||||||
+ }
|
|
||||||
+ if hdr.Uname != chineseUsername {
|
|
||||||
+ t.Fatal("Couldn't recover unicode user")
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
func TestPAXHeader(t *testing.T) {
|
|
||||||
medName := strings.Repeat("CD", 50)
|
|
||||||
longName := strings.Repeat("AB", 100)
|
|
||||||
paxTests := [][2]string{
|
|
||||||
- {"name=/etc/hosts", "19 name=/etc/hosts\n"},
|
|
||||||
+ {paxPath + "=/etc/hosts", "19 path=/etc/hosts\n"},
|
|
||||||
{"a=b", "6 a=b\n"}, // Single digit length
|
|
||||||
{"a=names", "11 a=names\n"}, // Test case involving carries
|
|
||||||
- {"name=" + longName, fmt.Sprintf("210 name=%s\n", longName)},
|
|
||||||
- {"name=" + medName, fmt.Sprintf("110 name=%s\n", medName)}}
|
|
||||||
+ {paxPath + "=" + longName, fmt.Sprintf("210 path=%s\n", longName)},
|
|
||||||
+ {paxPath + "=" + medName, fmt.Sprintf("110 path=%s\n", medName)}}
|
|
||||||
|
|
||||||
for _, test := range paxTests {
|
|
||||||
key, expected := test[0], test[1]
|
|
@ -1,62 +0,0 @@
|
|||||||
Index: src/pkg/archive/tar/writer.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/writer.go
|
|
||||||
+++ b/src/pkg/archive/tar/writer.go
|
|
||||||
@@ -263,8 +263,11 @@
|
|
||||||
length--
|
|
||||||
}
|
|
||||||
i := strings.LastIndex(name[:length], "/")
|
|
||||||
- nlen := length - i - 1
|
|
||||||
- if i <= 0 || nlen > fileNameSize || nlen == 0 {
|
|
||||||
+ // nlen contains the resulting length in the name field.
|
|
||||||
+ // plen contains the resulting length in the prefix field.
|
|
||||||
+ nlen := len(name) - i - 1
|
|
||||||
+ plen := i
|
|
||||||
+ if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize {
|
|
||||||
err = errNameTooLong
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Index: src/pkg/archive/tar/writer_test.go
|
|
||||||
===================================================================
|
|
||||||
--- a/src/pkg/archive/tar/writer_test.go
|
|
||||||
+++ b/src/pkg/archive/tar/writer_test.go
|
|
||||||
@@ -355,3 +355,39 @@
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func TestUSTARLongName(t *testing.T) {
|
|
||||||
+ // Create an archive with a path that failed to split with USTAR extension in previous versions.
|
|
||||||
+ fileinfo, err := os.Stat("testdata/small.txt")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ hdr, err := FileInfoHeader(fileinfo, "")
|
|
||||||
+ hdr.Typeflag = TypeDir
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatalf("os.Stat:1 %v", err)
|
|
||||||
+ }
|
|
||||||
+ // Force a PAX long name to be written. The name was taken from a practical example
|
|
||||||
+ // that fails and replaced ever char through numbers to anonymize the sample.
|
|
||||||
+ longName := "/0000_0000000/00000-000000000/0000_0000000/00000-0000000000000/0000_0000000/00000-0000000-00000000/0000_0000000/00000000/0000_0000000/000/0000_0000000/00000000v00/0000_0000000/000000/0000_0000000/0000000/0000_0000000/00000y-00/0000/0000/00000000/0x000000/"
|
|
||||||
+ hdr.Name = longName
|
|
||||||
+
|
|
||||||
+ hdr.Size = 0
|
|
||||||
+ var buf bytes.Buffer
|
|
||||||
+ writer := NewWriter(&buf)
|
|
||||||
+ if err := writer.WriteHeader(hdr); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if err := writer.Close(); err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ // Test that we can get a long name back out of the archive.
|
|
||||||
+ reader := NewReader(&buf)
|
|
||||||
+ hdr, err = reader.Next()
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Fatal(err)
|
|
||||||
+ }
|
|
||||||
+ if hdr.Name != longName {
|
|
||||||
+ t.Fatal("Couldn't recover long name")
|
|
||||||
+ }
|
|
||||||
+}
|
|
@ -1,16 +1,16 @@
|
|||||||
diff -ur go~/src/make.bash go/src/make.bash
|
diff -r 7326da92ff4d src/make.bash
|
||||||
--- go~/src/make.bash 2013-05-13 16:07:18.000000000 -0400
|
--- a/src/make.bash Mon Dec 02 09:06:41 2013 +1100
|
||||||
+++ go/src/make.bash 2013-05-23 21:20:56.804544307 -0400
|
+++ b/src/make.bash Tue Dec 03 15:29:09 2013 -0500
|
||||||
@@ -135,7 +135,7 @@
|
@@ -145,7 +145,7 @@
|
||||||
if [ "$1" = "--no-clean" ]; then
|
if [ "$1" = "--no-clean" ]; then
|
||||||
buildall=""
|
buildall=""
|
||||||
fi
|
fi
|
||||||
-./cmd/dist/dist bootstrap $buildall -v # builds go_bootstrap
|
-./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -v # builds go_bootstrap
|
||||||
+./cmd/dist/dist bootstrap $buildall -vv # builds go_bootstrap
|
+./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -vv # builds go_bootstrap
|
||||||
# Delay move of dist tool to now, because bootstrap may clear tool directory.
|
# Delay move of dist tool to now, because bootstrap may clear tool directory.
|
||||||
mv cmd/dist/dist "$GOTOOLDIR"/dist
|
mv cmd/dist/dist "$GOTOOLDIR"/dist
|
||||||
"$GOTOOLDIR"/go_bootstrap clean -i std
|
"$GOTOOLDIR"/go_bootstrap clean -i std
|
||||||
@@ -144,12 +144,12 @@
|
@@ -154,12 +154,12 @@
|
||||||
if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
|
if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOHOSTOS" != "$GOOS" ]; then
|
||||||
echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
|
echo "# Building packages and commands for host, $GOHOSTOS/$GOHOSTARCH."
|
||||||
GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
|
GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
|
57
golang.spec
57
golang.spec
@ -24,8 +24,8 @@
|
|||||||
/usr/lib/rpm/brp-compress
|
/usr/lib/rpm/brp-compress
|
||||||
|
|
||||||
Name: golang
|
Name: golang
|
||||||
Version: 1.1.2
|
Version: 1.2
|
||||||
Release: 8%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: The Go Programming Language
|
Summary: The Go Programming Language
|
||||||
|
|
||||||
License: BSD
|
License: BSD
|
||||||
@ -50,14 +50,9 @@ BuildRequires: xemacs xemacs-packages-extra
|
|||||||
# This is an odd issue, still looking for a better fix.
|
# This is an odd issue, still looking for a better fix.
|
||||||
Requires: glibc
|
Requires: glibc
|
||||||
|
|
||||||
# `go doc ...` calls out to godoc in $PATH
|
|
||||||
# while godoc is in go1.1, it is moved to go.tools in go1.2
|
|
||||||
Requires: /usr/bin/godoc
|
Requires: /usr/bin/godoc
|
||||||
|
|
||||||
Patch0: golang-1.1-verbose-build.patch
|
Patch0: golang-1.2-verbose-build.patch
|
||||||
|
|
||||||
Patch10: golang-1.1.2-long-links.patch
|
|
||||||
Patch11: golang-1.1.2-ustar-split.patch
|
|
||||||
|
|
||||||
# Having documentation separate was broken
|
# Having documentation separate was broken
|
||||||
Obsoletes: %{name}-docs < 1.1-4
|
Obsoletes: %{name}-docs < 1.1-4
|
||||||
@ -74,11 +69,6 @@ Source101: golang-prelink.conf
|
|||||||
%{summary}.
|
%{summary}.
|
||||||
|
|
||||||
|
|
||||||
%package godoc
|
|
||||||
Summary: The Go Programming Language documentation tool
|
|
||||||
%description godoc
|
|
||||||
%{summary}.
|
|
||||||
|
|
||||||
# Restore this package if RPM gets fixed (bug #975909)
|
# Restore this package if RPM gets fixed (bug #975909)
|
||||||
#%package data
|
#%package data
|
||||||
#Summary: Required architecture-independent files for Go
|
#Summary: Required architecture-independent files for Go
|
||||||
@ -141,23 +131,15 @@ end
|
|||||||
# increase verbosity of build
|
# increase verbosity of build
|
||||||
%patch0 -p1
|
%patch0 -p1
|
||||||
|
|
||||||
%if 0%{?fedora} >= 21
|
# create a [dirty] gcc wrapper to allow us to build with our own flags
|
||||||
%patch1 -p1
|
# (dirty because it is spoofing 'gcc' since CC value is stored in the go tool)
|
||||||
%endif
|
# TODO: remove this and just set CFLAGS/LDFLAGS once upstream supports it
|
||||||
|
# https://code.google.com/p/go/issues/detail?id=6882
|
||||||
# Fix BZ#1010271
|
mkdir -p zz
|
||||||
%patch10 -p1
|
echo -e "#!/bin/sh\n/usr/bin/gcc $RPM_OPT_FLAGS $RPM_LD_FLAGS \"\$@\"" > ./zz/gcc
|
||||||
%patch11 -p1
|
chmod +x ./zz/gcc
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# create a gcc wrapper to allow us to build with our own flags
|
|
||||||
mkdir zz
|
|
||||||
cd zz
|
|
||||||
echo -e "#!/bin/sh\n/usr/bin/gcc $RPM_OPT_FLAGS $RPM_LD_FLAGS \"\$@\"" > mygcc
|
|
||||||
chmod +x mygcc
|
|
||||||
export CC="$(pwd -P)/mygcc"
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
# set up final install location
|
# set up final install location
|
||||||
export GOROOT_FINAL=%{_libdir}/%{name}
|
export GOROOT_FINAL=%{_libdir}/%{name}
|
||||||
|
|
||||||
@ -167,14 +149,8 @@ export GOROOT_FINAL=%{_libdir}/%{name}
|
|||||||
|
|
||||||
# build
|
# build
|
||||||
cd src
|
cd src
|
||||||
./make.bash
|
# use our gcc wrapper
|
||||||
cd ..
|
PATH="$(pwd -P)/../zz:$PATH" CC="gcc" ./make.bash
|
||||||
|
|
||||||
# build static version of documentation
|
|
||||||
export GOROOT=$(pwd -P)
|
|
||||||
export PATH="$PATH":"$GOROOT"/bin
|
|
||||||
cd doc
|
|
||||||
make
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
# compile for emacs and xemacs
|
# compile for emacs and xemacs
|
||||||
@ -193,6 +169,8 @@ cd ..
|
|||||||
export GOROOT=$(pwd -P)
|
export GOROOT=$(pwd -P)
|
||||||
export PATH="$PATH":"$GOROOT"/bin
|
export PATH="$PATH":"$GOROOT"/bin
|
||||||
cd src
|
cd src
|
||||||
|
# not using our 'gcc' since the CFLAGS fails crash_cgo_test.go due to unused variables
|
||||||
|
# https://code.google.com/p/go/issues/detail?id=6883
|
||||||
./run.bash --no-rebuild
|
./run.bash --no-rebuild
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
@ -262,9 +240,6 @@ mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d
|
|||||||
cp -av %{SOURCE101} $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d/golang.conf
|
cp -av %{SOURCE101} $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d/golang.conf
|
||||||
|
|
||||||
|
|
||||||
%files godoc
|
|
||||||
%{_bindir}/godoc
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%doc AUTHORS CONTRIBUTORS LICENSE PATENTS VERSION
|
%doc AUTHORS CONTRIBUTORS LICENSE PATENTS VERSION
|
||||||
|
|
||||||
@ -307,6 +282,10 @@ cp -av %{SOURCE101} $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d/golang.conf
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 2 2013 Vincent Batts <vbatts@fedoraproject.org> - 1.2-1
|
||||||
|
- Update to upstream 1.2 release
|
||||||
|
- remove the pax tar patches
|
||||||
|
|
||||||
* Tue Nov 26 2013 Vincent Batts <vbatts@redhat.com> - 1.1.2-8
|
* Tue Nov 26 2013 Vincent Batts <vbatts@redhat.com> - 1.1.2-8
|
||||||
- fix the rpmspec conditional for rhel and fedora
|
- fix the rpmspec conditional for rhel and fedora
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user