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 "os/file.h"
18 #include "utils/logger.h"
19
20 #include <securec.h>
21
22 namespace panda {
23
24 constexpr size_t ZIP_MAGIC_MASK = 0xff;
25 constexpr size_t ZIP_MAGIC_OFFSET = 8U;
26
IsZipMagic(uint32_t magic)27 bool IsZipMagic(uint32_t magic)
28 {
29 return ((((magic >> 0U) & ZIP_MAGIC_MASK) == 'P') && (((magic >> ZIP_MAGIC_OFFSET) & ZIP_MAGIC_MASK) == 'K'));
30 }
31
OpenArchive(ZipArchiveHandle & handle,const char * path)32 int OpenArchive(ZipArchiveHandle &handle, const char *path)
33 {
34 handle = unzOpen(path);
35 if (handle == nullptr) {
36 LOG(ERROR, ZIPARCHIVE) << "OpenArchive failed, filename is " << path;
37 return ZIPARCHIVE_ERR;
38 }
39 return ZIPARCHIVE_OK;
40 }
41
OpenArchiveFile(ZipArchiveHandle & handle,FILE * fp)42 int OpenArchiveFile(ZipArchiveHandle &handle, FILE *fp)
43 {
44 handle = unzOpenFile(fp);
45 if (handle == nullptr) {
46 LOG(ERROR, ZIPARCHIVE) << "OpenArchive failed from FILE *fp";
47 return ZIPARCHIVE_ERR;
48 }
49 return ZIPARCHIVE_OK;
50 }
51
CloseArchive(ZipArchiveHandle & handle)52 int CloseArchive(ZipArchiveHandle &handle)
53 {
54 if (handle == nullptr) {
55 LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
56 return ZIPARCHIVE_ERR;
57 }
58 int err = unzClose(handle);
59 if (err != UNZ_OK) {
60 LOG(ERROR, ZIPARCHIVE) << "unzClose with error: " << err;
61 return ZIPARCHIVE_ERR;
62 }
63 return ZIPARCHIVE_OK;
64 }
65
CloseArchiveFile(ZipArchiveHandle & handle)66 int CloseArchiveFile(ZipArchiveHandle &handle)
67 {
68 if (handle == nullptr) {
69 LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
70 return ZIPARCHIVE_ERR;
71 }
72 int err = unzCloseFile(handle);
73 if (err != UNZ_OK) {
74 LOG(ERROR, ZIPARCHIVE) << "unzCloseFile with error: " << err;
75 return ZIPARCHIVE_ERR;
76 }
77 return ZIPARCHIVE_OK;
78 }
79
GetGlobalFileInfo(ZipArchiveHandle & handle,GlobalStat * gstat)80 int GetGlobalFileInfo(ZipArchiveHandle &handle, GlobalStat *gstat)
81 {
82 int err = unzGetGlobalInfo(handle, &gstat->ginfo);
83 if (err != UNZ_OK) {
84 LOG(ERROR, ZIPARCHIVE) << "GetGlobalFileInfo with error: " << err;
85 return ZIPARCHIVE_ERR;
86 }
87 return ZIPARCHIVE_OK;
88 }
89
GoToNextFile(ZipArchiveHandle & handle)90 int GoToNextFile(ZipArchiveHandle &handle)
91 {
92 int err = unzGoToNextFile(handle);
93 if (err != UNZ_OK) {
94 LOG(ERROR, ZIPARCHIVE) << "GoToNextFile with error: " << err;
95 return ZIPARCHIVE_ERR;
96 }
97 return ZIPARCHIVE_OK;
98 }
99
LocateFile(ZipArchiveHandle & handle,const char * filename)100 int LocateFile(ZipArchiveHandle &handle, const char *filename)
101 {
102 int err = unzLocateFile2(handle, filename, 0);
103 if (err != UNZ_OK) {
104 LOG(ERROR, ZIPARCHIVE) << filename << " is not found in the zipfile";
105 return ZIPARCHIVE_ERR;
106 }
107 return ZIPARCHIVE_OK;
108 }
109
GetCurrentFileInfo(ZipArchiveHandle & handle,EntryFileStat * entry)110 int GetCurrentFileInfo(ZipArchiveHandle &handle, EntryFileStat *entry)
111 {
112 int err = unzGetCurrentFileInfo(handle, &entry->file_stat, nullptr, 0, nullptr, 0, nullptr, 0);
113 if (err != UNZ_OK) {
114 LOG(ERROR, ZIPARCHIVE) << "unzGetCurrentFileInfo failed!";
115 return ZIPARCHIVE_ERR;
116 }
117 return ZIPARCHIVE_OK;
118 }
119
OpenCurrentFile(ZipArchiveHandle & handle)120 int OpenCurrentFile(ZipArchiveHandle &handle)
121 {
122 int err = unzOpenCurrentFile(handle);
123 if (err != UNZ_OK) {
124 LOG(ERROR, ZIPARCHIVE) << "OpenCurrentFile failed!";
125 return ZIPARCHIVE_ERR;
126 }
127 return ZIPARCHIVE_OK;
128 }
129
GetCurrentFileOffset(ZipArchiveHandle & handle,EntryFileStat * entry)130 void GetCurrentFileOffset(ZipArchiveHandle &handle, EntryFileStat *entry)
131 {
132 entry->offset = static_cast<uint32_t>(unzGetCurrentFileZStreamPos64(handle));
133 }
134
CloseCurrentFile(ZipArchiveHandle & handle)135 int CloseCurrentFile(ZipArchiveHandle &handle)
136 {
137 int err = unzCloseCurrentFile(handle);
138 if (err != UNZ_OK) {
139 LOG(ERROR, ZIPARCHIVE) << "CloseCurrentFile failed!";
140 return ZIPARCHIVE_ERR;
141 }
142 return ZIPARCHIVE_OK;
143 }
144
ExtractToMemory(ZipArchiveHandle & handle,void * buf,size_t buf_size)145 int ExtractToMemory(ZipArchiveHandle &handle, void *buf, size_t buf_size)
146 {
147 int size = unzReadCurrentFile(handle, buf, buf_size);
148 if (size < 0) {
149 LOG(ERROR, ZIPARCHIVE) << "ExtractToMemory failed!";
150 return ZIPARCHIVE_ERR;
151 }
152 LOG(INFO, ZIPARCHIVE) << "ExtractToMemory size is " << size;
153 return ZIPARCHIVE_OK;
154 }
155
CreateOrAddFileIntoZip(const char * zipname,const char * filename,const void * pbuf,size_t buf_size,int append,int level)156 int CreateOrAddFileIntoZip(const char *zipname, const char *filename, const void *pbuf, size_t buf_size, int append,
157 int level)
158 {
159 zipFile zfile = nullptr;
160 zfile = zipOpen(zipname, append);
161 if (zfile == nullptr) {
162 LOG(ERROR, ZIPARCHIVE) << "CreateArchive failed, zipname is " << zipname;
163 return ZIPARCHIVE_ERR;
164 }
165 int success = ZIPARCHIVE_OK;
166 int err = zipOpenNewFileInZip(zfile, filename, nullptr, nullptr, 0, nullptr, 0, nullptr,
167 (level != 0) ? Z_DEFLATED : 0, level);
168 if (err != UNZ_OK) {
169 LOG(ERROR, ZIPARCHIVE) << "zipOpenNewFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
170 return ZIPARCHIVE_ERR;
171 }
172 err = zipWriteInFileInZip(zfile, pbuf, buf_size);
173 if (err != UNZ_OK) {
174 LOG(ERROR, ZIPARCHIVE) << "zipWriteInFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
175 success = ZIPARCHIVE_ERR;
176 }
177 err = zipCloseFileInZip(zfile);
178 if (err != UNZ_OK) {
179 LOG(ERROR, ZIPARCHIVE) << "zipCloseFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
180 }
181 err = zipClose(zfile, nullptr);
182 if (err != UNZ_OK) {
183 LOG(ERROR, ZIPARCHIVE) << "CloseArcive failed!, zipname is" << zipname;
184 }
185 return success;
186 }
187 } // namespace panda
188