Strip extended-timestap extra block in zip2zip.
The extended-timestap extra block changes between Local File Header and Central Directory. We have to strip it out to avoid mis-filling during zip2zip. Bug: b/65455145 Test: add unit-test. Change-Id: I17e3f6c10fd6a068019620b4426f6042f6fac317
This commit is contained in:
parent
8eded0ac86
commit
10e8e93710
2 changed files with 21 additions and 11 deletions
25
third_party/zip/android.go
vendored
25
third_party/zip/android.go
vendored
|
@ -20,6 +20,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const DataDescriptorFlag = 0x8
|
const DataDescriptorFlag = 0x8
|
||||||
|
const ExtendedTimeStampTag = 0x5455
|
||||||
|
|
||||||
func (w *Writer) CopyFrom(orig *File, newName string) error {
|
func (w *Writer) CopyFrom(orig *File, newName string) error {
|
||||||
if w.last != nil && !w.last.closed {
|
if w.last != nil && !w.last.closed {
|
||||||
|
@ -33,11 +34,9 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
|
||||||
fileHeader.Name = newName
|
fileHeader.Name = newName
|
||||||
fh := &fileHeader
|
fh := &fileHeader
|
||||||
|
|
||||||
// The zip64 extras change between the Central Directory and Local File Header, while we use
|
// In some cases, we need strip the extras if it change between Central Directory
|
||||||
// the same structure for both. The Local File Haeder is taken care of by us writing a data
|
// and Local File Header.
|
||||||
// descriptor with the zip64 values. The Central Directory Entry is written by Close(), where
|
fh.Extra = stripExtras(fh.Extra)
|
||||||
// the zip64 extra is automatically created and appended when necessary.
|
|
||||||
fh.Extra = stripZip64Extras(fh.Extra)
|
|
||||||
|
|
||||||
h := &header{
|
h := &header{
|
||||||
FileHeader: fh,
|
FileHeader: fh,
|
||||||
|
@ -48,8 +47,6 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
|
||||||
if err := writeHeader(w.cw, fh); err != nil {
|
if err := writeHeader(w.cw, fh); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy data
|
|
||||||
dataOffset, err := orig.DataOffset()
|
dataOffset, err := orig.DataOffset()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -79,8 +76,16 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip any Zip64 extra fields
|
// The zip64 extras change between the Central Directory and Local File Header, while we use
|
||||||
func stripZip64Extras(input []byte) []byte {
|
// the same structure for both. The Local File Haeder is taken care of by us writing a data
|
||||||
|
// descriptor with the zip64 values. The Central Directory Entry is written by Close(), where
|
||||||
|
// the zip64 extra is automatically created and appended when necessary.
|
||||||
|
//
|
||||||
|
// The extended-timestamp extra block changes between the Central Directory Header and Local
|
||||||
|
// File Header.
|
||||||
|
// Extended-Timestamp extra(LFH): <tag-size-flag-modtime-actime-changetime>
|
||||||
|
// Extended-Timestamp extra(CDH): <tag-size-flag-modtime>
|
||||||
|
func stripExtras(input []byte) []byte {
|
||||||
ret := []byte{}
|
ret := []byte{}
|
||||||
|
|
||||||
for len(input) >= 4 {
|
for len(input) >= 4 {
|
||||||
|
@ -90,7 +95,7 @@ func stripZip64Extras(input []byte) []byte {
|
||||||
if int(size) > len(r) {
|
if int(size) > len(r) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if tag != zip64ExtraId {
|
if tag != zip64ExtraId && tag != ExtendedTimeStampTag {
|
||||||
ret = append(ret, input[:4+size]...)
|
ret = append(ret, input[:4+size]...)
|
||||||
}
|
}
|
||||||
input = input[4+size:]
|
input = input[4+size:]
|
||||||
|
|
7
third_party/zip/android_test.go
vendored
7
third_party/zip/android_test.go
vendored
|
@ -59,11 +59,16 @@ var stripZip64Testcases = []struct {
|
||||||
in: []byte{0, 0, 8, 0, 0, 0},
|
in: []byte{0, 0, 8, 0, 0, 0},
|
||||||
out: []byte{0, 0, 8, 0, 0, 0},
|
out: []byte{0, 0, 8, 0, 0, 0},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "zip64 extra and extended-timestamp extra and valid non-zip64 extra",
|
||||||
|
in: []byte{1, 0, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 85, 84, 5, 0, 1, 1, 2, 3, 4, 2, 0, 0, 0},
|
||||||
|
out: []byte{2, 0, 0, 0},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStripZip64Extras(t *testing.T) {
|
func TestStripZip64Extras(t *testing.T) {
|
||||||
for _, testcase := range stripZip64Testcases {
|
for _, testcase := range stripZip64Testcases {
|
||||||
got := stripZip64Extras(testcase.in)
|
got := stripExtras(testcase.in)
|
||||||
if !bytes.Equal(got, testcase.out) {
|
if !bytes.Equal(got, testcase.out) {
|
||||||
t.Errorf("Failed testcase %s\ninput: %v\n want: %v\n got: %v\n", testcase.name, testcase.in, testcase.out, got)
|
t.Errorf("Failed testcase %s\ninput: %v\n want: %v\n got: %v\n", testcase.name, testcase.in, testcase.out, got)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue