aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/archive
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/archive')
-rw-r--r--libgo/go/archive/tar/reader.go8
-rw-r--r--libgo/go/archive/tar/reader_test.go27
-rw-r--r--libgo/go/archive/zip/reader.go24
-rw-r--r--libgo/go/archive/zip/reader_test.go24
-rw-r--r--libgo/go/archive/zip/struct.go38
-rw-r--r--libgo/go/archive/zip/writer.go2
-rw-r--r--libgo/go/archive/zip/zip_test.go20
7 files changed, 90 insertions, 53 deletions
diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go
index 13fe270..755a730 100644
--- a/libgo/go/archive/tar/reader.go
+++ b/libgo/go/archive/tar/reader.go
@@ -18,7 +18,7 @@ import (
)
var (
- HeaderError = errors.New("invalid tar header")
+ ErrHeader = errors.New("invalid tar header")
)
// A Reader provides sequential access to the contents of a tar archive.
@@ -123,13 +123,13 @@ func (tr *Reader) readHeader() *Header {
if bytes.Equal(header, zeroBlock[0:blockSize]) {
tr.err = io.EOF
} else {
- tr.err = HeaderError // zero block and then non-zero block
+ tr.err = ErrHeader // zero block and then non-zero block
}
return nil
}
if !tr.verifyChecksum(header) {
- tr.err = HeaderError
+ tr.err = ErrHeader
return nil
}
@@ -188,7 +188,7 @@ func (tr *Reader) readHeader() *Header {
}
if tr.err != nil {
- tr.err = HeaderError
+ tr.err = ErrHeader
return nil
}
diff --git a/libgo/go/archive/tar/reader_test.go b/libgo/go/archive/tar/reader_test.go
index 0a6513d..0a8646c 100644
--- a/libgo/go/archive/tar/reader_test.go
+++ b/libgo/go/archive/tar/reader_test.go
@@ -240,31 +240,20 @@ func TestNonSeekable(t *testing.T) {
}
defer f.Close()
- // pipe the data in
- r, w, err := os.Pipe()
- if err != nil {
- t.Fatalf("Unexpected error %s", err)
+ type readerOnly struct {
+ io.Reader
}
- go func() {
- rdbuf := make([]uint8, 1<<16)
- for {
- nr, err := f.Read(rdbuf)
- w.Write(rdbuf[0:nr])
- if err == io.EOF {
- break
- }
- }
- w.Close()
- }()
-
- tr := NewReader(r)
+ tr := NewReader(readerOnly{f})
nread := 0
for ; ; nread++ {
- hdr, err := tr.Next()
- if hdr == nil || err == io.EOF {
+ _, err := tr.Next()
+ if err == io.EOF {
break
}
+ if err != nil {
+ t.Fatalf("Unexpected error: %v", err)
+ }
}
if nread != len(test.headers) {
diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go
index 4365009..4dd0f4f 100644
--- a/libgo/go/archive/zip/reader.go
+++ b/libgo/go/archive/zip/reader.go
@@ -17,9 +17,9 @@ import (
)
var (
- FormatError = errors.New("zip: not a valid zip file")
- UnsupportedMethod = errors.New("zip: unsupported compression algorithm")
- ChecksumError = errors.New("zip: checksum error")
+ ErrFormat = errors.New("zip: not a valid zip file")
+ ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
+ ErrChecksum = errors.New("zip: checksum error")
)
type Reader struct {
@@ -90,12 +90,12 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
// The count of files inside a zip is truncated to fit in a uint16.
// Gloss over this by reading headers until we encounter
- // a bad one, and then only report a FormatError or UnexpectedEOF if
+ // a bad one, and then only report a ErrFormat or UnexpectedEOF if
// the file count modulo 65536 is incorrect.
for {
f := &File{zipr: r, zipsize: size}
err = readDirectoryHeader(f, buf)
- if err == FormatError || err == io.ErrUnexpectedEOF {
+ if err == ErrFormat || err == io.ErrUnexpectedEOF {
break
}
if err != nil {
@@ -135,7 +135,7 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
case Deflate:
rc = flate.NewReader(r)
default:
- err = UnsupportedMethod
+ err = ErrAlgorithm
}
if rc != nil {
rc = &checksumReader{rc, crc32.NewIEEE(), f, r}
@@ -162,7 +162,7 @@ func (r *checksumReader) Read(b []byte) (n int, err error) {
}
}
if r.hash.Sum32() != r.f.CRC32 {
- err = ChecksumError
+ err = ErrChecksum
}
return
}
@@ -176,7 +176,7 @@ func readFileHeader(f *File, r io.Reader) error {
}
c := binary.LittleEndian
if sig := c.Uint32(b[:4]); sig != fileHeaderSignature {
- return FormatError
+ return ErrFormat
}
f.ReaderVersion = c.Uint16(b[4:6])
f.Flags = c.Uint16(b[6:8])
@@ -207,7 +207,7 @@ func (f *File) findBodyOffset() (int64, error) {
}
c := binary.LittleEndian
if sig := c.Uint32(b[:4]); sig != fileHeaderSignature {
- return 0, FormatError
+ return 0, ErrFormat
}
filenameLen := int(c.Uint16(b[26:28]))
extraLen := int(c.Uint16(b[28:30]))
@@ -216,7 +216,7 @@ func (f *File) findBodyOffset() (int64, error) {
// readDirectoryHeader attempts to read a directory header from r.
// It returns io.ErrUnexpectedEOF if it cannot read a complete header,
-// and FormatError if it doesn't find a valid header signature.
+// and ErrFormat if it doesn't find a valid header signature.
func readDirectoryHeader(f *File, r io.Reader) error {
var b [directoryHeaderLen]byte
if _, err := io.ReadFull(r, b[:]); err != nil {
@@ -224,7 +224,7 @@ func readDirectoryHeader(f *File, r io.Reader) error {
}
c := binary.LittleEndian
if sig := c.Uint32(b[:4]); sig != directoryHeaderSignature {
- return FormatError
+ return ErrFormat
}
f.CreatorVersion = c.Uint16(b[4:6])
f.ReaderVersion = c.Uint16(b[6:8])
@@ -280,7 +280,7 @@ func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error)
break
}
if i == 1 || bLen == size {
- return nil, FormatError
+ return nil, ErrFormat
}
}
diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go
index 0e40268..9407e35 100644
--- a/libgo/go/archive/zip/reader_test.go
+++ b/libgo/go/archive/zip/reader_test.go
@@ -70,7 +70,7 @@ var tests = []ZipTest{
},
},
{Name: "readme.zip"},
- {Name: "readme.notzip", Error: FormatError},
+ {Name: "readme.notzip", Error: ErrFormat},
{
Name: "dd.zip",
File: []ZipTestFile{
@@ -131,7 +131,7 @@ func readTestZip(t *testing.T, zt ZipTest) {
}
// bail if file is not zip
- if err == FormatError {
+ if err == ErrFormat {
return
}
defer func() {
@@ -184,8 +184,8 @@ func readTestZip(t *testing.T, zt ZipTest) {
}
var b bytes.Buffer
_, err = io.Copy(&b, r)
- if err != ChecksumError {
- t.Errorf("%s: copy error=%v, want %v", z.File[0].Name, err, ChecksumError)
+ if err != ErrChecksum {
+ t.Errorf("%s: copy error=%v, want %v", z.File[0].Name, err, ErrChecksum)
}
}
}
@@ -250,13 +250,9 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
}
func testFileMode(t *testing.T, f *File, want os.FileMode) {
- mode, err := f.Mode()
+ mode := f.Mode()
if want == 0 {
- if err == nil {
- t.Errorf("%s mode: got %v, want none", f.Name, mode)
- }
- } else if err != nil {
- t.Errorf("%s mode: %s", f.Name, err)
+ t.Errorf("%s mode: got %v, want none", f.Name, mode)
} else if mode != want {
t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
}
@@ -268,8 +264,8 @@ func TestInvalidFiles(t *testing.T) {
// zeroes
_, err := NewReader(sliceReaderAt(b), size)
- if err != FormatError {
- t.Errorf("zeroes: error=%v, want %v", err, FormatError)
+ if err != ErrFormat {
+ t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
}
// repeated directoryEndSignatures
@@ -279,8 +275,8 @@ func TestInvalidFiles(t *testing.T) {
copy(b[i:i+4], sig)
}
_, err = NewReader(sliceReaderAt(b), size)
- if err != FormatError {
- t.Errorf("sigs: error=%v, want %v", err, FormatError)
+ if err != ErrFormat {
+ t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
}
}
diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go
index 34a87fa..67e9658 100644
--- a/libgo/go/archive/zip/struct.go
+++ b/libgo/go/archive/zip/struct.go
@@ -12,6 +12,7 @@ This package does not support ZIP64 or disk spanning.
package zip
import (
+ "errors"
"os"
"time"
)
@@ -55,6 +56,38 @@ type FileHeader struct {
Comment string
}
+// FileInfo returns an os.FileInfo for the FileHeader.
+func (fh *FileHeader) FileInfo() os.FileInfo {
+ return headerFileInfo{fh}
+}
+
+// headerFileInfo implements os.FileInfo.
+type headerFileInfo struct {
+ fh *FileHeader
+}
+
+func (fi headerFileInfo) Name() string { return fi.fh.Name }
+func (fi headerFileInfo) Size() int64 { return int64(fi.fh.UncompressedSize) }
+func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
+func (fi headerFileInfo) ModTime() time.Time { return fi.fh.ModTime() }
+func (fi headerFileInfo) Mode() os.FileMode { return fi.fh.Mode() }
+
+// FileInfoHeader creates a partially-populated FileHeader from an
+// os.FileInfo.
+func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) {
+ size := fi.Size()
+ if size > (1<<32 - 1) {
+ return nil, errors.New("zip: file over 4GB")
+ }
+ fh := &FileHeader{
+ Name: fi.Name(),
+ UncompressedSize: uint32(size),
+ }
+ fh.SetModTime(fi.ModTime())
+ fh.SetMode(fi.Mode())
+ return fh, nil
+}
+
type directoryEnd struct {
diskNbr uint16 // unused
dirDiskNbr uint16 // unused
@@ -131,8 +164,7 @@ const (
)
// Mode returns the permission and mode bits for the FileHeader.
-// An error is returned in case the information is not available.
-func (h *FileHeader) Mode() (mode os.FileMode, err error) {
+func (h *FileHeader) Mode() (mode os.FileMode) {
switch h.CreatorVersion >> 8 {
case creatorUnix, creatorMacOSX:
mode = unixModeToFileMode(h.ExternalAttrs >> 16)
@@ -142,7 +174,7 @@ func (h *FileHeader) Mode() (mode os.FileMode, err error) {
if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
mode |= os.ModeDir
}
- return mode, nil
+ return mode
}
// SetMode changes the permission and mode bits for the FileHeader.
diff --git a/libgo/go/archive/zip/writer.go b/libgo/go/archive/zip/writer.go
index a153064..b1b128e 100644
--- a/libgo/go/archive/zip/writer.go
+++ b/libgo/go/archive/zip/writer.go
@@ -129,7 +129,7 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
case Deflate:
fw.comp = flate.NewWriter(fw.compCount, 5)
default:
- return nil, UnsupportedMethod
+ return nil, ErrAlgorithm
}
fw.rawCount = &countWriter{w: fw.comp}
diff --git a/libgo/go/archive/zip/zip_test.go b/libgo/go/archive/zip/zip_test.go
index 8aab2b6..acd3d93 100644
--- a/libgo/go/archive/zip/zip_test.go
+++ b/libgo/go/archive/zip/zip_test.go
@@ -10,6 +10,7 @@ import (
"bytes"
"fmt"
"io"
+ "reflect"
"testing"
"time"
)
@@ -66,3 +67,22 @@ func TestModTime(t *testing.T) {
t.Errorf("times don't match: got %s, want %s", outTime, testTime)
}
}
+
+func TestFileHeaderRoundTrip(t *testing.T) {
+ fh := &FileHeader{
+ Name: "foo.txt",
+ UncompressedSize: 987654321,
+ ModifiedTime: 1234,
+ ModifiedDate: 5678,
+ }
+ fi := fh.FileInfo()
+ fh2, err := FileInfoHeader(fi)
+
+ // Ignore these fields:
+ fh2.CreatorVersion = 0
+ fh2.ExternalAttrs = 0
+
+ if !reflect.DeepEqual(fh, fh2) {
+ t.Errorf("mismatch\n input=%#v\noutput=%#v\nerr=%v", fh, fh2, err)
+ }
+}