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 26using namespace panda::ecmascript; 27namespace panda::ecmascript { 28class ZipFileFriend { 29public: 30 explicit ZipFileFriend(const std::string &path) : zipFile_(path) 31 { 32 } 33 34 ~ZipFileFriend() 35 { 36 Close(); 37 } 38 39 void SetContentLocation(ZipPos start, size_t length) 40 { 41 zipFile_.SetContentLocation(start, length); 42 } 43 44 bool CheckEndDir(EndDir &endDir) const 45 { 46 return zipFile_.CheckEndDir(endDir); 47 } 48 49 bool ParseEndDirectory() 50 { 51 return zipFile_.ParseEndDirectory(); 52 } 53 54 bool ParseOneEntry(uint8_t *&entryPtr) 55 { 56 return zipFile_.ParseOneEntry(entryPtr); 57 } 58 59 void AddEntryToTree(const std::string &fileName) 60 { 61 return zipFile_.AddEntryToTree(fileName); 62 } 63 64 bool ParseAllEntries() 65 { 66 return zipFile_.ParseAllEntries(); 67 } 68 69 bool Open() 70 { 71 return zipFile_.Open(); 72 } 73 74 void Close() 75 { 76 zipFile_.Close(); 77 } 78 79 bool IsDirExist(const std::string &dir) const 80 { 81 return zipFile_.IsDirExist(dir); 82 } 83 84 void GetAllFileList(const std::string &srcPath, std::vector<std::string> &assetList) 85 { 86 zipFile_.GetAllFileList(srcPath, assetList); 87 } 88 89 void GetChildNames(const std::string &srcPath, std::set<std::string> &fileSet) 90 { 91 zipFile_.GetChildNames(srcPath, fileSet); 92 } 93 94 bool GetEntry(const std::string &entryName, ZipEntry &resultEntry) const 95 { 96 return zipFile_.GetEntry(entryName, resultEntry); 97 } 98 99 bool CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const 100 { 101 return zipFile_.CheckCoherencyLocalHeader(zipEntry, extraSize); 102 } 103 104 std::unique_ptr<FileMapper> CreateFileMapper(const std::string &fileName, FileMapperType type) const 105 { 106 return zipFile_.CreateFileMapper(fileName, type); 107 } 108 109 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 114 void SetIsOpen(bool isOpen) 115 { 116 zipFile_.isOpen_ = isOpen; 117 } 118 119 ZipPos GetFileStartPos() const 120 { 121 return zipFile_.fileStartPos_; 122 } 123 124 void SetFileLength(ZipPos length) 125 { 126 zipFile_.fileLength_ = length; 127 } 128 129 ZipPos GetFileLength() const 130 { 131 return zipFile_.fileLength_; 132 } 133 134 const std::string &GetPathName() const 135 { 136 return zipFile_.pathName_; 137 } 138 139 void SetPathName(const std::string &newPathName) 140 { 141 zipFile_.pathName_ = newPathName; 142 } 143 144 std::shared_ptr<ZipFileReader> GetZipFileReader() const 145 { 146 return zipFile_.zipFileReader_; 147 } 148 149 void SetZipFileReader(const std::shared_ptr<ZipFileReader> &newZipFileReader) 150 { 151 zipFile_.zipFileReader_ = newZipFileReader; 152 } 153 154private: 155 ZipFile zipFile_; 156}; 157} 158 159namespace panda::test { 160class ZipFileTest : public testing::Test { 161public: 162 static void SetUpTestCase() 163 { 164 GTEST_LOG_(INFO) << "SetUpTestCase"; 165 } 166 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 188int 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 203int DeleteTestFile() 204{ 205 const char *fileName = "TestFile.zip"; 206 if (std::remove(fileName) != 0) { 207 return 1; 208 } 209 return 0; 210} 211 212HWTEST_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 227HWTEST_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 248HWTEST_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 256HWTEST_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 269HWTEST_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 283HWTEST_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 296HWTEST_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 317HWTEST_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 343HWTEST_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 352HWTEST_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}