1/* 2 * Copyright (c) 2023 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 "extractor.h" 17 18#include <fstream> 19#include <sstream> 20#include "constants.h" 21#include "file_path_utils.h" 22#include "ecmascript/platform/file.h" 23 24namespace panda { 25namespace ecmascript { 26namespace { 27constexpr char EXT_NAME_ABC[] = ".abc"; 28} 29Extractor::Extractor(const std::string &source) : zipFile_(source) 30{ 31 hapPath_ = source; 32} 33 34Extractor::~Extractor() 35{} 36 37bool Extractor::Init() 38{ 39 if (!zipFile_.Open()) { 40 return false; 41 } 42 initial_ = true; 43 return true; 44} 45 46bool Extractor::GetFileBuffer(const std::string& srcPath, std::ostringstream& dest) 47{ 48 if (!initial_) { 49 return false; 50 } 51 52 if (srcPath.empty()) { 53 return false; 54 } 55 56 std::string relativePath = GetRelativePath(srcPath); 57 if (!ExtractByName(relativePath, dest)) { 58 return false; 59 } 60 61 return true; 62} 63 64bool Extractor::GetFileList(const std::string& srcPath, std::vector<std::string>& assetList) 65{ 66 if (!initial_) { 67 return false; 68 } 69 70 if (srcPath.empty()) { 71 return false; 72 } 73 zipFile_.GetAllFileList(srcPath, assetList); 74 if (assetList.empty()) { 75 } 76 77 return true; 78} 79 80bool Extractor::HasEntry(const std::string &fileName) const 81{ 82 if (!initial_) { 83 return false; 84 } 85 86 return zipFile_.HasEntry(fileName); 87} 88 89bool Extractor::IsDirExist(const std::string &dir) const 90{ 91 if (!initial_) { 92 return false; 93 } 94 if (dir.empty()) { 95 return false; 96 } 97 return zipFile_.IsDirExist(dir); 98} 99 100bool Extractor::ExtractByName(const std::string &fileName, std::ostream &dest) const 101{ 102 if (!initial_) { 103 return false; 104 } 105 if (!zipFile_.ExtractFile(fileName, dest)) { 106 return false; 107 } 108 return true; 109} 110 111bool Extractor::ExtractFile(const std::string &fileName, const std::string &targetPath) const 112{ 113 if (!panda::ecmascript::FileExist(targetPath.c_str())) { 114 return false; 115 } 116 std::ofstream fileStream; 117 fileStream.open(targetPath, std::ios_base::out | std::ios_base::binary); 118 if (!fileStream.is_open()) { 119 return false; 120 } 121 if ((!ExtractByName(fileName, fileStream)) || (!fileStream.good())) { 122 fileStream.clear(); 123 fileStream.close(); 124 if (remove(targetPath.c_str()) != 0) { 125 } 126 return false; 127 } 128 fileStream.clear(); 129 fileStream.close(); 130 return true; 131} 132 133bool Extractor::IsSameHap(const std::string& hapPath) const 134{ 135 return !hapPath_.empty() && !hapPath.empty() && hapPath_ == hapPath; 136} 137 138std::unique_ptr<FileMapper> Extractor::GetData(const std::string &fileName, bool) const 139{ 140 std::string relativePath = GetRelativePath(fileName); 141 return zipFile_.CreateFileMapper(relativePath, FileMapperType::NORMAL_MEM); 142} 143 144std::shared_ptr<FileMapper> Extractor::GetSafeData(const std::string &fileName) 145{ 146 std::string relativePath = GetRelativePath(fileName); 147 if (!StringEndWith(relativePath, EXT_NAME_ABC, sizeof(EXT_NAME_ABC) - 1)) { 148 return nullptr; 149 } 150 151 return zipFile_.CreateFileMapper(relativePath, FileMapperType::SAFE_ABC); 152} 153 154std::unique_ptr<FileMapper> Extractor::GetMmapData(const std::string &fileName) 155{ 156 std::string relativePath = GetRelativePath(fileName); 157 return zipFile_.CreateFileMapper(relativePath, FileMapperType::SHARED_MMAP); 158} 159 160bool Extractor::IsStageModel() 161{ 162 if (isStageModel_.has_value()) { 163 return isStageModel_.value(); 164 } 165 isStageModel_ = !zipFile_.HasEntry("config.json"); 166 return isStageModel_.value(); 167} 168 169bool Extractor::ExtractToBufByName(const std::string &fileName, std::unique_ptr<uint8_t[]> &dataPtr, 170 size_t &len) 171{ 172 std::string relativePath = GetRelativePath(fileName); 173 return zipFile_.ExtractToBufByName(relativePath, dataPtr, len); 174} 175 176bool Extractor::GetFileInfo(const std::string &fileName, FileInfo &fileInfo) const 177{ 178 std::string relativePath = GetRelativePath(fileName); 179 ZipEntry zipEntry; 180 if (!zipFile_.GetEntry(relativePath, zipEntry)) { 181 return false; 182 } 183 184 ZipPos offset = 0; 185 uint32_t length = 0; 186 if (!zipFile_.GetDataOffsetRelative(relativePath, offset, length)) { 187 return false; 188 } 189 190 fileInfo.fileName = fileName; 191 fileInfo.offset = static_cast<uint32_t>(offset); 192 fileInfo.length = static_cast<uint32_t>(length); 193 fileInfo.lastModTime = zipEntry.modifiedTime; 194 fileInfo.lastModDate = zipEntry.modifiedDate; 195 return true; 196} 197 198bool Extractor::GetFileList(const std::string &srcPath, std::set<std::string> &fileSet) 199{ 200 if (!initial_) { 201 return false; 202 } 203 204 if (srcPath.empty()) { 205 return false; 206 } 207 208 zipFile_.GetChildNames(srcPath, fileSet); 209 if (fileSet.empty()) { 210 } 211 212 return true; 213} 214 215bool Extractor::IsHapCompress(const std::string &fileName) const 216{ 217 std::string relativePath = GetRelativePath(fileName); 218 ZipEntry zipEntry; 219 if (!zipFile_.GetEntry(relativePath, zipEntry)) { 220 return false; 221 } 222 return zipEntry.compressionMethod > 0; 223} 224 225std::mutex ExtractorUtil::mapMutex_; 226std::unordered_map<std::string, std::shared_ptr<Extractor>> ExtractorUtil::extractorMap_; 227std::string ExtractorUtil::GetLoadFilePath(const std::string &hapPath) 228{ 229 std::string loadPath; 230 if (StringStartWith(hapPath, Constants::ABS_CODE_PATH, std::string(Constants::ABS_CODE_PATH).length())) { 231 loadPath = GetLoadPath(hapPath); 232 } else { 233 loadPath = hapPath; 234 } 235 return loadPath; 236} 237 238std::shared_ptr<Extractor> ExtractorUtil::GetExtractor(const std::string &hapPath, bool &newCreate, bool cache) 239{ 240 newCreate = false; 241 if (hapPath.empty()) { 242 return nullptr; 243 } 244 { 245 std::lock_guard<std::mutex> mapMutex(mapMutex_); 246 auto mapIter = extractorMap_.find(hapPath); 247 if (mapIter != extractorMap_.end()) { 248 return mapIter->second; 249 } 250 } 251 252 std::shared_ptr<Extractor> extractor = std::make_shared<Extractor>(hapPath); 253 if (!extractor->Init()) { 254 return nullptr; 255 } 256 if (cache) { 257 std::lock_guard<std::mutex> mapMutex(mapMutex_); 258 extractorMap_.emplace(hapPath, extractor); 259 } 260 newCreate = true; 261 return extractor; 262} 263 264void ExtractorUtil::DeleteExtractor(const std::string &hapPath) 265{ 266 if (hapPath.empty()) { 267 return; 268 } 269 270 std::lock_guard<std::mutex> mapMutex(mapMutex_); 271 auto mapIter = extractorMap_.find(hapPath); 272 if (mapIter != extractorMap_.end()) { 273 extractorMap_.erase(mapIter); 274 } 275} 276} // namespace AbilityBase 277} // namespace OHOS 278