• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef ZIP_PKG_FILE_H
17 #define ZIP_PKG_FILE_H
18 
19 #include <map>
20 #include "pkg_pkgfile.h"
21 #include "pkg_utils.h"
22 
23 namespace Hpackage {
24 // Local file header: descript in APPNOTE-6.3.4
25 //    local file header signature     4 bytes  (0x04034b50)
26 //    version needed to extract       2 bytes
27 //    general purpose bit flag        2 bytes
28 //    compression method              2 bytes
29 //    last mod file time              2 bytes
30 //    last mod file date              2 bytes
31 //    crc-32                          4 bytes
32 //    compressed size                 4 bytes
33 //    uncompressed size               4 bytes
34 //    file name length                2 bytes
35 //    extra field length              2 bytes
36 struct __attribute__((packed)) LocalFileHeader {
37     uint32_t signature = 0;
38     uint16_t versionNeeded = 0;
39     uint16_t flags = 0;
40     uint16_t compressionMethod = 0;
41     uint16_t modifiedTime = 0;
42     uint16_t modifiedDate = 0;
43     uint32_t crc = 0;
44     uint32_t compressedSize = 0;
45     uint32_t uncompressedSize = 0;
46     uint16_t nameSize = 0;
47     uint16_t extraSize = 0;
48 };
49 
50 // central file header
51 //    Central File header:
52 //    central file header signature   4 bytes  (0x02014b50)
53 //    version made by                 2 bytes
54 //    version needed to extract       2 bytes
55 //    general purpose bit flag        2 bytes
56 //    compression method              2 bytes
57 //    last mod file time              2 bytes
58 //    last mod file date              2 bytes
59 //    crc-32                          4 bytes
60 //    compressed size                 4 bytes
61 //    uncompressed size               4 bytes
62 //    file name length                2 bytes
63 //    extra field length              2 bytes
64 //    file comment length             2 bytes
65 //    disk number start               2 bytes
66 //    internal file attributes        2 bytes
67 //    external file attributes        4 bytes
68 //    relative offset of local header 4 bytes
69 struct __attribute__((packed)) CentralDirEntry {
70     uint32_t signature = 0;
71     uint16_t versionMade = 0;
72     uint16_t versionNeeded = 0;
73     uint16_t flags = 0; // general purpose bit flag
74     uint16_t compressionMethod = 0;
75     uint16_t modifiedTime = 0;
76     uint16_t modifiedDate = 0;
77     uint32_t crc = 0;
78     uint32_t compressedSize = 0;
79     uint32_t uncompressedSize = 0;
80     uint16_t nameSize = 0;
81     uint16_t extraSize = 0;
82     uint16_t commentSize = 0;
83     uint16_t diskNumStart = 0;
84     uint16_t internalAttr = 0;
85     uint32_t externalAttr = 0;
86     uint32_t localHeaderOffset = 0;
87 };
88 
89 struct __attribute__((packed)) EndCentralDir {
90     uint32_t signature = 0;
91     uint16_t numDisk = 0;
92     uint16_t startDiskOfCentralDir = 0;
93     uint16_t totalEntriesInThisDisk = 0;
94     uint16_t totalEntries = 0;
95     uint32_t sizeOfCentralDir = 0;
96     uint32_t offset = 0;
97     uint16_t commentLen = 0;
98 };
99 
100 struct __attribute__((packed)) DataDescriptor {
101     uint32_t signature = 0;
102     uint32_t crc = 0;
103     uint32_t compressedSize = 0;
104     uint32_t uncompressedSize = 0;
105 };
106 
107 struct __attribute__((packed)) Zip64EndCentralDirRecord {
108     uint32_t signature = 0; // 0x06064b50
109     uint64_t size = 0;
110     uint16_t versionMadeBy = 0;
111     uint16_t versionNeedToExtra = 0;
112     uint32_t numberOfThisDisk = 0;
113     uint32_t startOfthisDisk = 0;
114     uint64_t totalEntriesInThisDisk = 0;
115     uint64_t totalEntries = 0;
116     uint64_t sizeOfCentralDir = 0;
117     uint64_t offset = 0;
118 };
119 
120 struct __attribute__((packed)) Zip64EndCentralDirLocator {
121     uint32_t signature = 0; // 0x07064b50
122     uint32_t numberOfDisk = 0;
123     uint64_t endOfCentralDirectoryRecord = 0;
124     uint32_t totalNumberOfDisks = 0;
125 };
126 
127 class ZipFileEntry : public PkgEntry {
128 public:
ZipFileEntry(PkgFilePtr pkgFile,uint32_t nodeId)129     ZipFileEntry(PkgFilePtr pkgFile, uint32_t nodeId) : PkgEntry(pkgFile, nodeId) {}
130 
~ZipFileEntry()131     ~ZipFileEntry() override {}
132 
133     int32_t Init(const PkgManager::FileInfoPtr fileInfo, PkgStreamPtr inStream) override;
134 
GetFileInfo()135     const FileInfo *GetFileInfo() const override
136     {
137         return &fileInfo_.fileInfo;
138     };
139 
140     int32_t EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) override;
141 
142     int32_t Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) override;
143 
144     int32_t Unpack(PkgStreamPtr outStream) override;
145 
146     int32_t DecodeHeader(const PkgBuffer &buffer, size_t headOffset, size_t dataOffset,
147         size_t &decodeLen) override;
148 
149     int32_t EncodeCentralDirEntry(const PkgStreamPtr stream, size_t startOffset, size_t &encodeLen);
150 
151     int32_t DecodeCentralDirEntry(PkgStreamPtr inStream, PkgBuffer &buffer, size_t currentPos,
152         size_t &decodeLen);
153 
154 protected:
155     ZipFileInfo fileInfo_ {};
156     uint32_t crc32_ {0};
157 
158 private:
159     int32_t DecodeLocalFileHeaderCheck(PkgStreamPtr inStream, const PkgBuffer &data, size_t currentPos);
160 
161     int32_t DecodeLocalFileHeader(PkgStreamPtr inStream, const PkgBuffer &data, size_t currentPos,
162         size_t &decodeLen);
163 
164     int32_t EncodeLocalFileHeader(uint8_t *buffer, size_t bufferLen, bool hasDataDesc, size_t nameLen);
165 
166     int32_t EncodeDataDescriptor(const PkgStreamPtr stream, size_t startOffset, uint32_t &encodeLen) const;
167 
168     void CombineTimeAndDate(time_t &time, uint16_t modifiedTime, uint16_t modifiedDate) const;
169 };
170 
171 class ZipPkgFile : public PkgFile {
172 public:
ZipPkgFile(PkgManager::PkgManagerPtr manager,PkgStreamPtr stream)173     explicit ZipPkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream)
174         : PkgFile(manager, stream, PkgFile::PKG_TYPE_ZIP)
175     {
176         pkgInfo_.signMethod = PKG_SIGN_METHOD_RSA;
177         pkgInfo_.digestMethod = PKG_DIGEST_TYPE_SHA256;
178     }
~ZipPkgFile()179     ~ZipPkgFile() override {}
180 
181     int32_t AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream) override;
182 
183     int32_t SavePackage(size_t &signOffset) override;
184 
185     int32_t LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier = nullptr) override;
186 
187 private:
188     int32_t LoadPackage(std::vector<std::string> &fileNames, const PkgBuffer &buffer,
189         uint32_t endDirLen, size_t endDirPos, size_t &readLen);
190     int32_t ParseFileEntries(std::vector<std::string> &fileNames, const EndCentralDir &endDir,
191         size_t currentPos, size_t fileLen);
192 
193 private:
194     PkgInfo pkgInfo_ {};
195     size_t currentOffset_ = 0;
196 };
197 } // namespace Hpackage
198 #endif
199