1 /*
2 * Copyright (c) 2024 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 <cstdio>
17 #include <fstream>
18 #include <ostream>
19 #include <string>
20
21 #include "gtest/gtest.h"
22 #include "ecmascript/extractortool/src/zip_file.h"
23 #include "ecmascript/tests/test_helper.h"
24 #include "ecmascript/extractortool/src/zip_file_reader.h"
25
26 using namespace panda::ecmascript;
27 namespace panda::ecmascript {
28 class ZipFileFriend {
29 public:
ZipFileFriend(const std::string &path)30 explicit ZipFileFriend(const std::string &path) : zipFile_(path)
31 {
32 }
33
~ZipFileFriend()34 ~ZipFileFriend()
35 {
36 Close();
37 }
38
SetContentLocation(ZipPos start, size_t length)39 void SetContentLocation(ZipPos start, size_t length)
40 {
41 zipFile_.SetContentLocation(start, length);
42 }
43
CheckEndDir(EndDir &endDir) const44 bool CheckEndDir(EndDir &endDir) const
45 {
46 return zipFile_.CheckEndDir(endDir);
47 }
48
ParseEndDirectory()49 bool ParseEndDirectory()
50 {
51 return zipFile_.ParseEndDirectory();
52 }
53
ParseOneEntry(uint8_t *&entryPtr)54 bool ParseOneEntry(uint8_t *&entryPtr)
55 {
56 return zipFile_.ParseOneEntry(entryPtr);
57 }
58
AddEntryToTree(const std::string &fileName)59 void AddEntryToTree(const std::string &fileName)
60 {
61 return zipFile_.AddEntryToTree(fileName);
62 }
63
ParseAllEntries()64 bool ParseAllEntries()
65 {
66 return zipFile_.ParseAllEntries();
67 }
68
Open()69 bool Open()
70 {
71 return zipFile_.Open();
72 }
73
Close()74 void Close()
75 {
76 zipFile_.Close();
77 }
78
IsDirExist(const std::string &dir) const79 bool IsDirExist(const std::string &dir) const
80 {
81 return zipFile_.IsDirExist(dir);
82 }
83
GetAllFileList(const std::string &srcPath, std::vector<std::string> &assetList)84 void GetAllFileList(const std::string &srcPath, std::vector<std::string> &assetList)
85 {
86 zipFile_.GetAllFileList(srcPath, assetList);
87 }
88
GetChildNames(const std::string &srcPath, std::set<std::string> &fileSet)89 void GetChildNames(const std::string &srcPath, std::set<std::string> &fileSet)
90 {
91 zipFile_.GetChildNames(srcPath, fileSet);
92 }
93
GetEntry(const std::string &entryName, ZipEntry &resultEntry) const94 bool GetEntry(const std::string &entryName, ZipEntry &resultEntry) const
95 {
96 return zipFile_.GetEntry(entryName, resultEntry);
97 }
98
CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const99 bool CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const
100 {
101 return zipFile_.CheckCoherencyLocalHeader(zipEntry, extraSize);
102 }
103
CreateFileMapper(const std::string &fileName, FileMapperType type) const104 std::unique_ptr<FileMapper> CreateFileMapper(const std::string &fileName, FileMapperType type) const
105 {
106 return zipFile_.CreateFileMapper(fileName, type);
107 }
108
ExtractToBufByName(const std::string &fileName, std::unique_ptr<uint8_t[]> &dataPtr, size_t &len) const109 bool ExtractToBufByName(const std::string &fileName, std::unique_ptr<uint8_t[]> &dataPtr, size_t &len) const
110 {
111 return zipFile_.ExtractToBufByName(fileName, dataPtr, len);
112 }
113
SetIsOpen(bool isOpen)114 void SetIsOpen(bool isOpen)
115 {
116 zipFile_.isOpen_ = isOpen;
117 }
118
GetFileStartPos() const119 ZipPos GetFileStartPos() const
120 {
121 return zipFile_.fileStartPos_;
122 }
123
SetFileLength(ZipPos length)124 void SetFileLength(ZipPos length)
125 {
126 zipFile_.fileLength_ = length;
127 }
128
GetFileLength() const129 ZipPos GetFileLength() const
130 {
131 return zipFile_.fileLength_;
132 }
133
GetPathName() const134 const std::string &GetPathName() const
135 {
136 return zipFile_.pathName_;
137 }
138
SetPathName(const std::string &newPathName)139 void SetPathName(const std::string &newPathName)
140 {
141 zipFile_.pathName_ = newPathName;
142 }
143
GetZipFileReader() const144 std::shared_ptr<ZipFileReader> GetZipFileReader() const
145 {
146 return zipFile_.zipFileReader_;
147 }
148
SetZipFileReader(const std::shared_ptr<ZipFileReader> &newZipFileReader)149 void SetZipFileReader(const std::shared_ptr<ZipFileReader> &newZipFileReader)
150 {
151 zipFile_.zipFileReader_ = newZipFileReader;
152 }
153
154 private:
155 ZipFile zipFile_;
156 };
157 }
158
159 namespace panda::test {
160 class ZipFileTest : public testing::Test {
161 public:
SetUpTestCase()162 static void SetUpTestCase()
163 {
164 GTEST_LOG_(INFO) << "SetUpTestCase";
165 }
166
TearDownTestCase()167 static void TearDownTestCase()
168 {
169 GTEST_LOG_(INFO) << "TearDownCase";
170 }
171
172 void SetUp() override
173 {
174 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
175 instance->SetEnableForceGC(false);
176 }
177
178 void TearDown() override
179 {
180 TestHelper::DestroyEcmaVMWithScope(instance, scope);
181 }
182
183 EcmaVM *instance{nullptr};
184 EcmaHandleScope *scope{nullptr};
185 JSThread *thread{nullptr};
186 };
187
CreateTestFile()188 int CreateTestFile()
189 {
190 const std::string fileName = "TestFile.zip";
191 std::ofstream file(fileName);
192 if (!file.is_open()) {
193 return 1;
194 }
195 file << "This is a test file." << std::endl;
196 file.close();
197 if (!file) {
198 return 1;
199 }
200 return 0;
201 }
202
DeleteTestFile()203 int DeleteTestFile()
204 {
205 const char *fileName = "TestFile.zip";
206 if (std::remove(fileName) != 0) {
207 return 1;
208 }
209 return 0;
210 }
211
HWTEST_F_L0(ZipFileTest, SetContentLocationTest)212 HWTEST_F_L0(ZipFileTest, SetContentLocationTest)
213 {
214 std::string pathName = "path/to/zip.hap";
215 ZipFileFriend zipFileFriend(pathName);
216 zipFileFriend.SetIsOpen(true);
217 zipFileFriend.SetContentLocation(1, 1);
218 EXPECT_EQ(zipFileFriend.GetFileStartPos(), 0);
219 EXPECT_EQ(zipFileFriend.GetFileLength(), 0);
220
221 zipFileFriend.SetIsOpen(false);
222 zipFileFriend.SetContentLocation(1, 1);
223 EXPECT_EQ(zipFileFriend.GetFileStartPos(), 1);
224 EXPECT_EQ(zipFileFriend.GetFileLength(), 1);
225 }
226
HWTEST_F_L0(ZipFileTest, CheckEndDirTest)227 HWTEST_F_L0(ZipFileTest, CheckEndDirTest)
228 {
229 std::string pathName = "path/to/zip.hap";
230 ZipFileFriend zipFileFriend(pathName);
231 EndDir endDir;
232 EXPECT_FALSE(zipFileFriend.CheckEndDir(endDir));
233
234 zipFileFriend.SetFileLength(100);
235 EndDir endDir2;
236 endDir2.signature = 0x06054b50;
237 endDir2.numDisk = 0;
238 endDir2.startDiskOfCentralDir = 0;
239 endDir2.totalEntriesInThisDisk = 1;
240 endDir2.totalEntries = 1;
241 endDir2.sizeOfCentralDir = 78;
242 endDir2.offset = 0;
243 endDir2.commentLen = 0;
244
245 EXPECT_TRUE(zipFileFriend.CheckEndDir(endDir2));
246 }
247
HWTEST_F_L0(ZipFileTest, ParseEndDirectoryTest)248 HWTEST_F_L0(ZipFileTest, ParseEndDirectoryTest)
249 {
250 std::string pathName = "path/to/zip.hap";
251 ZipFileFriend zipFileFriend(pathName);
252 zipFileFriend.SetFileLength(22);
253 EXPECT_FALSE(zipFileFriend.ParseEndDirectory());
254 }
255
HWTEST_F_L0(ZipFileTest, OpenTest)256 HWTEST_F_L0(ZipFileTest, OpenTest)
257 {
258 std::string pathName = "test_files/long_path_name.txt";
259 ZipFileFriend zipFileFriend(pathName);
260 zipFileFriend.SetIsOpen(true);
261 EXPECT_TRUE(zipFileFriend.Open());
262
263 zipFileFriend.SetIsOpen(false);
264 std::string longPathName(4097, 'a');
265 zipFileFriend.SetPathName(longPathName);
266 EXPECT_FALSE(zipFileFriend.Open());
267 }
268
HWTEST_F_L0(ZipFileTest, CloseTest)269 HWTEST_F_L0(ZipFileTest, CloseTest)
270 {
271 std::string pathName = "zipFileTest.zip";
272 ZipFileFriend zipFileFriend(pathName);
273 zipFileFriend.Close();
274 EXPECT_EQ(zipFileFriend.GetPathName(), "zipFileTest.zip");
275
276 EXPECT_EQ(CreateTestFile(), 0);
277 std::shared_ptr<ZipFileReader> zipFileReader = ZipFileReader::CreateZipFileReader(pathName);
278 zipFileFriend.SetZipFileReader(zipFileReader);
279 EXPECT_EQ(DeleteTestFile(), 0);
280 zipFileFriend.Close();
281 }
282
HWTEST_F_L0(ZipFileTest, IsDirExistTest)283 HWTEST_F_L0(ZipFileTest, IsDirExistTest)
284 {
285 std::string pathName = "zipFileTest.zip";
286 ZipFileFriend zipFileFriend(pathName);
287 EXPECT_FALSE(zipFileFriend.IsDirExist(""));
288 std::string dir = ".";
289 EXPECT_FALSE(zipFileFriend.IsDirExist(dir));
290 dir = "path/to/nonexistent";
291 EXPECT_FALSE(zipFileFriend.IsDirExist(dir));
292 dir = "/";
293 EXPECT_TRUE(zipFileFriend.IsDirExist(dir));
294 }
295
HWTEST_F_L0(ZipFileTest, GetAllFileListTest)296 HWTEST_F_L0(ZipFileTest, GetAllFileListTest)
297 {
298 std::string pathName = "zipFileTest.zip";
299 ZipFileFriend zipFileFriend(pathName);
300 std::vector<std::string> assetList;
301 zipFileFriend.GetAllFileList("", assetList);
302 EXPECT_TRUE(assetList.empty());
303
304 assetList.clear();
305 zipFileFriend.GetAllFileList(".", assetList);
306 EXPECT_TRUE(assetList.empty());
307
308 assetList.clear();
309 zipFileFriend.GetAllFileList("./", assetList);
310 EXPECT_TRUE(assetList.empty());
311
312 assetList.clear();
313 zipFileFriend.GetAllFileList("path/to/nonexistent", assetList);
314 EXPECT_TRUE(assetList.empty());
315 }
316
HWTEST_F_L0(ZipFileTest, GetChildNamesTest)317 HWTEST_F_L0(ZipFileTest, GetChildNamesTest)
318 {
319 std::string pathName = "zipFileTest.zip";
320 ZipFileFriend zipFileFriend(pathName);
321 std::set<std::string> fileSet;
322
323 zipFileFriend.GetChildNames("", fileSet);
324 EXPECT_TRUE(fileSet.empty());
325
326 fileSet.clear();
327 zipFileFriend.GetChildNames("/", fileSet);
328 EXPECT_TRUE(fileSet.empty());
329
330 fileSet.clear();
331 zipFileFriend.GetChildNames(".", fileSet);
332 EXPECT_TRUE(fileSet.empty());
333
334 fileSet.clear();
335 zipFileFriend.GetChildNames(".", fileSet);
336 EXPECT_TRUE(fileSet.empty());
337
338 fileSet.clear();
339 zipFileFriend.GetChildNames("path/to/nonexistent", fileSet);
340 EXPECT_TRUE(fileSet.empty());
341 }
342
HWTEST_F_L0(ZipFileTest, GetEntryTest)343 HWTEST_F_L0(ZipFileTest, GetEntryTest)
344 {
345 std::string pathName = "zipFileTest.zip";
346 ZipFileFriend zipFileFriend(pathName);
347 ZipEntry resultEntry;
348 std::string nonExistingEntryName = "nonExistingEntry";
349 EXPECT_FALSE(zipFileFriend.GetEntry(nonExistingEntryName, resultEntry));
350 }
351
HWTEST_F_L0(ZipFileTest, CheckCoherencyLocalHeaderTest)352 HWTEST_F_L0(ZipFileTest, CheckCoherencyLocalHeaderTest)
353 {
354 std::string pathName = "zipFileTest.zip";
355 ZipFileFriend zipFileFriend(pathName);
356 ZipEntry zipEntry;
357 uint16_t extraSize;
358 size_t fileStartPos_;
359 fileStartPos_ = 0;
360 zipEntry.compressionMethod = 8;
361 zipEntry.localHeaderOffset = 0;
362 zipEntry.fileName = "testFile.txt";
363 zipEntry.compressionMethod = 9;
364 EXPECT_FALSE(zipFileFriend.CheckCoherencyLocalHeader(zipEntry, extraSize));
365 zipEntry.fileName = std::string(4096, 'a');
366 EXPECT_FALSE(zipFileFriend.CheckCoherencyLocalHeader(zipEntry, extraSize));
367 zipEntry.fileName = "differentName.txt";
368 EXPECT_FALSE(zipFileFriend.CheckCoherencyLocalHeader(zipEntry, extraSize));
369 }
370 }