1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "zip_archive.h"
17 #include "libpandafile/file.h"
18 #include "os/file.h"
19 #include "os/mem.h"
20
21 #include "assembly-emitter.h"
22 #include "assembly-parser.h"
23
24 #include <cstddef>
25 #include <cstdio>
26 #include <cstdint>
27 #include <vector>
28 #include <gtest/gtest.h>
29 #include <memory>
30 #include <securec.h>
31
32 #include <climits>
33 #include <cstdlib>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <sys/stat.h>
37
38 namespace panda::test {
39
40 #define GTEST_COUT std::cerr << "[ ] [ INFO ]"
41
42 constexpr size_t MAX_BUFFER_SIZE = 2048;
43 constexpr size_t MAX_DIR_SIZE = 64;
44
GenerateZipfile(const char *data, const char *archivename, int N, char *buf, char *archive_filename, int &i, int &ret, std::vector<uint8_t> &pf_data, int level = Z_BEST_COMPRESSION)45 static void GenerateZipfile(const char *data, const char *archivename, int N, char *buf, char *archive_filename, int &i,
46 int &ret, std::vector<uint8_t> &pf_data, int level = Z_BEST_COMPRESSION)
47 {
48 // Delete the test archive, so it doesn't keep growing as we run this test
49 remove(archivename);
50
51 // Create and append a directory entry for testing
52 ret = CreateOrAddFileIntoZip(archivename, "directory/", NULL, 0, APPEND_STATUS_CREATE, level);
53 if (ret != 0) {
54 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip for directory failed!";
55 return;
56 }
57
58 // Append a bunch of text files to the test archive
59 for (i = (N - 1); i >= 0; --i) {
60 (void)sprintf_s(archive_filename, MAX_DIR_SIZE, "%d.txt", i);
61 (void)sprintf_s(buf, MAX_BUFFER_SIZE, "%d %s %d", (N - 1) - i, data, i);
62 ret =
63 CreateOrAddFileIntoZip(archivename, archive_filename, buf, strlen(buf) + 1, APPEND_STATUS_ADDINZIP, level);
64 if (ret != 0) {
65 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip for " << i << ".txt failed!";
66 return;
67 }
68 }
69
70 // Append a file into directory entry for testing
71 (void)sprintf_s(buf, MAX_BUFFER_SIZE, "%d %s %d", N, data, N);
72 ret = CreateOrAddFileIntoZip(archivename, "directory/indirectory.txt", buf, strlen(buf) + 1, APPEND_STATUS_ADDINZIP,
73 level);
74 if (ret != 0) {
75 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip for directory/indirectory.txt failed!";
76 return;
77 }
78
79 // Add a pandafile into zip for testing
80 ret = CreateOrAddFileIntoZip(archivename, "classes.abc", pf_data.data(), pf_data.size(), APPEND_STATUS_ADDINZIP,
81 level);
82 if (ret != 0) {
83 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip for classes.abc failed!";
84 return;
85 }
86 }
87
UnzipFileCheckDirectory(const char *archivename, char *filename, int level = Z_BEST_COMPRESSION)88 static void UnzipFileCheckDirectory(const char *archivename, char *filename, int level = Z_BEST_COMPRESSION)
89 {
90 (void)sprintf_s(filename, MAX_DIR_SIZE, "directory/");
91
92 ZipArchiveHandle zipfile = nullptr;
93 FILE *myfile = fopen(archivename, "rbe");
94
95 if (OpenArchiveFile(zipfile, myfile) != 0) {
96 fclose(myfile);
97 ASSERT_EQ(1, 0) << "OpenArchiveFILE error.";
98 return;
99 }
100 if (LocateFile(zipfile, filename) != 0) {
101 CloseArchiveFile(zipfile);
102 fclose(myfile);
103 ASSERT_EQ(1, 0) << "LocateFile error.";
104 return;
105 }
106 EntryFileStat entry = EntryFileStat();
107 if (GetCurrentFileInfo(zipfile, &entry) != 0) {
108 CloseArchiveFile(zipfile);
109 fclose(myfile);
110 ASSERT_EQ(1, 0) << "GetCurrentFileInfo test error.";
111 return;
112 }
113 if (OpenCurrentFile(zipfile) != 0) {
114 CloseCurrentFile(zipfile);
115 CloseArchiveFile(zipfile);
116 fclose(myfile);
117 ASSERT_EQ(1, 0) << "OpenCurrentFile test error.";
118 return;
119 }
120
121 GetCurrentFileOffset(zipfile, &entry);
122
123 uint32_t uncompressed_length = entry.GetUncompressedSize();
124
125 ASSERT_GT(entry.GetOffset(), 0U);
126 if (level == Z_NO_COMPRESSION) {
127 ASSERT_FALSE(entry.IsCompressed());
128 } else {
129 ASSERT_TRUE(entry.IsCompressed());
130 }
131
132 GTEST_COUT << "Filename: " << filename << ", Uncompressed size: " << uncompressed_length
133 << "Compressed size: " << entry.GetCompressedSize() << "Compressed(): " << entry.IsCompressed()
134 << "entry offset: " << entry.GetOffset() << "\n";
135
136 CloseCurrentFile(zipfile);
137 CloseArchiveFile(zipfile);
138 fclose(myfile);
139 }
140
UnzipFileCheckTxt(const char *archivename, char *filename, const char *data, int N, char *buf, int &ret, int level = Z_BEST_COMPRESSION)141 static void UnzipFileCheckTxt(const char *archivename, char *filename, const char *data, int N, char *buf, int &ret,
142 int level = Z_BEST_COMPRESSION)
143 {
144 for (int i = 0; i < N; i++) {
145 (void)sprintf_s(filename, MAX_DIR_SIZE, "%d.txt", i);
146 (void)sprintf_s(buf, MAX_BUFFER_SIZE, "%d %s %d", (N - 1) - i, data, i);
147
148 ZipArchiveHandle zipfile = nullptr;
149 FILE *myfile = fopen(archivename, "rbe");
150
151 if (OpenArchiveFile(zipfile, myfile) != 0) {
152 fclose(myfile);
153 ASSERT_EQ(1, 0) << "OpenArchiveFILE error.";
154 return;
155 }
156 if (LocateFile(zipfile, filename) != 0) {
157 CloseArchiveFile(zipfile);
158 fclose(myfile);
159 ASSERT_EQ(1, 0) << "LocateFile error.";
160 return;
161 }
162 EntryFileStat entry = EntryFileStat();
163 if (GetCurrentFileInfo(zipfile, &entry) != 0) {
164 CloseArchiveFile(zipfile);
165 fclose(myfile);
166 ASSERT_EQ(1, 0) << "GetCurrentFileInfo test error.";
167 return;
168 }
169 if (OpenCurrentFile(zipfile) != 0) {
170 CloseCurrentFile(zipfile);
171 CloseArchiveFile(zipfile);
172 fclose(myfile);
173 ASSERT_EQ(1, 0) << "OpenCurrentFile test error.";
174 return;
175 }
176
177 GetCurrentFileOffset(zipfile, &entry);
178
179 uint32_t uncompressed_length = entry.GetUncompressedSize();
180 if (uncompressed_length == 0) {
181 CloseCurrentFile(zipfile);
182 CloseArchiveFile(zipfile);
183 fclose(myfile);
184 ASSERT_EQ(1, 0) << "Entry file has zero length! Readed bad data!";
185 return;
186 }
187 ASSERT_GT(entry.GetOffset(), 0U);
188 ASSERT_EQ(uncompressed_length, strlen(buf) + 1);
189 if (level == Z_NO_COMPRESSION) {
190 ASSERT_EQ(uncompressed_length, entry.GetCompressedSize());
191 ASSERT_FALSE(entry.IsCompressed());
192 } else {
193 ASSERT_GE(uncompressed_length, entry.GetCompressedSize());
194 ASSERT_TRUE(entry.IsCompressed());
195 }
196
197 GTEST_COUT << "Filename: " << filename << ", Uncompressed size: " << uncompressed_length
198 << "Compressed size: " << entry.GetCompressedSize() << "Compressed(): " << entry.IsCompressed()
199 << "entry offset: " << entry.GetOffset() << "\n";
200
201 {
202 // Extract to mem buffer accroding to entry info.
203 uint32_t page_size = os::mem::GetPageSize();
204 uint32_t min_pages = uncompressed_length / page_size;
205 uint32_t size_to_mmap =
206 uncompressed_length % page_size == 0 ? min_pages * page_size : (min_pages + 1) * page_size;
207 // we will use mem in memcmp, so donnot poision it!
208 void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
209 if (mem == nullptr) {
210 CloseCurrentFile(zipfile);
211 CloseArchiveFile(zipfile);
212 fclose(myfile);
213 ASSERT_EQ(1, 0) << "Can't mmap anonymous!";
214 return;
215 }
216
217 ret = ExtractToMemory(zipfile, reinterpret_cast<uint8_t *>(mem), size_to_mmap);
218 if (ret != 0) {
219 os::mem::UnmapRaw(mem, size_to_mmap);
220 CloseCurrentFile(zipfile);
221 CloseArchiveFile(zipfile);
222 fclose(myfile);
223 ASSERT_EQ(1, 0) << "Can't extract!";
224 return;
225 }
226
227 // Make sure the extraction really succeeded.
228 size_t dlen = strlen(buf);
229 if (uncompressed_length != (dlen + 1)) {
230 os::mem::UnmapRaw(mem, size_to_mmap);
231 CloseCurrentFile(zipfile);
232 CloseArchive(zipfile);
233 fclose(myfile);
234 ASSERT_EQ(1, 0) << "ExtractToMemory() failed!, uncompressed_length is " << uncompressed_length - 1
235 << ", original strlen is " << dlen;
236 return;
237 }
238
239 if (memcmp(mem, buf, dlen)) {
240 os::mem::UnmapRaw(mem, size_to_mmap);
241 CloseCurrentFile(zipfile);
242 CloseArchive(zipfile);
243 fclose(myfile);
244 ASSERT_EQ(1, 0) << "ExtractToMemory() memcmp failed!";
245 return;
246 }
247
248 GTEST_COUT << "Successfully extracted file " << filename << " from " << archivename << ", size is "
249 << uncompressed_length << "\n";
250 os::mem::UnmapRaw(mem, size_to_mmap);
251 }
252
253 CloseCurrentFile(zipfile);
254 CloseArchiveFile(zipfile);
255 fclose(myfile);
256 }
257 }
258
UnzipFileCheckPandaFile(const char *archivename, char *filename, std::vector<uint8_t> &pf_data, int &ret, int level = Z_BEST_COMPRESSION)259 static void UnzipFileCheckPandaFile(const char *archivename, char *filename, std::vector<uint8_t> &pf_data, int &ret,
260 int level = Z_BEST_COMPRESSION)
261 {
262 {
263 ZipArchiveHandle zipfile = nullptr;
264 FILE *myfile = fopen(archivename, "rbe");
265
266 if (OpenArchiveFile(zipfile, myfile) != 0) {
267 fclose(myfile);
268 ASSERT_EQ(1, 0) << "OpenArchiveFILE error.";
269 return;
270 }
271 if (LocateFile(zipfile, filename) != 0) {
272 CloseArchiveFile(zipfile);
273 fclose(myfile);
274 ASSERT_EQ(1, 0) << "LocateFile error.";
275 return;
276 }
277 EntryFileStat entry = EntryFileStat();
278 if (GetCurrentFileInfo(zipfile, &entry) != 0) {
279 CloseArchiveFile(zipfile);
280 fclose(myfile);
281 ASSERT_EQ(1, 0) << "GetCurrentFileInfo test error.";
282 return;
283 }
284 if (OpenCurrentFile(zipfile) != 0) {
285 CloseCurrentFile(zipfile);
286 CloseArchiveFile(zipfile);
287 fclose(myfile);
288 ASSERT_EQ(1, 0) << "OpenCurrentFile test error.";
289 return;
290 }
291
292 GetCurrentFileOffset(zipfile, &entry);
293
294 uint32_t uncompressed_length = entry.GetUncompressedSize();
295 if (uncompressed_length == 0) {
296 CloseCurrentFile(zipfile);
297 CloseArchiveFile(zipfile);
298 fclose(myfile);
299 ASSERT_EQ(1, 0) << "Entry file has zero length! Readed bad data!";
300 return;
301 }
302 ASSERT_GT(entry.GetOffset(), 0U);
303 ASSERT_EQ(uncompressed_length, pf_data.size());
304 if (level == Z_NO_COMPRESSION) {
305 ASSERT_EQ(uncompressed_length, entry.GetCompressedSize());
306 ASSERT_FALSE(entry.IsCompressed());
307 } else {
308 ASSERT_GE(uncompressed_length, entry.GetCompressedSize());
309 ASSERT_TRUE(entry.IsCompressed());
310 }
311
312 GTEST_COUT << "Filename: " << filename << ", Uncompressed size: " << uncompressed_length
313 << "Compressed size: " << entry.GetCompressedSize() << "Compressed(): " << entry.IsCompressed()
314 << "entry offset: " << entry.GetOffset() << "\n";
315
316 {
317 // Extract to mem buffer accroding to entry info.
318 uint32_t page_size = os::mem::GetPageSize();
319 uint32_t min_pages = uncompressed_length / page_size;
320 uint32_t size_to_mmap =
321 uncompressed_length % page_size == 0 ? min_pages * page_size : (min_pages + 1) * page_size;
322 // we will use mem in memcmp, so donnot poision it!
323 void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
324 if (mem == nullptr) {
325 CloseCurrentFile(zipfile);
326 CloseArchiveFile(zipfile);
327 fclose(myfile);
328 ASSERT_EQ(1, 0) << "Can't mmap anonymous!";
329 return;
330 }
331
332 ret = ExtractToMemory(zipfile, reinterpret_cast<uint8_t *>(mem), size_to_mmap);
333 if (ret != 0) {
334 os::mem::UnmapRaw(mem, size_to_mmap);
335 CloseCurrentFile(zipfile);
336 CloseArchiveFile(zipfile);
337 fclose(myfile);
338 ASSERT_EQ(1, 0) << "Can't extract!";
339 return;
340 }
341
342 // Make sure the extraction really succeeded.
343 if (uncompressed_length != pf_data.size()) {
344 os::mem::UnmapRaw(mem, size_to_mmap);
345 CloseCurrentFile(zipfile);
346 CloseArchiveFile(zipfile);
347 fclose(myfile);
348 ASSERT_EQ(1, 0) << "ExtractToMemory() failed!, uncompressed_length is " << uncompressed_length
349 << ", original pf_data size is " << pf_data.size() << "\n";
350 return;
351 }
352
353 if (memcmp(mem, pf_data.data(), pf_data.size())) {
354 os::mem::UnmapRaw(mem, size_to_mmap);
355 CloseCurrentFile(zipfile);
356 CloseArchiveFile(zipfile);
357 fclose(myfile);
358 ASSERT_EQ(1, 0) << "ExtractToMemory() memcmp failed!";
359 return;
360 }
361
362 GTEST_COUT << "Successfully extracted file " << filename << " from " << archivename << ", size is "
363 << uncompressed_length << "\n";
364
365 os::mem::UnmapRaw(mem, size_to_mmap);
366 }
367 CloseCurrentFile(zipfile);
368 CloseArchiveFile(zipfile);
369 fclose(myfile);
370 }
371 }
372
UnzipFileCheckInDirectory(const char *archivename, char *filename, const char *data, int N, char *buf, int &ret, int level = Z_BEST_COMPRESSION)373 static void UnzipFileCheckInDirectory(const char *archivename, char *filename, const char *data, int N, char *buf,
374 int &ret, int level = Z_BEST_COMPRESSION)
375 {
376 {
377 (void)sprintf_s(filename, MAX_DIR_SIZE, "directory/indirectory.txt");
378 (void)sprintf_s(buf, MAX_BUFFER_SIZE, "%d %s %d", N, data, N);
379
380 // Unzip Check
381 ZipArchiveHandle zipfile = nullptr;
382 FILE *myfile = fopen(archivename, "rbe");
383
384 if (OpenArchiveFile(zipfile, myfile) != 0) {
385 fclose(myfile);
386 ASSERT_EQ(1, 0) << "OpenArchiveFILE error.";
387 return;
388 }
389 if (LocateFile(zipfile, filename) != 0) {
390 CloseArchiveFile(zipfile);
391 fclose(myfile);
392 ASSERT_EQ(1, 0) << "LocateFile error.";
393 return;
394 }
395 EntryFileStat entry = EntryFileStat();
396 if (GetCurrentFileInfo(zipfile, &entry) != 0) {
397 CloseArchiveFile(zipfile);
398 fclose(myfile);
399 ASSERT_EQ(1, 0) << "GetCurrentFileInfo test error.";
400 return;
401 }
402 if (OpenCurrentFile(zipfile) != 0) {
403 CloseCurrentFile(zipfile);
404 CloseArchiveFile(zipfile);
405 fclose(myfile);
406 ASSERT_EQ(1, 0) << "OpenCurrentFile test error.";
407 return;
408 }
409
410 GetCurrentFileOffset(zipfile, &entry);
411
412 uint32_t uncompressed_length = entry.GetUncompressedSize();
413 if (uncompressed_length == 0) {
414 CloseCurrentFile(zipfile);
415 CloseArchiveFile(zipfile);
416 fclose(myfile);
417 ASSERT_EQ(1, 0) << "Entry file has zero length! Readed bad data!";
418 return;
419 }
420 ASSERT_GT(entry.GetOffset(), 0U);
421 ASSERT_EQ(uncompressed_length, strlen(buf) + 1);
422 if (level == Z_NO_COMPRESSION) {
423 ASSERT_EQ(uncompressed_length, entry.GetCompressedSize());
424 ASSERT_FALSE(entry.IsCompressed());
425 } else {
426 ASSERT_GE(uncompressed_length, entry.GetCompressedSize());
427 ASSERT_TRUE(entry.IsCompressed());
428 }
429 GTEST_COUT << "Filename: " << filename << ", Uncompressed size: " << uncompressed_length
430 << "Compressed size: " << entry.GetCompressedSize() << "Compressed(): " << entry.IsCompressed()
431 << "entry offset: " << entry.GetOffset() << "\n";
432
433 {
434 // Extract to mem buffer accroding to entry info.
435 uint32_t page_size = os::mem::GetPageSize();
436 uint32_t min_pages = uncompressed_length / page_size;
437 uint32_t size_to_mmap =
438 uncompressed_length % page_size == 0 ? min_pages * page_size : (min_pages + 1) * page_size;
439 // we will use mem in memcmp, so donnot poision it!
440 void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
441 if (mem == nullptr) {
442 CloseCurrentFile(zipfile);
443 CloseArchiveFile(zipfile);
444 fclose(myfile);
445 ASSERT_EQ(1, 0) << "Can't mmap anonymous!";
446 return;
447 }
448
449 ret = ExtractToMemory(zipfile, reinterpret_cast<uint8_t *>(mem), size_to_mmap);
450 if (ret != 0) {
451 os::mem::UnmapRaw(mem, size_to_mmap);
452 CloseCurrentFile(zipfile);
453 CloseArchiveFile(zipfile);
454 fclose(myfile);
455 ASSERT_EQ(1, 0) << "Can't extract!";
456 return;
457 }
458
459 // Make sure the extraction really succeeded.
460 size_t dlen = strlen(buf);
461 if (uncompressed_length != (dlen + 1)) {
462 os::mem::UnmapRaw(mem, size_to_mmap);
463 CloseCurrentFile(zipfile);
464 CloseArchive(zipfile);
465 fclose(myfile);
466 ASSERT_EQ(1, 0) << "ExtractToMemory() failed!, uncompressed_length is " << uncompressed_length - 1
467 << ", original strlen is " << dlen;
468 return;
469 }
470
471 if (memcmp(mem, buf, dlen)) {
472 os::mem::UnmapRaw(mem, size_to_mmap);
473 CloseCurrentFile(zipfile);
474 CloseArchive(zipfile);
475 fclose(myfile);
476 ASSERT_EQ(1, 0) << "ExtractToMemory() memcmp failed!";
477 return;
478 }
479
480 GTEST_COUT << "Successfully extracted file " << filename << " from " << archivename << ", size is "
481 << uncompressed_length << "\n";
482
483 os::mem::UnmapRaw(mem, size_to_mmap);
484 }
485
486 CloseCurrentFile(zipfile);
487 CloseArchiveFile(zipfile);
488 fclose(myfile);
489 }
490 }
491
HWTEST(LIBZIPARCHIVE, ZipFile, testing::ext::TestSize.Level0)492 HWTEST(LIBZIPARCHIVE, ZipFile, testing::ext::TestSize.Level0)
493 {
494 static const char *data =
495 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat et odio ac sollicitudin. Maecenas "
496 "lobortis ultrices eros sed pharetra. Phasellus in tortor rhoncus, aliquam augue ac, gravida elit. Sed "
497 "molestie dolor a vulputate tincidunt. Proin a tellus quam. Suspendisse id feugiat elit, non ornare lacus. "
498 "Mauris arcu ex, pretium quis dolor ut, porta iaculis eros. Vestibulum sagittis placerat diam, vitae efficitur "
499 "turpis ultrices sit amet. Etiam elementum bibendum congue. In sit amet dolor ultricies, suscipit arcu ac, "
500 "molestie urna. Mauris ultrices volutpat massa quis ultrices. Suspendisse rutrum lectus sit amet metus "
501 "laoreet, non porta sapien venenatis. Fusce ut massa et purus elementum lacinia. Sed tempus bibendum pretium.";
502
503 /*
504 * creating an empty pandafile
505 */
506 std::vector<uint8_t> pf_data {};
507 {
508 pandasm::Parser p;
509
510 auto source = R"()";
511
512 std::string src_filename = "src.pa";
513 auto res = p.Parse(source, src_filename);
514 ASSERT_EQ(p.ShowError().err, pandasm::Error::ErrorType::ERR_NONE);
515
516 auto pf = pandasm::AsmEmitter::Emit(res.Value());
517 ASSERT_NE(pf, nullptr);
518
519 const auto header_ptr = reinterpret_cast<const uint8_t *>(pf->GetHeader());
520 pf_data.assign(header_ptr, header_ptr + sizeof(panda_file::File::Header));
521 }
522
523 static const char *archivename = "__LIBZIPARCHIVE__ZipFile__.zip";
524 const int N = 3;
525 char buf[MAX_BUFFER_SIZE];
526 char archive_filename[MAX_DIR_SIZE];
527 int i = 0;
528 int ret = 0;
529
530 GenerateZipfile(data, archivename, N, buf, archive_filename, i, ret, pf_data);
531
532 // Quick Check
533 ZipArchiveHandle zipfile = nullptr;
534 if (OpenArchive(zipfile, archivename) != 0) {
535 ASSERT_EQ(1, 0) << "OpenArchive error.";
536 return;
537 }
538
539 GlobalStat gi = GlobalStat();
540 if (GetGlobalFileInfo(zipfile, &gi) != 0) {
541 ASSERT_EQ(1, 0) << "GetGlobalFileInfo error.";
542 return;
543 }
544 for (i = 0; i < (int)gi.GetNumberOfEntry(); ++i) {
545 EntryFileStat file_stat;
546 if (GetCurrentFileInfo(zipfile, &file_stat) != 0) {
547 CloseArchive(zipfile);
548 ASSERT_EQ(1, 0) << "GetCurrentFileInfo error. Current index i = " << i;
549 return;
550 }
551 GTEST_COUT << "Index: " << i << ", Uncompressed size: " << file_stat.GetUncompressedSize()
552 << "Compressed size: " << file_stat.GetCompressedSize()
553 << "Compressed(): " << file_stat.IsCompressed() << "entry offset: " << file_stat.GetOffset() << "\n";
554 if ((i + 1) < (int)gi.GetNumberOfEntry()) {
555 if (GoToNextFile(zipfile) != 0) {
556 CloseArchive(zipfile);
557 ASSERT_EQ(1, 0) << "GoToNextFile error. Current index i = " << i;
558 return;
559 }
560 }
561 }
562
563 CloseArchive(zipfile);
564 remove(archivename);
565 GTEST_COUT << "Success.\n";
566 }
567
HWTEST(LIBZIPARCHIVE, UnZipFile, testing::ext::TestSize.Level0)568 HWTEST(LIBZIPARCHIVE, UnZipFile, testing::ext::TestSize.Level0)
569 {
570 static const char *data =
571 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat et odio ac sollicitudin. Maecenas "
572 "lobortis ultrices eros sed pharetra. Phasellus in tortor rhoncus, aliquam augue ac, gravida elit. Sed "
573 "molestie dolor a vulputate tincidunt. Proin a tellus quam. Suspendisse id feugiat elit, non ornare lacus. "
574 "Mauris arcu ex, pretium quis dolor ut, porta iaculis eros. Vestibulum sagittis placerat diam, vitae efficitur "
575 "turpis ultrices sit amet. Etiam elementum bibendum congue. In sit amet dolor ultricies, suscipit arcu ac, "
576 "molestie urna. Mauris ultrices volutpat massa quis ultrices. Suspendisse rutrum lectus sit amet metus "
577 "laoreet, non porta sapien venenatis. Fusce ut massa et purus elementum lacinia. Sed tempus bibendum pretium.";
578
579 /*
580 * creating an empty pandafile
581 */
582 std::vector<uint8_t> pf_data {};
583 {
584 pandasm::Parser p;
585
586 auto source = R"()";
587
588 std::string src_filename = "src.pa";
589 auto res = p.Parse(source, src_filename);
590 ASSERT_EQ(p.ShowError().err, pandasm::Error::ErrorType::ERR_NONE);
591
592 auto pf = pandasm::AsmEmitter::Emit(res.Value());
593 ASSERT_NE(pf, nullptr);
594
595 const auto header_ptr = reinterpret_cast<const uint8_t *>(pf->GetHeader());
596 pf_data.assign(header_ptr, header_ptr + sizeof(panda_file::File::Header));
597 }
598
599 // The zip filename
600 static const char *archivename = "__LIBZIPARCHIVE__UnZipFile__.zip";
601 const int N = 3;
602 char buf[MAX_BUFFER_SIZE];
603 char archive_filename[MAX_DIR_SIZE];
604 char filename[MAX_DIR_SIZE];
605 int i = 0;
606 int ret = 0;
607
608 GenerateZipfile(data, archivename, N, buf, archive_filename, i, ret, pf_data);
609
610 UnzipFileCheckDirectory(archivename, filename);
611
612 UnzipFileCheckTxt(archivename, filename, data, N, buf, ret);
613
614 UnzipFileCheckInDirectory(archivename, filename, data, N, buf, ret);
615
616 sprintf_s(filename, MAX_DIR_SIZE, "classes.abc");
617 UnzipFileCheckPandaFile(archivename, filename, pf_data, ret);
618
619 remove(archivename);
620 GTEST_COUT << "Success.\n";
621 }
622
HWTEST(LIBZIPARCHIVE, UnZipUncompressedFile, testing::ext::TestSize.Level0)623 HWTEST(LIBZIPARCHIVE, UnZipUncompressedFile, testing::ext::TestSize.Level0)
624 {
625 static const char *data =
626 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras feugiat et odio ac sollicitudin. Maecenas "
627 "lobortis ultrices eros sed pharetra. Phasellus in tortor rhoncus, aliquam augue ac, gravida elit. Sed "
628 "molestie dolor a vulputate tincidunt. Proin a tellus quam. Suspendisse id feugiat elit, non ornare lacus. "
629 "Mauris arcu ex, pretium quis dolor ut, porta iaculis eros. Vestibulum sagittis placerat diam, vitae efficitur "
630 "turpis ultrices sit amet. Etiam elementum bibendum congue. In sit amet dolor ultricies, suscipit arcu ac, "
631 "molestie urna. Mauris ultrices volutpat massa quis ultrices. Suspendisse rutrum lectus sit amet metus "
632 "laoreet, non porta sapien venenatis. Fusce ut massa et purus elementum lacinia. Sed tempus bibendum pretium.";
633
634 /*
635 * creating an empty pandafile
636 */
637 std::vector<uint8_t> pf_data {};
638 {
639 pandasm::Parser p;
640
641 auto source = R"()";
642
643 std::string src_filename = "src.pa";
644 auto res = p.Parse(source, src_filename);
645 ASSERT_EQ(p.ShowError().err, pandasm::Error::ErrorType::ERR_NONE);
646
647 auto pf = pandasm::AsmEmitter::Emit(res.Value());
648 ASSERT_NE(pf, nullptr);
649
650 const auto header_ptr = reinterpret_cast<const uint8_t *>(pf->GetHeader());
651 pf_data.assign(header_ptr, header_ptr + sizeof(panda_file::File::Header));
652 }
653
654 // The zip filename
655 static const char *archivename = "__LIBZIPARCHIVE__UnZipUncompressedFile__.zip";
656 const int N = 3;
657 char buf[MAX_BUFFER_SIZE];
658 char archive_filename[MAX_DIR_SIZE];
659 char filename[MAX_DIR_SIZE];
660 int i = 0;
661 int ret = 0;
662
663 GenerateZipfile(data, archivename, N, buf, archive_filename, i, ret, pf_data, Z_NO_COMPRESSION);
664
665 UnzipFileCheckDirectory(archivename, filename, Z_NO_COMPRESSION);
666
667 UnzipFileCheckTxt(archivename, filename, data, N, buf, ret, Z_NO_COMPRESSION);
668
669 UnzipFileCheckInDirectory(archivename, filename, data, N, buf, ret, Z_NO_COMPRESSION);
670
671 (void)sprintf_s(filename, MAX_DIR_SIZE, "classes.abc");
672 UnzipFileCheckPandaFile(archivename, filename, pf_data, ret, Z_NO_COMPRESSION);
673
674 remove(archivename);
675 GTEST_COUT << "Success.\n";
676 }
677
HWTEST(LIBZIPARCHIVE, UnZipUncompressedPandaFile, testing::ext::TestSize.Level0)678 HWTEST(LIBZIPARCHIVE, UnZipUncompressedPandaFile, testing::ext::TestSize.Level0)
679 {
680 /*
681 * creating an empty pandafile
682 */
683 std::vector<uint8_t> pf_data {};
684 {
685 pandasm::Parser p;
686
687 auto source = R"()";
688
689 std::string src_filename = "src.pa";
690 auto res = p.Parse(source, src_filename);
691 ASSERT_EQ(p.ShowError().err, pandasm::Error::ErrorType::ERR_NONE);
692
693 auto pf = pandasm::AsmEmitter::Emit(res.Value());
694 ASSERT_NE(pf, nullptr);
695
696 const auto header_ptr = reinterpret_cast<const uint8_t *>(pf->GetHeader());
697 pf_data.assign(header_ptr, header_ptr + sizeof(panda_file::File::Header));
698 }
699
700 // The zip filename
701 static const char *archivename = "__LIBZIPARCHIVE__UnZipUncompressedPandaFile__.zip";
702 char filename[MAX_DIR_SIZE];
703 int ret = 0;
704
705 // Delete the test archive, so it doesn't keep growing as we run this test
706 remove(archivename);
707
708 // Add pandafile into zip for testing
709 ret = CreateOrAddFileIntoZip(archivename, "class.abc", pf_data.data(), pf_data.size(), APPEND_STATUS_CREATE,
710 Z_NO_COMPRESSION);
711 if (ret != 0) {
712 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip failed!";
713 return;
714 }
715 ret = CreateOrAddFileIntoZip(archivename, "classes.abc", pf_data.data(), pf_data.size(), APPEND_STATUS_ADDINZIP,
716 Z_NO_COMPRESSION);
717 if (ret != 0) {
718 ASSERT_EQ(1, 0) << "CreateOrAddFileIntoZip failed!";
719 return;
720 }
721
722 sprintf_s(filename, MAX_DIR_SIZE, "class.abc");
723 UnzipFileCheckPandaFile(archivename, filename, pf_data, ret, Z_NO_COMPRESSION);
724 sprintf_s(filename, MAX_DIR_SIZE, "classes.abc");
725 UnzipFileCheckPandaFile(archivename, filename, pf_data, ret, Z_NO_COMPRESSION);
726
727 remove(archivename);
728 GTEST_COUT << "Success.\n";
729 }
730
HWTEST(LIBZIPARCHIVE, IllegalPathTest, testing::ext::TestSize.Level0)731 HWTEST(LIBZIPARCHIVE, IllegalPathTest, testing::ext::TestSize.Level0)
732 {
733 static const char *archivename = "__LIBZIPARCHIVE__ILLEGALPATHTEST__.zip";
734 int ret = CreateOrAddFileIntoZip(archivename, "illegal_path.abc", nullptr, 0, APPEND_STATUS_ADDINZIP,
735 Z_NO_COMPRESSION);
736 ASSERT_EQ(ret, ZIPARCHIVE_ERR);
737 ZipArchiveHandle zipfile = nullptr;
738 ASSERT_EQ(OpenArchive(zipfile, archivename), ZIPARCHIVE_ERR);
739 GlobalStat gi = GlobalStat();
740 ASSERT_EQ(GetGlobalFileInfo(zipfile, &gi), ZIPARCHIVE_ERR);
741 ASSERT_EQ(GoToNextFile(zipfile), ZIPARCHIVE_ERR);
742 ASSERT_EQ(LocateFile(zipfile, "illegal_path.abc"), ZIPARCHIVE_ERR);
743 EntryFileStat entry = EntryFileStat();
744 ASSERT_EQ(GetCurrentFileInfo(zipfile, &entry), ZIPARCHIVE_ERR);
745 ASSERT_EQ(CloseArchive(zipfile), ZIPARCHIVE_ERR);
746
747 ASSERT_EQ(OpenArchiveFile(zipfile, nullptr), ZIPARCHIVE_ERR);
748 ASSERT_EQ(OpenCurrentFile(zipfile), ZIPARCHIVE_ERR);
749 ASSERT_EQ(CloseCurrentFile(zipfile), ZIPARCHIVE_ERR);
750 ASSERT_EQ(CloseArchiveFile(zipfile), ZIPARCHIVE_ERR);
751 }
752 } // namespace panda::test
753