diff options
Diffstat (limited to 'libgo/go/archive')
-rw-r--r-- | libgo/go/archive/tar/reader.go | 8 | ||||
-rw-r--r-- | libgo/go/archive/tar/reader_test.go | 27 | ||||
-rw-r--r-- | libgo/go/archive/zip/reader.go | 24 | ||||
-rw-r--r-- | libgo/go/archive/zip/reader_test.go | 24 | ||||
-rw-r--r-- | libgo/go/archive/zip/struct.go | 38 | ||||
-rw-r--r-- | libgo/go/archive/zip/writer.go | 2 | ||||
-rw-r--r-- | libgo/go/archive/zip/zip_test.go | 20 |
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) + } +} |