1600cc4afSopenharmony_ci/* 2600cc4afSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3600cc4afSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4600cc4afSopenharmony_ci * you may not use this file except in compliance with the License. 5600cc4afSopenharmony_ci * You may obtain a copy of the License at 6600cc4afSopenharmony_ci * 7600cc4afSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8600cc4afSopenharmony_ci * 9600cc4afSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10600cc4afSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11600cc4afSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12600cc4afSopenharmony_ci * See the License for the specific language governing permissions and 13600cc4afSopenharmony_ci * limitations under the License. 14600cc4afSopenharmony_ci */ 15600cc4afSopenharmony_ci 16600cc4afSopenharmony_ci#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_ZIP_FILE_H 17600cc4afSopenharmony_ci#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_ZIP_FILE_H 18600cc4afSopenharmony_ci 19600cc4afSopenharmony_ci#include <cstdint> 20600cc4afSopenharmony_ci#include <map> 21600cc4afSopenharmony_ci#include <string> 22600cc4afSopenharmony_ci 23600cc4afSopenharmony_ci#include "unzip.h" 24600cc4afSopenharmony_ci 25600cc4afSopenharmony_cinamespace OHOS { 26600cc4afSopenharmony_cinamespace AppExecFwk { 27600cc4afSopenharmony_cistruct CentralDirEntry; 28600cc4afSopenharmony_cistruct ZipEntry; 29600cc4afSopenharmony_ciusing ZipPos = ZPOS64_T; 30600cc4afSopenharmony_ciusing ZipEntryMap = std::map<std::string, ZipEntry>; 31600cc4afSopenharmony_ciusing BytePtr = Byte *; 32600cc4afSopenharmony_ci 33600cc4afSopenharmony_ci// Local file header: descript in APPNOTE-6.3.4 34600cc4afSopenharmony_ci// local file header signature 4 bytes (0x04034b50) 35600cc4afSopenharmony_ci// version needed to extract 2 bytes 36600cc4afSopenharmony_ci// general purpose bit flag 2 bytes 37600cc4afSopenharmony_ci// compression method 2 bytes 10 38600cc4afSopenharmony_ci// last mod file time 2 bytes 39600cc4afSopenharmony_ci// last mod file date 2 bytes 40600cc4afSopenharmony_ci// crc-32 4 bytes 41600cc4afSopenharmony_ci// compressed size 4 bytes 22 42600cc4afSopenharmony_ci// uncompressed size 4 bytes 43600cc4afSopenharmony_ci// file name length 2 bytes 44600cc4afSopenharmony_ci// extra field length 2 bytes 30 45600cc4afSopenharmony_cistruct __attribute__((packed)) LocalHeader { 46600cc4afSopenharmony_ci uint32_t signature = 0; 47600cc4afSopenharmony_ci uint16_t versionNeeded = 0; 48600cc4afSopenharmony_ci uint16_t flags = 0; 49600cc4afSopenharmony_ci uint16_t compressionMethod = 0; 50600cc4afSopenharmony_ci uint16_t modifiedTime = 0; 51600cc4afSopenharmony_ci uint16_t modifiedDate = 0; 52600cc4afSopenharmony_ci uint32_t crc = 0; 53600cc4afSopenharmony_ci uint32_t compressedSize = 0; 54600cc4afSopenharmony_ci uint32_t uncompressedSize = 0; 55600cc4afSopenharmony_ci uint16_t nameSize = 0; 56600cc4afSopenharmony_ci uint16_t extraSize = 0; 57600cc4afSopenharmony_ci}; 58600cc4afSopenharmony_ci 59600cc4afSopenharmony_ci// central file header 60600cc4afSopenharmony_ci// Central File header: 61600cc4afSopenharmony_ci// central file header signature 4 bytes (0x02014b50) 62600cc4afSopenharmony_ci// version made by 2 bytes 63600cc4afSopenharmony_ci// version needed to extract 2 bytes 64600cc4afSopenharmony_ci// general purpose bit flag 2 bytes 10 65600cc4afSopenharmony_ci// compression method 2 bytes 66600cc4afSopenharmony_ci// last mod file time 2 bytes 67600cc4afSopenharmony_ci// last mod file date 2 bytes 68600cc4afSopenharmony_ci// crc-32 4 bytes 20 69600cc4afSopenharmony_ci// compressed size 4 bytes 70600cc4afSopenharmony_ci// uncompressed size 4 bytes 71600cc4afSopenharmony_ci// file name length 2 bytes 30 72600cc4afSopenharmony_ci// extra field length 2 bytes 73600cc4afSopenharmony_ci// file comment length 2 bytes 74600cc4afSopenharmony_ci// disk number start 2 bytes 75600cc4afSopenharmony_ci// internal file attributes 2 bytes 76600cc4afSopenharmony_ci// external file attributes 4 bytes 77600cc4afSopenharmony_ci// relative offset of local header 4 bytes 46byte 78600cc4afSopenharmony_cistruct __attribute__((packed)) CentralDirEntry { 79600cc4afSopenharmony_ci uint32_t signature = 0; 80600cc4afSopenharmony_ci uint16_t versionMade = 0; 81600cc4afSopenharmony_ci uint16_t versionNeeded = 0; 82600cc4afSopenharmony_ci uint16_t flags = 0; // general purpose bit flag 83600cc4afSopenharmony_ci uint16_t compressionMethod = 0; 84600cc4afSopenharmony_ci uint16_t modifiedTime = 0; 85600cc4afSopenharmony_ci uint16_t modifiedDate = 0; 86600cc4afSopenharmony_ci uint32_t crc = 0; 87600cc4afSopenharmony_ci uint32_t compressedSize = 0; 88600cc4afSopenharmony_ci uint32_t uncompressedSize = 0; 89600cc4afSopenharmony_ci uint16_t nameSize = 0; 90600cc4afSopenharmony_ci uint16_t extraSize = 0; 91600cc4afSopenharmony_ci uint16_t commentSize = 0; 92600cc4afSopenharmony_ci uint16_t diskNumStart = 0; 93600cc4afSopenharmony_ci uint16_t internalAttr = 0; 94600cc4afSopenharmony_ci uint32_t externalAttr = 0; 95600cc4afSopenharmony_ci uint32_t localHeaderOffset = 0; 96600cc4afSopenharmony_ci}; 97600cc4afSopenharmony_ci 98600cc4afSopenharmony_ci// end of central directory packed structure 99600cc4afSopenharmony_ci// end of central dir signature 4 bytes (0x06054b50) 100600cc4afSopenharmony_ci// number of this disk 2 bytes 101600cc4afSopenharmony_ci// number of the disk with the 102600cc4afSopenharmony_ci// start of the central directory 2 bytes 103600cc4afSopenharmony_ci// total number of entries in the 104600cc4afSopenharmony_ci// central directory on this disk 2 bytes 105600cc4afSopenharmony_ci// total number of entries in 106600cc4afSopenharmony_ci// the central directory 2 bytes 107600cc4afSopenharmony_ci// size of the central directory 4 bytes 108600cc4afSopenharmony_ci// offset of start of central 109600cc4afSopenharmony_ci// directory with respect to 110600cc4afSopenharmony_ci// the starting disk number 4 bytes 111600cc4afSopenharmony_ci// .ZIP file comment length 2 bytes 112600cc4afSopenharmony_cistruct __attribute__((packed)) EndDir { 113600cc4afSopenharmony_ci uint32_t signature = 0; 114600cc4afSopenharmony_ci uint16_t numDisk = 0; 115600cc4afSopenharmony_ci uint16_t startDiskOfCentralDir = 0; 116600cc4afSopenharmony_ci uint16_t totalEntriesInThisDisk = 0; 117600cc4afSopenharmony_ci uint16_t totalEntries = 0; 118600cc4afSopenharmony_ci uint32_t sizeOfCentralDir = 0; 119600cc4afSopenharmony_ci uint32_t offset = 0; 120600cc4afSopenharmony_ci uint16_t commentLen = 0; 121600cc4afSopenharmony_ci}; 122600cc4afSopenharmony_ci 123600cc4afSopenharmony_ci// Data descriptor: 124600cc4afSopenharmony_ci// data descriptor signature 4 bytes (0x06054b50) 125600cc4afSopenharmony_ci// crc-32 4 bytes 126600cc4afSopenharmony_ci// compressed size 4 bytes 127600cc4afSopenharmony_ci// uncompressed size 4 bytes 128600cc4afSopenharmony_ci// This descriptor MUST exist if bit 3 of the general purpose bit flag is set (see below). 129600cc4afSopenharmony_ci// It is byte aligned and immediately follows the last byte of compressed data. 130600cc4afSopenharmony_cistruct __attribute__((packed)) DataDesc { 131600cc4afSopenharmony_ci uint32_t signature = 0; 132600cc4afSopenharmony_ci uint32_t crc = 0; 133600cc4afSopenharmony_ci uint32_t compressedSize = 0; 134600cc4afSopenharmony_ci uint32_t uncompressedSize = 0; 135600cc4afSopenharmony_ci}; 136600cc4afSopenharmony_ci 137600cc4afSopenharmony_cistruct ZipEntry { 138600cc4afSopenharmony_ci ZipEntry() = default; 139600cc4afSopenharmony_ci explicit ZipEntry(const CentralDirEntry ¢ralEntry); 140600cc4afSopenharmony_ci ~ZipEntry() = default; // for CodeDEX warning 141600cc4afSopenharmony_ci 142600cc4afSopenharmony_ci uint16_t compressionMethod = 0; 143600cc4afSopenharmony_ci uint32_t uncompressedSize = 0; 144600cc4afSopenharmony_ci uint32_t compressedSize = 0; 145600cc4afSopenharmony_ci uint32_t localHeaderOffset = 0; 146600cc4afSopenharmony_ci uint32_t crc = 0; 147600cc4afSopenharmony_ci uint16_t flags = 0; 148600cc4afSopenharmony_ci std::string fileName; 149600cc4afSopenharmony_ci}; 150600cc4afSopenharmony_ci 151600cc4afSopenharmony_ci// zip file extract class for bundle format. 152600cc4afSopenharmony_ciclass ZipFile { 153600cc4afSopenharmony_cipublic: 154600cc4afSopenharmony_ci explicit ZipFile(const std::string &pathName); 155600cc4afSopenharmony_ci ~ZipFile(); 156600cc4afSopenharmony_ci /** 157600cc4afSopenharmony_ci * @brief Open zip file. 158600cc4afSopenharmony_ci * @return Returns true if the zip file is successfully opened; returns false otherwise. 159600cc4afSopenharmony_ci */ 160600cc4afSopenharmony_ci bool Open(); 161600cc4afSopenharmony_ci /** 162600cc4afSopenharmony_ci * @brief Close zip file. 163600cc4afSopenharmony_ci */ 164600cc4afSopenharmony_ci void Close(); 165600cc4afSopenharmony_ci /** 166600cc4afSopenharmony_ci * @brief Set this zip content start offset and length in the zip file form pathName. 167600cc4afSopenharmony_ci * @param start Indicates the zip content location start position. 168600cc4afSopenharmony_ci * @param length Indicates the zip content length. 169600cc4afSopenharmony_ci */ 170600cc4afSopenharmony_ci void SetContentLocation(ZipPos start, size_t length); 171600cc4afSopenharmony_ci /** 172600cc4afSopenharmony_ci * @brief Get all entries in the zip file. 173600cc4afSopenharmony_ci * @param start Indicates the zip content location start position. 174600cc4afSopenharmony_ci * @param length Indicates the zip content length. 175600cc4afSopenharmony_ci * @return Returns the ZipEntryMap object cotain all entries. 176600cc4afSopenharmony_ci */ 177600cc4afSopenharmony_ci const ZipEntryMap &GetAllEntries() const; 178600cc4afSopenharmony_ci /** 179600cc4afSopenharmony_ci * @brief Has entry by name. 180600cc4afSopenharmony_ci * @param entryName Indicates the entry name. 181600cc4afSopenharmony_ci * @return Returns true if the ZipEntry is successfully finded; returns false otherwise. 182600cc4afSopenharmony_ci */ 183600cc4afSopenharmony_ci bool HasEntry(const std::string &entryName) const; 184600cc4afSopenharmony_ci 185600cc4afSopenharmony_ci bool IsDirExist(const std::string &dir) const; 186600cc4afSopenharmony_ci 187600cc4afSopenharmony_ci /** 188600cc4afSopenharmony_ci * @brief Get entry by name. 189600cc4afSopenharmony_ci * @param entryName Indicates the entry name. 190600cc4afSopenharmony_ci * @param resultEntry Indicates the obtained ZipEntry object. 191600cc4afSopenharmony_ci * @return Returns true if the ZipEntry is successfully finded; returns false otherwise. 192600cc4afSopenharmony_ci */ 193600cc4afSopenharmony_ci bool GetEntry(const std::string &entryName, ZipEntry &resultEntry) const; 194600cc4afSopenharmony_ci /** 195600cc4afSopenharmony_ci * @brief Get data relative offset for file. 196600cc4afSopenharmony_ci * @param file Indicates the entry name. 197600cc4afSopenharmony_ci * @param offset Indicates the obtained offset. 198600cc4afSopenharmony_ci * @param length Indicates the length. 199600cc4afSopenharmony_ci * @return Returns true if this function is successfully called; returns false otherwise. 200600cc4afSopenharmony_ci */ 201600cc4afSopenharmony_ci bool GetDataOffsetRelative(const std::string &file, ZipPos &offset, uint32_t &length) const; 202600cc4afSopenharmony_ci /** 203600cc4afSopenharmony_ci * @brief Get data relative offset for file. 204600cc4afSopenharmony_ci * @param file Indicates the entry name. 205600cc4afSopenharmony_ci * @param dest Indicates the obtained ostream object. 206600cc4afSopenharmony_ci * @return Returns true if file is successfully extracted; returns false otherwise. 207600cc4afSopenharmony_ci */ 208600cc4afSopenharmony_ci bool ExtractFile(const std::string &file, std::ostream &dest) const; 209600cc4afSopenharmony_ci 210600cc4afSopenharmony_ciprivate: 211600cc4afSopenharmony_ci /** 212600cc4afSopenharmony_ci * @brief Check the EndDir object. 213600cc4afSopenharmony_ci * @param endDir Indicates the EndDir object to check. 214600cc4afSopenharmony_ci * @return Returns true if successfully checked; returns false otherwise. 215600cc4afSopenharmony_ci */ 216600cc4afSopenharmony_ci bool CheckEndDir(const EndDir &endDir) const; 217600cc4afSopenharmony_ci /** 218600cc4afSopenharmony_ci * @brief Parse the EndDir. 219600cc4afSopenharmony_ci * @return Returns true if successfully Parsed; returns false otherwise. 220600cc4afSopenharmony_ci */ 221600cc4afSopenharmony_ci bool ParseEndDirectory(); 222600cc4afSopenharmony_ci /** 223600cc4afSopenharmony_ci * @brief Parse all Entries. 224600cc4afSopenharmony_ci * @return Returns true if successfully parsed; returns false otherwise. 225600cc4afSopenharmony_ci */ 226600cc4afSopenharmony_ci bool ParseAllEntries(); 227600cc4afSopenharmony_ci /** 228600cc4afSopenharmony_ci * @brief Get LocalHeader object size. 229600cc4afSopenharmony_ci * @param nameSize Indicates the nameSize. 230600cc4afSopenharmony_ci * @param extraSize Indicates the extraSize. 231600cc4afSopenharmony_ci * @return Returns size of LocalHeader. 232600cc4afSopenharmony_ci */ 233600cc4afSopenharmony_ci size_t GetLocalHeaderSize(const uint16_t nameSize = 0, const uint16_t extraSize = 0) const; 234600cc4afSopenharmony_ci /** 235600cc4afSopenharmony_ci * @brief Get entry data offset. 236600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 237600cc4afSopenharmony_ci * @param extraSize Indicates the extraSize. 238600cc4afSopenharmony_ci * @return Returns position. 239600cc4afSopenharmony_ci */ 240600cc4afSopenharmony_ci ZipPos GetEntryDataOffset(const ZipEntry &zipEntry, const uint16_t extraSize) const; 241600cc4afSopenharmony_ci /** 242600cc4afSopenharmony_ci * @brief Check data description. 243600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 244600cc4afSopenharmony_ci * @param localHeader Indicates the localHeader object. 245600cc4afSopenharmony_ci * @return Returns true if successfully checked; returns false otherwise. 246600cc4afSopenharmony_ci */ 247600cc4afSopenharmony_ci bool CheckDataDesc(const ZipEntry &zipEntry, const LocalHeader &localHeader) const; 248600cc4afSopenharmony_ci /** 249600cc4afSopenharmony_ci * @brief Check coherency LocalHeader object. 250600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 251600cc4afSopenharmony_ci * @param extraSize Indicates the obtained size. 252600cc4afSopenharmony_ci * @return Returns true if successfully checked; returns false otherwise. 253600cc4afSopenharmony_ci */ 254600cc4afSopenharmony_ci bool CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const; 255600cc4afSopenharmony_ci /** 256600cc4afSopenharmony_ci * @brief Unzip ZipEntry object to ostream. 257600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 258600cc4afSopenharmony_ci * @param extraSize Indicates the size. 259600cc4afSopenharmony_ci * @param dest Indicates the obtained ostream object. 260600cc4afSopenharmony_ci * @return Returns true if successfully Unzip; returns false otherwise. 261600cc4afSopenharmony_ci */ 262600cc4afSopenharmony_ci bool UnzipWithStore(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const; 263600cc4afSopenharmony_ci /** 264600cc4afSopenharmony_ci * @brief Unzip ZipEntry object to ostream. 265600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 266600cc4afSopenharmony_ci * @param extraSize Indicates the size. 267600cc4afSopenharmony_ci * @param dest Indicates the obtained ostream object. 268600cc4afSopenharmony_ci * @return Returns true if successfully Unzip; returns false otherwise. 269600cc4afSopenharmony_ci */ 270600cc4afSopenharmony_ci bool UnzipWithInflated(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const; 271600cc4afSopenharmony_ci /** 272600cc4afSopenharmony_ci * @brief Seek to Entry start. 273600cc4afSopenharmony_ci * @param zipEntry Indicates the ZipEntry object. 274600cc4afSopenharmony_ci * @param extraSize Indicates the extra size. 275600cc4afSopenharmony_ci * @return Returns true if successfully Seeked; returns false otherwise. 276600cc4afSopenharmony_ci */ 277600cc4afSopenharmony_ci bool SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSize) const; 278600cc4afSopenharmony_ci /** 279600cc4afSopenharmony_ci * @brief Init zlib stream. 280600cc4afSopenharmony_ci * @param zstream Indicates the obtained z_stream object. 281600cc4afSopenharmony_ci * @return Returns true if successfully init; returns false otherwise. 282600cc4afSopenharmony_ci */ 283600cc4afSopenharmony_ci bool InitZStream(z_stream &zstream) const; 284600cc4afSopenharmony_ci /** 285600cc4afSopenharmony_ci * @brief Read zlib stream. 286600cc4afSopenharmony_ci * @param buffer Indicates the buffer to read. 287600cc4afSopenharmony_ci * @param zstream Indicates the obtained z_stream object. 288600cc4afSopenharmony_ci * @param remainCompressedSize Indicates the obtained size. 289600cc4afSopenharmony_ci * @return Returns true if successfully read; returns false otherwise. 290600cc4afSopenharmony_ci */ 291600cc4afSopenharmony_ci bool ReadZStream(const BytePtr &buffer, z_stream &zstream, uint32_t &remainCompressedSize) const; 292600cc4afSopenharmony_ci 293600cc4afSopenharmony_ciprivate: 294600cc4afSopenharmony_ci std::string pathName_; 295600cc4afSopenharmony_ci FILE *file_ = nullptr; 296600cc4afSopenharmony_ci EndDir endDir_; 297600cc4afSopenharmony_ci ZipEntryMap entriesMap_; 298600cc4afSopenharmony_ci // offset of central directory relative to zip file. 299600cc4afSopenharmony_ci ZipPos centralDirPos_ = 0; 300600cc4afSopenharmony_ci // this zip content start offset relative to zip file. 301600cc4afSopenharmony_ci ZipPos fileStartPos_ = 0; 302600cc4afSopenharmony_ci // this zip content length in the zip file. 303600cc4afSopenharmony_ci ZipPos fileLength_ = 0; 304600cc4afSopenharmony_ci bool isOpen_ = false; 305600cc4afSopenharmony_ci}; 306600cc4afSopenharmony_ci} // namespace AppExecFwk 307600cc4afSopenharmony_ci} // namespace OHOS 308600cc4afSopenharmony_ci#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_ZIP_FILE_H 309