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_file.h"
17 
18 #include <ostream>
19 
20 #include "app_log_wrapper.h"
21 #include "bundle_service_constants.h"
22 #include "securec.h"
23 
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 constexpr uint32_t MAX_FILE_PATH = 4096;
28 constexpr uint32_t UNZIP_BUFFER_SIZE = 1024;
29 constexpr uint32_t UNZIP_BUF_IN_LEN = 160 * UNZIP_BUFFER_SIZE;   // in  buffer length: 160KB
30 constexpr uint32_t UNZIP_BUF_OUT_LEN = 320 * UNZIP_BUFFER_SIZE;  // out buffer length: 320KB
31 constexpr uint32_t LOCAL_HEADER_SIGNATURE = 0x04034b50;
32 constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50;
33 constexpr uint32_t EOCD_SIGNATURE = 0x06054b50;
34 constexpr uint32_t DATA_DESC_SIGNATURE = 0x08074b50;
35 constexpr uint32_t FLAG_DATA_DESC = 0x8;
36 constexpr size_t FILE_READ_COUNT = 1;
37 constexpr uint8_t INFLATE_ERROR_TIMES = 5;
38 }  // namespace
39 
ZipEntry(const CentralDirEntry & centralEntry)40 ZipEntry::ZipEntry(const CentralDirEntry &centralEntry)
41 {
42     compressionMethod = centralEntry.compressionMethod;
43     uncompressedSize = centralEntry.uncompressedSize;
44     compressedSize = centralEntry.compressedSize;
45     localHeaderOffset = centralEntry.localHeaderOffset;
46     crc = centralEntry.crc;
47     flags = centralEntry.flags;
48 }
49 
ZipFile(const std::string & pathName)50 ZipFile::ZipFile(const std::string &pathName) : pathName_(pathName)
51 {
52     APP_LOGD("create instance from %{private}s", pathName_.c_str());
53 }
54 
~ZipFile()55 ZipFile::~ZipFile()
56 {
57     Close();
58 }
59 
SetContentLocation(const ZipPos start,const size_t length)60 void ZipFile::SetContentLocation(const ZipPos start, const size_t length)
61 {
62     APP_LOGD("set content location start position(%{public}llu), length(%{public}zu)", start, length);
63     fileStartPos_ = start;
64     fileLength_ = length;
65 }
66 
CheckEndDir(const EndDir & endDir) const67 bool ZipFile::CheckEndDir(const EndDir &endDir) const
68 {
69     size_t lenEndDir = sizeof(EndDir);
70     if ((endDir.numDisk != 0) || (endDir.signature != EOCD_SIGNATURE) || (endDir.startDiskOfCentralDir != 0) ||
71         (endDir.offset >= fileLength_) || (endDir.totalEntriesInThisDisk != endDir.totalEntries) ||
72         (endDir.commentLen != 0) ||
73         // central dir can't overlap end of central dir
74         ((endDir.offset + endDir.sizeOfCentralDir + lenEndDir) > fileLength_)) {
75         APP_LOGE("end dir format error");
76         return false;
77     }
78     return true;
79 }
80 
ParseEndDirectory()81 bool ZipFile::ParseEndDirectory()
82 {
83     size_t endDirLen = sizeof(EndDir);
84     size_t endFilePos = fileStartPos_ + fileLength_;
85 
86     if (fileLength_ <= endDirLen) {
87         APP_LOGE("parse EOCD file length(%{public}llu) <= end dir length(%{public}llu)", fileStartPos_, fileLength_);
88         return false;
89     }
90 
91     size_t eocdPos = endFilePos - endDirLen;
92     if (fseek(file_, eocdPos, SEEK_SET) != 0) {
93         APP_LOGE("locate EOCD seek failed, error: %{public}d", errno);
94         return false;
95     }
96 
97     if (fread(&endDir_, sizeof(EndDir), FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
98         APP_LOGE("read EOCD struct failed, error: %{public}d", errno);
99         return false;
100     }
101 
102     centralDirPos_ = endDir_.offset + fileStartPos_;
103     APP_LOGD("parse EOCD offset(0x%{public}08x) file start position(0x%{public}08llx)", endDir_.offset, fileStartPos_);
104 
105     return CheckEndDir(endDir_);
106 }
107 
ParseAllEntries()108 bool ZipFile::ParseAllEntries()
109 {
110     bool ret = true;
111     ZipPos currentPos = centralDirPos_;
112     CentralDirEntry directoryEntry = {0};
113 
114     for (uint16_t i = 0; i < endDir_.totalEntries; i++) {
115         std::string fileName;
116         fileName.reserve(MAX_FILE_PATH);
117         fileName.resize(MAX_FILE_PATH - 1);
118 
119         if (fseek(file_, currentPos, SEEK_SET) != 0) {
120             APP_LOGE("parse entry(%{public}d) seek zipEntry failed, error: %{public}d", i, errno);
121             ret = false;
122             break;
123         }
124 
125         if (fread(&directoryEntry, sizeof(CentralDirEntry), FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
126             APP_LOGE("parse entry(%{public}d) read ZipEntry failed, error: %{public}d", i, errno);
127             ret = false;
128             break;
129         }
130 
131         if (directoryEntry.signature != CENTRAL_SIGNATURE) {
132             APP_LOGE("parse entry(%{public}d) check signature(0x%08x) at pos(0x%08llx) failed",
133                 i,
134                 directoryEntry.signature,
135                 currentPos);
136             ret = false;
137             break;
138         }
139 
140         size_t fileLength = (directoryEntry.nameSize >= MAX_FILE_PATH) ? (MAX_FILE_PATH - 1) : directoryEntry.nameSize;
141         if (fread(&(fileName[0]), fileLength, FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
142             APP_LOGE("parse entry(%{public}d) read file name failed, error: %{public}d", i, errno);
143             ret = false;
144             break;
145         }
146         fileName.resize(fileLength);
147 
148         ZipEntry currentEntry(directoryEntry);
149         currentEntry.fileName = fileName;
150         entriesMap_[fileName] = currentEntry;
151 
152         currentPos += sizeof(directoryEntry);
153         currentPos += directoryEntry.nameSize + directoryEntry.extraSize + directoryEntry.commentSize;
154     }
155 
156     APP_LOGD("parse %{public}d central entries from %{private}s", endDir_.totalEntries, pathName_.c_str());
157     return ret;
158 }
159 
Open()160 bool ZipFile::Open()
161 {
162     APP_LOGD("open: %{private}s", pathName_.c_str());
163 
164     if (isOpen_) {
165         APP_LOGE("has already opened");
166         return true;
167     }
168 
169     if (pathName_.length() > PATH_MAX) {
170         APP_LOGE("path length(%{public}u) longer than max length(%{public}d)",
171             static_cast<unsigned int>(pathName_.length()),
172             PATH_MAX);
173         return false;
174     }
175     std::string realPath;
176     realPath.reserve(PATH_MAX);
177     realPath.resize(PATH_MAX - 1);
178     if (realpath(pathName_.c_str(), &(realPath[0])) == nullptr) {
179         APP_LOGE("transform real path error: %{public}d", errno);
180         return false;
181     }
182 
183     FILE *tmpFile = fopen(realPath.c_str(), "rb");
184     if (tmpFile == nullptr) {
185         APP_LOGE("open file(%{private}s) failed, error: %{public}d", pathName_.c_str(), errno);
186         return false;
187     }
188 
189     if (fileLength_ == 0) {
190         if (fseek(tmpFile, 0, SEEK_END) != 0) {
191             APP_LOGE("file seek failed, error: %{public}d", errno);
192             fclose(tmpFile);
193             return false;
194         }
195         int64_t fileLength = ftell(tmpFile);
196         if (fileLength == -1) {
197             APP_LOGE("open file %{private}s failed", pathName_.c_str());
198             fclose(tmpFile);
199             return false;
200         }
201         fileLength_ = static_cast<ZipPos>(fileLength);
202         if (fileStartPos_ >= fileLength_) {
203             APP_LOGE("open start pos > length failed");
204             fclose(tmpFile);
205             return false;
206         }
207 
208         fileLength_ -= fileStartPos_;
209     }
210 
211     file_ = tmpFile;
212     bool result = ParseEndDirectory();
213     if (result) {
214         result = ParseAllEntries();
215     }
216     // it means open file success.
217     isOpen_ = true;
218     return result;
219 }
220 
Close()221 void ZipFile::Close()
222 {
223     APP_LOGD("close: %{private}s", pathName_.c_str());
224 
225     if (!isOpen_ || file_ == nullptr) {
226         APP_LOGW("file is not opened");
227         return;
228     }
229 
230     entriesMap_.clear();
231     pathName_ = "";
232     isOpen_ = false;
233 
234     if (fclose(file_) != 0) {
235         APP_LOGW("close failed err: %{public}d", errno);
236     }
237     file_ = nullptr;
238 }
239 
240 // Get all file zipEntry in this file
GetAllEntries() const241 const ZipEntryMap &ZipFile::GetAllEntries() const
242 {
243     return entriesMap_;
244 }
245 
HasEntry(const std::string & entryName) const246 bool ZipFile::HasEntry(const std::string &entryName) const
247 {
248     return entriesMap_.find(entryName) != entriesMap_.end();
249 }
250 
IsDirExist(const std::string & dir) const251 bool ZipFile::IsDirExist(const std::string &dir) const
252 {
253     APP_LOGD("target dir: %{public}s", dir.c_str());
254     if (dir.empty()) {
255         APP_LOGE("target dir is empty");
256         return false;
257     }
258 
259     auto tempDir = dir;
260     if (tempDir.back() != ServiceConstants::FILE_SEPARATOR_CHAR) {
261         tempDir.push_back(ServiceConstants::FILE_SEPARATOR_CHAR);
262     }
263 
264     for (const auto &item : entriesMap_) {
265         if (item.first.find(tempDir) == 0) {
266             APP_LOGD("find target dir, fileName : %{public}s", item.first.c_str());
267             return true;
268         }
269     }
270     APP_LOGD("target dir not found, dir : %{public}s", dir.c_str());
271     return false;
272 }
273 
GetEntry(const std::string & entryName,ZipEntry & resultEntry) const274 bool ZipFile::GetEntry(const std::string &entryName, ZipEntry &resultEntry) const
275 {
276     APP_LOGD("get entry by name: %{public}s", entryName.c_str());
277     auto iter = entriesMap_.find(entryName);
278     if (iter != entriesMap_.end()) {
279         resultEntry = iter->second;
280         APP_LOGD("get entry succeed");
281         return true;
282     }
283     APP_LOGE("get entry failed");
284     return false;
285 }
286 
GetLocalHeaderSize(const uint16_t nameSize,const uint16_t extraSize) const287 size_t ZipFile::GetLocalHeaderSize(const uint16_t nameSize, const uint16_t extraSize) const
288 {
289     return sizeof(LocalHeader) + nameSize + extraSize;
290 }
291 
CheckDataDesc(const ZipEntry & zipEntry,const LocalHeader & localHeader) const292 bool ZipFile::CheckDataDesc(const ZipEntry &zipEntry, const LocalHeader &localHeader) const
293 {
294     uint32_t crcLocal = 0;
295     uint32_t compressedLocal = 0;
296     uint32_t uncompressedLocal = 0;
297 
298     if (localHeader.flags & FLAG_DATA_DESC) {  // use data desc
299         DataDesc dataDesc;
300         auto descPos = zipEntry.localHeaderOffset + GetLocalHeaderSize(localHeader.nameSize, localHeader.extraSize);
301         descPos += fileStartPos_ + zipEntry.compressedSize;
302 
303         if (fseek(file_, descPos, SEEK_SET) != 0) {
304             APP_LOGE("check local header seek datadesc failed, error: %{public}d", errno);
305             return false;
306         }
307 
308         if (fread(&dataDesc, sizeof(DataDesc), FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
309             APP_LOGE("check local header read datadesc failed, error: %{public}d", errno);
310             return false;
311         }
312 
313         if (dataDesc.signature != DATA_DESC_SIGNATURE) {
314             APP_LOGE("check local header check datadesc signature failed");
315             return false;
316         }
317 
318         crcLocal = dataDesc.crc;
319         compressedLocal = dataDesc.compressedSize;
320         uncompressedLocal = dataDesc.uncompressedSize;
321     } else {
322         crcLocal = localHeader.crc;
323         compressedLocal = localHeader.compressedSize;
324         uncompressedLocal = localHeader.uncompressedSize;
325     }
326 
327     if ((zipEntry.crc != crcLocal) || (zipEntry.compressedSize != compressedLocal) ||
328         (zipEntry.uncompressedSize != uncompressedLocal)) {
329         APP_LOGE("check local header compressed size corrupted");
330         return false;
331     }
332 
333     return true;
334 }
335 
CheckCoherencyLocalHeader(const ZipEntry & zipEntry,uint16_t & extraSize) const336 bool ZipFile::CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const
337 {
338     LocalHeader localHeader = {0};
339 
340     if (zipEntry.localHeaderOffset >= fileLength_) {
341         APP_LOGE("check local file header offset overflow %{public}d", zipEntry.localHeaderOffset);
342         return false;
343     }
344 
345     if (fseek(file_, fileStartPos_ + zipEntry.localHeaderOffset, SEEK_SET) != 0) {
346         APP_LOGE("check local header seek failed, error: %{public}d", errno);
347         return false;
348     }
349 
350     if (fread(&localHeader, sizeof(LocalHeader), FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
351         APP_LOGE("check local header read localheader failed, error: %{public}d", errno);
352         return false;
353     }
354 
355     if ((localHeader.signature != LOCAL_HEADER_SIGNATURE) ||
356         (zipEntry.compressionMethod != localHeader.compressionMethod)) {
357         APP_LOGE("check local header signature or compressionMethod failed");
358         return false;
359     }
360 
361     // current only support store and Z_DEFLATED method
362     if ((zipEntry.compressionMethod != Z_DEFLATED) && (zipEntry.compressionMethod != 0)) {
363         APP_LOGE("check local header compressionMethod(%{public}d) not support", zipEntry.compressionMethod);
364         return false;
365     }
366 
367     std::string fileName;
368     fileName.reserve(MAX_FILE_PATH);
369     fileName.resize(MAX_FILE_PATH - 1);
370     size_t fileLength = (localHeader.nameSize >= MAX_FILE_PATH) ? (MAX_FILE_PATH - 1) : localHeader.nameSize;
371     if (fileLength != zipEntry.fileName.length()) {
372         APP_LOGE("check local header file name size failed");
373         return false;
374     }
375     if (fread(&(fileName[0]), fileLength, FILE_READ_COUNT, file_) != FILE_READ_COUNT) {
376         APP_LOGE("check local header read file name failed, error: %{public}d", errno);
377         return false;
378     }
379     fileName.resize(fileLength);
380     if (zipEntry.fileName != fileName) {
381         APP_LOGE("check local header file name corrupted");
382         return false;
383     }
384 
385     if (!CheckDataDesc(zipEntry, localHeader)) {
386         APP_LOGE("check data desc failed");
387         return false;
388     }
389 
390     extraSize = localHeader.extraSize;
391     return true;
392 }
393 
SeekToEntryStart(const ZipEntry & zipEntry,const uint16_t extraSize) const394 bool ZipFile::SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSize) const
395 {
396     ZipPos startOffset = zipEntry.localHeaderOffset;
397     // get data offset, add signature+localheader+namesize+extrasize
398     startOffset += GetLocalHeaderSize(zipEntry.fileName.length(), extraSize);
399     if (startOffset + zipEntry.compressedSize > fileLength_) {
400         APP_LOGE("startOffset(%{public}lld)+entryCompressedSize(%{public}ud) > fileLength(%{public}llu)",
401             startOffset,
402             zipEntry.compressedSize,
403             fileLength_);
404         return false;
405     }
406     startOffset += fileStartPos_;  // add file start relative to file stream
407 
408     APP_LOGD("seek to entry start 0x%{public}08llx", startOffset);
409     if (fseek(file_, startOffset, SEEK_SET) != 0) {
410         APP_LOGE("seek failed, error: %{public}d", errno);
411         return false;
412     }
413     return true;
414 }
415 
UnzipWithStore(const ZipEntry & zipEntry,const uint16_t extraSize,std::ostream & dest) const416 bool ZipFile::UnzipWithStore(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const
417 {
418     APP_LOGD("unzip with store");
419 
420     if (!SeekToEntryStart(zipEntry, extraSize)) {
421         APP_LOGE("seek to entry start failed");
422         return false;
423     }
424 
425     uint32_t remainSize = zipEntry.compressedSize;
426     std::string readBuffer;
427     readBuffer.reserve(UNZIP_BUF_OUT_LEN);
428     readBuffer.resize(UNZIP_BUF_OUT_LEN - 1);
429     while (remainSize > 0) {
430         size_t readBytes;
431         size_t readLen = (remainSize > UNZIP_BUF_OUT_LEN) ? UNZIP_BUF_OUT_LEN : remainSize;
432         readBytes = fread(&(readBuffer[0]), sizeof(Byte), readLen, file_);
433         if (readBytes == 0) {
434             APP_LOGE("unzip store read failed, error: %{public}d", ferror(file_));
435             return false;
436         }
437         remainSize -= readBytes;
438         dest.write(&(readBuffer[0]), readBytes);
439     }
440 
441     return true;
442 }
443 
InitZStream(z_stream & zstream) const444 bool ZipFile::InitZStream(z_stream &zstream) const
445 {
446     // init zlib stream
447     if (memset_s(&zstream, sizeof(z_stream), 0, sizeof(z_stream))) {
448         APP_LOGE("unzip stream buffer init failed");
449         return false;
450     }
451     int32_t zlibErr = inflateInit2(&zstream, -MAX_WBITS);
452     if (zlibErr != Z_OK) {
453         APP_LOGE("unzip inflated init failed");
454         return false;
455     }
456 
457     BytePtr bufOut = new (std::nothrow) Byte[UNZIP_BUF_OUT_LEN];
458     if (bufOut == nullptr) {
459         APP_LOGE("unzip inflated new out buffer failed");
460         return false;
461     }
462 
463     BytePtr bufIn = new (std::nothrow) Byte[UNZIP_BUF_IN_LEN];
464     if (bufIn == nullptr) {
465         APP_LOGE("unzip inflated new in buffer failed");
466         delete[] bufOut;
467         return false;
468     }
469     zstream.next_out = bufOut;
470     zstream.next_in = bufIn;
471     zstream.avail_out = UNZIP_BUF_OUT_LEN;
472     return true;
473 }
474 
ReadZStream(const BytePtr & buffer,z_stream & zstream,uint32_t & remainCompressedSize) const475 bool ZipFile::ReadZStream(const BytePtr &buffer, z_stream &zstream, uint32_t &remainCompressedSize) const
476 {
477     if (zstream.avail_in == 0) {
478         size_t readBytes;
479         size_t remainBytes = (remainCompressedSize > UNZIP_BUF_IN_LEN) ? UNZIP_BUF_IN_LEN : remainCompressedSize;
480         readBytes = fread(buffer, sizeof(Byte), remainBytes, file_);
481         if (readBytes == 0) {
482             APP_LOGE("unzip inflated read failed, error: %{public}d", ferror(file_));
483             return false;
484         }
485 
486         remainCompressedSize -= readBytes;
487         zstream.avail_in = readBytes;
488         zstream.next_in = buffer;
489     }
490     return true;
491 }
492 
UnzipWithInflated(const ZipEntry & zipEntry,const uint16_t extraSize,std::ostream & dest) const493 bool ZipFile::UnzipWithInflated(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const
494 {
495     APP_LOGD("unzip with inflated");
496 
497     z_stream zstream;
498     if (!SeekToEntryStart(zipEntry, extraSize) || !InitZStream(zstream)) {
499         return false;
500     }
501 
502     BytePtr bufIn = zstream.next_in;
503     BytePtr bufOut = zstream.next_out;
504 
505     bool ret = true;
506     int32_t zlibErr = Z_OK;
507     uint32_t remainCompressedSize = zipEntry.compressedSize;
508     uint8_t errorTimes = 0;
509     while ((remainCompressedSize > 0) || (zstream.avail_in > 0)) {
510         if (!ReadZStream(bufIn, zstream, remainCompressedSize)) {
511             ret = false;
512             break;
513         }
514 
515         zlibErr = inflate(&zstream, Z_SYNC_FLUSH);
516         if ((zlibErr >= Z_OK) && (zstream.msg != nullptr)) {
517             APP_LOGE("unzip inflated inflate, error: %{public}d, err msg: %{public}s", zlibErr, zstream.msg);
518             ret = false;
519             break;
520         }
521 
522         size_t inflateLen = UNZIP_BUF_OUT_LEN - zstream.avail_out;
523         if (inflateLen > 0) {
524             dest.write(reinterpret_cast<const char *>(bufOut), inflateLen);
525             zstream.next_out = bufOut;
526             zstream.avail_out = UNZIP_BUF_OUT_LEN;
527             errorTimes = 0;
528         } else {
529             errorTimes++;
530         }
531         if (errorTimes >= INFLATE_ERROR_TIMES) {
532             APP_LOGE("unzip inflated data is abnormal");
533             ret = false;
534             break;
535         }
536     }
537 
538     // free all dynamically allocated data structures except the next_in and next_out for this stream.
539     zlibErr = inflateEnd(&zstream);
540     if (zlibErr != Z_OK) {
541         APP_LOGE("unzip inflateEnd error %{public}d", zlibErr);
542         ret = false;
543     }
544 
545     delete[] bufOut;
546     delete[] bufIn;
547     return ret;
548 }
549 
GetEntryDataOffset(const ZipEntry & zipEntry,const uint16_t extraSize) const550 ZipPos ZipFile::GetEntryDataOffset(const ZipEntry &zipEntry, const uint16_t extraSize) const
551 {
552     // get entry data offset relative file
553     ZipPos offset = zipEntry.localHeaderOffset;
554 
555     offset += GetLocalHeaderSize(zipEntry.fileName.length(), extraSize);
556     offset += fileStartPos_;
557 
558     return offset;
559 }
560 
GetDataOffsetRelative(const std::string & file,ZipPos & offset,uint32_t & length) const561 bool ZipFile::GetDataOffsetRelative(const std::string &file, ZipPos &offset, uint32_t &length) const
562 {
563     APP_LOGD("get data relative offset for file %{private}s", file.c_str());
564 
565     ZipEntry zipEntry;
566     if (!GetEntry(file, zipEntry)) {
567         APP_LOGE("extract file: not find file");
568         return false;
569     }
570 
571     uint16_t extraSize = 0;
572     if (!CheckCoherencyLocalHeader(zipEntry, extraSize)) {
573         APP_LOGE("check coherency local header failed");
574         return false;
575     }
576 
577     offset = GetEntryDataOffset(zipEntry, extraSize);
578     length = zipEntry.compressedSize;
579     return true;
580 }
581 
ExtractFile(const std::string & file,std::ostream & dest) const582 bool ZipFile::ExtractFile(const std::string &file, std::ostream &dest) const
583 {
584     APP_LOGD("extract file %{private}s", file.c_str());
585 
586     ZipEntry zipEntry;
587     if (!GetEntry(file, zipEntry)) {
588         APP_LOGE("extract file: not find file");
589         return false;
590     }
591 
592     uint16_t extraSize = 0;
593     if (!CheckCoherencyLocalHeader(zipEntry, extraSize)) {
594         APP_LOGE("check coherency local header failed");
595         return false;
596     }
597 
598     bool ret = true;
599     if (zipEntry.compressionMethod == 0) {
600         ret = UnzipWithStore(zipEntry, extraSize, dest);
601     } else {
602         ret = UnzipWithInflated(zipEntry, extraSize, dest);
603     }
604 
605     return ret;
606 }
607 }  // namespace AppExecFwk
608 }  // namespace OHOS
609