xref: /aosp_15_r20/system/libziparchive/zip_writer_test.cc (revision adcb0a6279ea715828f9bc5e351569419e478774)
1*adcb0a62SAndroid Build Coastguard Worker /*
2*adcb0a62SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*adcb0a62SAndroid Build Coastguard Worker  *
4*adcb0a62SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*adcb0a62SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*adcb0a62SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*adcb0a62SAndroid Build Coastguard Worker  *
8*adcb0a62SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*adcb0a62SAndroid Build Coastguard Worker  *
10*adcb0a62SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*adcb0a62SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*adcb0a62SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*adcb0a62SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*adcb0a62SAndroid Build Coastguard Worker  * limitations under the License.
15*adcb0a62SAndroid Build Coastguard Worker  */
16*adcb0a62SAndroid Build Coastguard Worker 
17*adcb0a62SAndroid Build Coastguard Worker #include "ziparchive/zip_writer.h"
18*adcb0a62SAndroid Build Coastguard Worker #include "ziparchive/zip_archive.h"
19*adcb0a62SAndroid Build Coastguard Worker 
20*adcb0a62SAndroid Build Coastguard Worker #include <android-base/test_utils.h>
21*adcb0a62SAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*adcb0a62SAndroid Build Coastguard Worker #include <time.h>
23*adcb0a62SAndroid Build Coastguard Worker #include <memory>
24*adcb0a62SAndroid Build Coastguard Worker #include <vector>
25*adcb0a62SAndroid Build Coastguard Worker 
26*adcb0a62SAndroid Build Coastguard Worker static ::testing::AssertionResult AssertFileEntryContentsEq(const std::string& expected,
27*adcb0a62SAndroid Build Coastguard Worker                                                             ZipArchiveHandle handle,
28*adcb0a62SAndroid Build Coastguard Worker                                                             ZipEntry* zip_entry);
29*adcb0a62SAndroid Build Coastguard Worker 
30*adcb0a62SAndroid Build Coastguard Worker struct zipwriter : public ::testing::Test {
31*adcb0a62SAndroid Build Coastguard Worker   TemporaryFile* temp_file_;
32*adcb0a62SAndroid Build Coastguard Worker   int fd_;
33*adcb0a62SAndroid Build Coastguard Worker   FILE* file_;
34*adcb0a62SAndroid Build Coastguard Worker 
SetUpzipwriter35*adcb0a62SAndroid Build Coastguard Worker   void SetUp() override {
36*adcb0a62SAndroid Build Coastguard Worker     temp_file_ = new TemporaryFile();
37*adcb0a62SAndroid Build Coastguard Worker     fd_ = temp_file_->fd;
38*adcb0a62SAndroid Build Coastguard Worker     file_ = fdopen(fd_, "w");
39*adcb0a62SAndroid Build Coastguard Worker     ASSERT_NE(file_, nullptr);
40*adcb0a62SAndroid Build Coastguard Worker   }
41*adcb0a62SAndroid Build Coastguard Worker 
TearDownzipwriter42*adcb0a62SAndroid Build Coastguard Worker   void TearDown() override {
43*adcb0a62SAndroid Build Coastguard Worker     fclose(file_);
44*adcb0a62SAndroid Build Coastguard Worker     delete temp_file_;
45*adcb0a62SAndroid Build Coastguard Worker   }
46*adcb0a62SAndroid Build Coastguard Worker };
47*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteEmptyUncompressedZipWithOneFile)48*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteEmptyUncompressedZipWithOneFile) {
49*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
50*adcb0a62SAndroid Build Coastguard Worker 
51*adcb0a62SAndroid Build Coastguard Worker   const char* expected = "";
52*adcb0a62SAndroid Build Coastguard Worker 
53*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
54*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
55*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
56*adcb0a62SAndroid Build Coastguard Worker 
57*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
58*adcb0a62SAndroid Build Coastguard Worker 
59*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
60*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
61*adcb0a62SAndroid Build Coastguard Worker 
62*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
63*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
64*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
65*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.has_data_descriptor);
66*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(strlen(expected), data.compressed_length);
67*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(strlen(expected), data.uncompressed_length);
68*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));
69*adcb0a62SAndroid Build Coastguard Worker 
70*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
71*adcb0a62SAndroid Build Coastguard Worker }
72*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteEmptyCompressedZipWithOneFile)73*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteEmptyCompressedZipWithOneFile) {
74*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
75*adcb0a62SAndroid Build Coastguard Worker 
76*adcb0a62SAndroid Build Coastguard Worker   const char* expected = "";
77*adcb0a62SAndroid Build Coastguard Worker 
78*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", ZipWriter::kCompress));
79*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
80*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
81*adcb0a62SAndroid Build Coastguard Worker 
82*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
83*adcb0a62SAndroid Build Coastguard Worker 
84*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
85*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
86*adcb0a62SAndroid Build Coastguard Worker 
87*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
88*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
89*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressDeflated, data.method);
90*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.has_data_descriptor);
91*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(strlen(expected), data.uncompressed_length);
92*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));
93*adcb0a62SAndroid Build Coastguard Worker 
94*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
95*adcb0a62SAndroid Build Coastguard Worker }
96*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipWithOneFile)97*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipWithOneFile) {
98*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
99*adcb0a62SAndroid Build Coastguard Worker 
100*adcb0a62SAndroid Build Coastguard Worker   const char* expected = "hello";
101*adcb0a62SAndroid Build Coastguard Worker 
102*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
103*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
104*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("llo", 3));
105*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
106*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
107*adcb0a62SAndroid Build Coastguard Worker 
108*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
109*adcb0a62SAndroid Build Coastguard Worker 
110*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
111*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
112*adcb0a62SAndroid Build Coastguard Worker 
113*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
114*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
115*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
116*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.has_data_descriptor);
117*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(strlen(expected), data.compressed_length);
118*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(strlen(expected), data.uncompressed_length);
119*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));
120*adcb0a62SAndroid Build Coastguard Worker 
121*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
122*adcb0a62SAndroid Build Coastguard Worker }
123*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipWithMultipleFiles)124*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipWithMultipleFiles) {
125*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
126*adcb0a62SAndroid Build Coastguard Worker 
127*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
128*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
129*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
130*adcb0a62SAndroid Build Coastguard Worker 
131*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file/file.txt", 0));
132*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("llo", 3));
133*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
134*adcb0a62SAndroid Build Coastguard Worker 
135*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file/file2.txt", 0));
136*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
137*adcb0a62SAndroid Build Coastguard Worker 
138*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
139*adcb0a62SAndroid Build Coastguard Worker 
140*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
141*adcb0a62SAndroid Build Coastguard Worker 
142*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
143*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
144*adcb0a62SAndroid Build Coastguard Worker 
145*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
146*adcb0a62SAndroid Build Coastguard Worker 
147*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
148*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
149*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(2u, data.compressed_length);
150*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(2u, data.uncompressed_length);
151*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq("he", handle, &data));
152*adcb0a62SAndroid Build Coastguard Worker 
153*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file/file.txt", &data));
154*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
155*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(3u, data.compressed_length);
156*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(3u, data.uncompressed_length);
157*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq("llo", handle, &data));
158*adcb0a62SAndroid Build Coastguard Worker 
159*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file/file2.txt", &data));
160*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
161*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.compressed_length);
162*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.uncompressed_length);
163*adcb0a62SAndroid Build Coastguard Worker 
164*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
165*adcb0a62SAndroid Build Coastguard Worker }
166*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipFileWithAlignedFlag)167*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlag) {
168*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
169*adcb0a62SAndroid Build Coastguard Worker 
170*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("align.txt", ZipWriter::kAlign32));
171*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
172*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
173*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
174*adcb0a62SAndroid Build Coastguard Worker 
175*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
176*adcb0a62SAndroid Build Coastguard Worker 
177*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
178*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
179*adcb0a62SAndroid Build Coastguard Worker 
180*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
181*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
182*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, data.offset & 0x03);
183*adcb0a62SAndroid Build Coastguard Worker 
184*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
185*adcb0a62SAndroid Build Coastguard Worker }
186*adcb0a62SAndroid Build Coastguard Worker 
MakeTm()187*adcb0a62SAndroid Build Coastguard Worker static struct tm MakeTm() {
188*adcb0a62SAndroid Build Coastguard Worker   struct tm tm = {};
189*adcb0a62SAndroid Build Coastguard Worker   tm.tm_year = 2001 - 1900;
190*adcb0a62SAndroid Build Coastguard Worker   tm.tm_mon = 1;
191*adcb0a62SAndroid Build Coastguard Worker   tm.tm_mday = 12;
192*adcb0a62SAndroid Build Coastguard Worker   tm.tm_hour = 18;
193*adcb0a62SAndroid Build Coastguard Worker   tm.tm_min = 30;
194*adcb0a62SAndroid Build Coastguard Worker   tm.tm_sec = 20;
195*adcb0a62SAndroid Build Coastguard Worker   return tm;
196*adcb0a62SAndroid Build Coastguard Worker }
197*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipFileWithAlignedFlagAndTime)198*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlagAndTime) {
199*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
200*adcb0a62SAndroid Build Coastguard Worker 
201*adcb0a62SAndroid Build Coastguard Worker   struct tm tm = MakeTm();
202*adcb0a62SAndroid Build Coastguard Worker   time_t time = mktime(&tm);
203*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntryWithTime("align.txt", ZipWriter::kAlign32, time));
204*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
205*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
206*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
207*adcb0a62SAndroid Build Coastguard Worker 
208*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
209*adcb0a62SAndroid Build Coastguard Worker 
210*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
211*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
212*adcb0a62SAndroid Build Coastguard Worker 
213*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
214*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
215*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, data.offset & 0x03);
216*adcb0a62SAndroid Build Coastguard Worker 
217*adcb0a62SAndroid Build Coastguard Worker   struct tm mod = data.GetModificationTime();
218*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_sec, mod.tm_sec);
219*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_min, mod.tm_min);
220*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_hour, mod.tm_hour);
221*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_mday, mod.tm_mday);
222*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_mon, mod.tm_mon);
223*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_year, mod.tm_year);
224*adcb0a62SAndroid Build Coastguard Worker 
225*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
226*adcb0a62SAndroid Build Coastguard Worker }
227*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipFileWithAlignedValue)228*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValue) {
229*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
230*adcb0a62SAndroid Build Coastguard Worker 
231*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartAlignedEntry("align.txt", 0, 4096));
232*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
233*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
234*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
235*adcb0a62SAndroid Build Coastguard Worker 
236*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
237*adcb0a62SAndroid Build Coastguard Worker 
238*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
239*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
240*adcb0a62SAndroid Build Coastguard Worker 
241*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
242*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
243*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, data.offset & 0xfff);
244*adcb0a62SAndroid Build Coastguard Worker 
245*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
246*adcb0a62SAndroid Build Coastguard Worker }
247*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteUncompressedZipFileWithAlignedValueAndTime)248*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValueAndTime) {
249*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
250*adcb0a62SAndroid Build Coastguard Worker 
251*adcb0a62SAndroid Build Coastguard Worker   struct tm tm = MakeTm();
252*adcb0a62SAndroid Build Coastguard Worker   time_t time = mktime(&tm);
253*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartAlignedEntryWithTime("align.txt", 0, time, 4096));
254*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("he", 2));
255*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
256*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
257*adcb0a62SAndroid Build Coastguard Worker 
258*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
259*adcb0a62SAndroid Build Coastguard Worker 
260*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
261*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
262*adcb0a62SAndroid Build Coastguard Worker 
263*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
264*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
265*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, data.offset & 0xfff);
266*adcb0a62SAndroid Build Coastguard Worker 
267*adcb0a62SAndroid Build Coastguard Worker   struct tm mod = data.GetModificationTime();
268*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_sec, mod.tm_sec);
269*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_min, mod.tm_min);
270*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_hour, mod.tm_hour);
271*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_mday, mod.tm_mday);
272*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_mon, mod.tm_mon);
273*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(tm.tm_year, mod.tm_year);
274*adcb0a62SAndroid Build Coastguard Worker 
275*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
276*adcb0a62SAndroid Build Coastguard Worker }
277*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteCompressedZipWithOneFile)278*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteCompressedZipWithOneFile) {
279*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
280*adcb0a62SAndroid Build Coastguard Worker 
281*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", ZipWriter::kCompress));
282*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("helo", 4));
283*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
284*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
285*adcb0a62SAndroid Build Coastguard Worker 
286*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
287*adcb0a62SAndroid Build Coastguard Worker 
288*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
289*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
290*adcb0a62SAndroid Build Coastguard Worker 
291*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
292*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
293*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressDeflated, data.method);
294*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0u, data.has_data_descriptor);
295*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(4u, data.uncompressed_length);
296*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq("helo", handle, &data));
297*adcb0a62SAndroid Build Coastguard Worker 
298*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
299*adcb0a62SAndroid Build Coastguard Worker }
300*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteCompressedZipFlushFull)301*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteCompressedZipFlushFull) {
302*adcb0a62SAndroid Build Coastguard Worker   // This exact data will cause the Finish() to require multiple calls
303*adcb0a62SAndroid Build Coastguard Worker   // to deflate() because the ZipWriter buffer isn't big enough to hold
304*adcb0a62SAndroid Build Coastguard Worker   // the entire compressed data buffer.
305*adcb0a62SAndroid Build Coastguard Worker   constexpr size_t kBufSize = 10000000;
306*adcb0a62SAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(kBufSize);
307*adcb0a62SAndroid Build Coastguard Worker   size_t prev = 1;
308*adcb0a62SAndroid Build Coastguard Worker   for (size_t i = 0; i < kBufSize; i++) {
309*adcb0a62SAndroid Build Coastguard Worker     buffer[i] = static_cast<uint8_t>(i + prev);
310*adcb0a62SAndroid Build Coastguard Worker     prev = i;
311*adcb0a62SAndroid Build Coastguard Worker   }
312*adcb0a62SAndroid Build Coastguard Worker 
313*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
314*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", ZipWriter::kCompress));
315*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(buffer.data(), buffer.size()));
316*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
317*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
318*adcb0a62SAndroid Build Coastguard Worker 
319*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
320*adcb0a62SAndroid Build Coastguard Worker 
321*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
322*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
323*adcb0a62SAndroid Build Coastguard Worker 
324*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
325*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
326*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressDeflated, data.method);
327*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kBufSize, data.uncompressed_length);
328*adcb0a62SAndroid Build Coastguard Worker 
329*adcb0a62SAndroid Build Coastguard Worker   std::vector<uint8_t> decompress(kBufSize);
330*adcb0a62SAndroid Build Coastguard Worker   memset(decompress.data(), 0, kBufSize);
331*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(),
332*adcb0a62SAndroid Build Coastguard Worker                                static_cast<uint32_t>(decompress.size())));
333*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, memcmp(decompress.data(), buffer.data(), kBufSize))
334*adcb0a62SAndroid Build Coastguard Worker       << "Input buffer and output buffer are different.";
335*adcb0a62SAndroid Build Coastguard Worker 
336*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
337*adcb0a62SAndroid Build Coastguard Worker }
338*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteZipWithEntryTimeBefore1980)339*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteZipWithEntryTimeBefore1980) {
340*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
341*adcb0a62SAndroid Build Coastguard Worker 
342*adcb0a62SAndroid Build Coastguard Worker   struct tm tm = {};
343*adcb0a62SAndroid Build Coastguard Worker   tm.tm_year = 77;  // 1977
344*adcb0a62SAndroid Build Coastguard Worker   tm.tm_mon = 7;    // August (0-based)
345*adcb0a62SAndroid Build Coastguard Worker   tm.tm_mday = 16;  // 16th
346*adcb0a62SAndroid Build Coastguard Worker   tm.tm_hour = 15;
347*adcb0a62SAndroid Build Coastguard Worker   tm.tm_min = 30;
348*adcb0a62SAndroid Build Coastguard Worker   tm.tm_sec = 20;
349*adcb0a62SAndroid Build Coastguard Worker   time_t time = mktime(&tm);
350*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntryWithTime("file.txt", 0, time));
351*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes("king", 4));
352*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
353*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
354*adcb0a62SAndroid Build Coastguard Worker 
355*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
356*adcb0a62SAndroid Build Coastguard Worker 
357*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
358*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
359*adcb0a62SAndroid Build Coastguard Worker 
360*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
361*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
362*adcb0a62SAndroid Build Coastguard Worker 
363*adcb0a62SAndroid Build Coastguard Worker   // We expect an entry time before 1980 to be set to 1980-01-01.
364*adcb0a62SAndroid Build Coastguard Worker   struct tm mod = data.GetModificationTime();
365*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(80, mod.tm_year);
366*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, mod.tm_mon);
367*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(1, mod.tm_mday);
368*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, mod.tm_hour);
369*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, mod.tm_min);
370*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(0, mod.tm_sec);
371*adcb0a62SAndroid Build Coastguard Worker 
372*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
373*adcb0a62SAndroid Build Coastguard Worker }
374*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,CheckStartEntryErrors)375*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, CheckStartEntryErrors) {
376*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
377*adcb0a62SAndroid Build Coastguard Worker 
378*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(-5, writer.StartAlignedEntry("align.txt", ZipWriter::kAlign32, 4096));
379*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(-6, writer.StartAlignedEntry("align.txt", 0, 3));
380*adcb0a62SAndroid Build Coastguard Worker }
381*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,BackupRemovesTheLastFile)382*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, BackupRemovesTheLastFile) {
383*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
384*adcb0a62SAndroid Build Coastguard Worker 
385*adcb0a62SAndroid Build Coastguard Worker   const char* kKeepThis = "keep this";
386*adcb0a62SAndroid Build Coastguard Worker   const char* kDropThis = "drop this";
387*adcb0a62SAndroid Build Coastguard Worker   const char* kReplaceWithThis = "replace with this";
388*adcb0a62SAndroid Build Coastguard Worker 
389*adcb0a62SAndroid Build Coastguard Worker   ZipWriter::FileEntry entry;
390*adcb0a62SAndroid Build Coastguard Worker   EXPECT_LT(writer.GetLastEntry(&entry), 0);
391*adcb0a62SAndroid Build Coastguard Worker 
392*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("keep.txt", 0));
393*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(kKeepThis, strlen(kKeepThis)));
394*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
395*adcb0a62SAndroid Build Coastguard Worker 
396*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.GetLastEntry(&entry));
397*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ("keep.txt", entry.path);
398*adcb0a62SAndroid Build Coastguard Worker 
399*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("drop.txt", 0));
400*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(kDropThis, strlen(kDropThis)));
401*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
402*adcb0a62SAndroid Build Coastguard Worker 
403*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.GetLastEntry(&entry));
404*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ("drop.txt", entry.path);
405*adcb0a62SAndroid Build Coastguard Worker 
406*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.DiscardLastEntry());
407*adcb0a62SAndroid Build Coastguard Worker 
408*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.GetLastEntry(&entry));
409*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ("keep.txt", entry.path);
410*adcb0a62SAndroid Build Coastguard Worker 
411*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("replace.txt", 0));
412*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(kReplaceWithThis, strlen(kReplaceWithThis)));
413*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
414*adcb0a62SAndroid Build Coastguard Worker 
415*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.GetLastEntry(&entry));
416*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ("replace.txt", entry.path);
417*adcb0a62SAndroid Build Coastguard Worker 
418*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
419*adcb0a62SAndroid Build Coastguard Worker 
420*adcb0a62SAndroid Build Coastguard Worker   // Verify that "drop.txt" does not exist.
421*adcb0a62SAndroid Build Coastguard Worker 
422*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
423*adcb0a62SAndroid Build Coastguard Worker 
424*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
425*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
426*adcb0a62SAndroid Build Coastguard Worker 
427*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
428*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "keep.txt", &data));
429*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(kKeepThis, handle, &data));
430*adcb0a62SAndroid Build Coastguard Worker 
431*adcb0a62SAndroid Build Coastguard Worker   ASSERT_NE(0, FindEntry(handle, "drop.txt", &data));
432*adcb0a62SAndroid Build Coastguard Worker 
433*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "replace.txt", &data));
434*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(kReplaceWithThis, handle, &data));
435*adcb0a62SAndroid Build Coastguard Worker 
436*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
437*adcb0a62SAndroid Build Coastguard Worker }
438*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,WriteToUnseekableFile)439*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, WriteToUnseekableFile) {
440*adcb0a62SAndroid Build Coastguard Worker   const char* expected = "hello";
441*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
442*adcb0a62SAndroid Build Coastguard Worker   writer.seekable_ = false;
443*adcb0a62SAndroid Build Coastguard Worker 
444*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
445*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(expected, strlen(expected)));
446*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
447*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
448*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));
449*adcb0a62SAndroid Build Coastguard Worker 
450*adcb0a62SAndroid Build Coastguard Worker   ZipArchiveHandle handle;
451*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));
452*adcb0a62SAndroid Build Coastguard Worker   ZipEntry data;
453*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
454*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(kCompressStored, data.method);
455*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(1u, data.has_data_descriptor);
456*adcb0a62SAndroid Build Coastguard Worker   EXPECT_EQ(strlen(expected), data.compressed_length);
457*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(strlen(expected), data.uncompressed_length);
458*adcb0a62SAndroid Build Coastguard Worker   ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));
459*adcb0a62SAndroid Build Coastguard Worker   CloseArchive(handle);
460*adcb0a62SAndroid Build Coastguard Worker }
461*adcb0a62SAndroid Build Coastguard Worker 
TEST_F(zipwriter,TruncateFileAfterBackup)462*adcb0a62SAndroid Build Coastguard Worker TEST_F(zipwriter, TruncateFileAfterBackup) {
463*adcb0a62SAndroid Build Coastguard Worker   ZipWriter writer(file_);
464*adcb0a62SAndroid Build Coastguard Worker 
465*adcb0a62SAndroid Build Coastguard Worker   const char* kSmall = "small";
466*adcb0a62SAndroid Build Coastguard Worker 
467*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("small.txt", 0));
468*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(kSmall, strlen(kSmall)));
469*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
470*adcb0a62SAndroid Build Coastguard Worker 
471*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.StartEntry("large.txt", 0));
472*adcb0a62SAndroid Build Coastguard Worker   std::vector<uint8_t> data;
473*adcb0a62SAndroid Build Coastguard Worker   data.resize(1024 * 1024, 0xef);
474*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.WriteBytes(data.data(), data.size()));
475*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.FinishEntry());
476*adcb0a62SAndroid Build Coastguard Worker 
477*adcb0a62SAndroid Build Coastguard Worker   off_t before_len = ftello(file_);
478*adcb0a62SAndroid Build Coastguard Worker 
479*adcb0a62SAndroid Build Coastguard Worker   ZipWriter::FileEntry entry;
480*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.GetLastEntry(&entry));
481*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.DiscardLastEntry());
482*adcb0a62SAndroid Build Coastguard Worker 
483*adcb0a62SAndroid Build Coastguard Worker   ASSERT_EQ(0, writer.Finish());
484*adcb0a62SAndroid Build Coastguard Worker 
485*adcb0a62SAndroid Build Coastguard Worker   off_t after_len = ftello(file_);
486*adcb0a62SAndroid Build Coastguard Worker 
487*adcb0a62SAndroid Build Coastguard Worker   ASSERT_GT(before_len, after_len);
488*adcb0a62SAndroid Build Coastguard Worker }
489*adcb0a62SAndroid Build Coastguard Worker 
AssertFileEntryContentsEq(const std::string & expected,ZipArchiveHandle handle,ZipEntry * zip_entry)490*adcb0a62SAndroid Build Coastguard Worker static ::testing::AssertionResult AssertFileEntryContentsEq(const std::string& expected,
491*adcb0a62SAndroid Build Coastguard Worker                                                             ZipArchiveHandle handle,
492*adcb0a62SAndroid Build Coastguard Worker                                                             ZipEntry* zip_entry) {
493*adcb0a62SAndroid Build Coastguard Worker   if (expected.size() != zip_entry->uncompressed_length) {
494*adcb0a62SAndroid Build Coastguard Worker     return ::testing::AssertionFailure()
495*adcb0a62SAndroid Build Coastguard Worker            << "uncompressed entry size " << zip_entry->uncompressed_length
496*adcb0a62SAndroid Build Coastguard Worker            << " does not match expected size " << expected.size();
497*adcb0a62SAndroid Build Coastguard Worker   }
498*adcb0a62SAndroid Build Coastguard Worker 
499*adcb0a62SAndroid Build Coastguard Worker   std::string actual;
500*adcb0a62SAndroid Build Coastguard Worker   actual.resize(expected.size());
501*adcb0a62SAndroid Build Coastguard Worker 
502*adcb0a62SAndroid Build Coastguard Worker   uint8_t* buffer = reinterpret_cast<uint8_t*>(&*actual.begin());
503*adcb0a62SAndroid Build Coastguard Worker   if (ExtractToMemory(handle, zip_entry, buffer, static_cast<uint32_t>(actual.size())) != 0) {
504*adcb0a62SAndroid Build Coastguard Worker     return ::testing::AssertionFailure() << "failed to extract entry";
505*adcb0a62SAndroid Build Coastguard Worker   }
506*adcb0a62SAndroid Build Coastguard Worker 
507*adcb0a62SAndroid Build Coastguard Worker   if (expected != actual) {
508*adcb0a62SAndroid Build Coastguard Worker     return ::testing::AssertionFailure() << "actual zip_entry data '" << actual
509*adcb0a62SAndroid Build Coastguard Worker                                          << "' does not match expected '" << expected << "'";
510*adcb0a62SAndroid Build Coastguard Worker   }
511*adcb0a62SAndroid Build Coastguard Worker   return ::testing::AssertionSuccess();
512*adcb0a62SAndroid Build Coastguard Worker }
513