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 22namespace panda { 23 24constexpr size_t ZIP_MAGIC_MASK = 0xff; 25constexpr size_t ZIP_MAGIC_OFFSET = 8U; 26 27bool IsZipMagic(uint32_t magic) 28{ 29 return ((((magic >> 0U) & ZIP_MAGIC_MASK) == 'P') && (((magic >> ZIP_MAGIC_OFFSET) & ZIP_MAGIC_MASK) == 'K')); 30} 31 32int 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 42int 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 52int 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 66int 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 80int 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 90int 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 100int 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 110int 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 120int 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 130void GetCurrentFileOffset(ZipArchiveHandle &handle, EntryFileStat *entry) 131{ 132 entry->offset = static_cast<uint32_t>(unzGetCurrentFileZStreamPos64(handle)); 133} 134 135int 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 145int 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 156int 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