aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/zip
diff options
context:
space:
mode:
authorNan Zhang <nanzhang@google.com>2017-09-19 17:13:11 -0700
committerNan Zhang <nanzhang@google.com>2017-09-19 21:01:18 -0700
commit10e8e937100833d222e46fed5cae38bd70cb5298 (patch)
tree44bc467aea9a62974b179ee51494a8d8a06e1634 /third_party/zip
parent8eded0ac865bbe3df12a62afcbce0091320cddf3 (diff)
downloadbuild_soong-10e8e937100833d222e46fed5cae38bd70cb5298.tar.gz
build_soong-10e8e937100833d222e46fed5cae38bd70cb5298.tar.bz2
build_soong-10e8e937100833d222e46fed5cae38bd70cb5298.zip
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
Diffstat (limited to 'third_party/zip')
-rw-r--r--third_party/zip/android.go25
-rw-r--r--third_party/zip/android_test.go7
2 files changed, 21 insertions, 11 deletions
diff --git a/third_party/zip/android.go b/third_party/zip/android.go
index d35513fd..8d387ccb 100644
--- a/third_party/zip/android.go
+++ b/third_party/zip/android.go
@@ -20,6 +20,7 @@ import (
)
const DataDescriptorFlag = 0x8
+const ExtendedTimeStampTag = 0x5455
func (w *Writer) CopyFrom(orig *File, newName string) error {
if w.last != nil && !w.last.closed {
@@ -33,11 +34,9 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
fileHeader.Name = newName
fh := &fileHeader
- // The zip64 extras change between the Central Directory and Local File Header, while we use
- // 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.
- fh.Extra = stripZip64Extras(fh.Extra)
+ // In some cases, we need strip the extras if it change between Central Directory
+ // and Local File Header.
+ fh.Extra = stripExtras(fh.Extra)
h := &header{
FileHeader: fh,
@@ -48,8 +47,6 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
if err := writeHeader(w.cw, fh); err != nil {
return err
}
-
- // Copy data
dataOffset, err := orig.DataOffset()
if err != nil {
return err
@@ -79,8 +76,16 @@ func (w *Writer) CopyFrom(orig *File, newName string) error {
return err
}
-// Strip any Zip64 extra fields
-func stripZip64Extras(input []byte) []byte {
+// The zip64 extras change between the Central Directory and Local File Header, while we use
+// 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{}
for len(input) >= 4 {
@@ -90,7 +95,7 @@ func stripZip64Extras(input []byte) []byte {
if int(size) > len(r) {
break
}
- if tag != zip64ExtraId {
+ if tag != zip64ExtraId && tag != ExtendedTimeStampTag {
ret = append(ret, input[:4+size]...)
}
input = input[4+size:]
diff --git a/third_party/zip/android_test.go b/third_party/zip/android_test.go
index cdf66ff6..5154a17b 100644
--- a/third_party/zip/android_test.go
+++ b/third_party/zip/android_test.go
@@ -59,11 +59,16 @@ var stripZip64Testcases = []struct {
in: []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) {
for _, testcase := range stripZip64Testcases {
- got := stripZip64Extras(testcase.in)
+ got := stripExtras(testcase.in)
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)
}