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