1 /*
2  * Copyright (c) 2023-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 "js_quickfix_callback.h"
17 
18 #include "file_mapper.h"
19 #include "file_path_utils.h"
20 #include "hilog_tag_wrapper.h"
21 #include "js_runtime.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26     constexpr char MERGE_ABC_PATH[] = "/ets/modules.abc";
27     constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
28 }
29 
operator ()(std::string baseFileName,std::string & patchFileName,uint8_t ** patchBuffer,size_t & patchSize)30 bool JsQuickfixCallback::operator()(std::string baseFileName, std::string &patchFileName,
31                                     uint8_t **patchBuffer, size_t &patchSize)
32 {
33     TAG_LOGD(AAFwkTag::JSRUNTIME, "baseFileName: %{private}s", baseFileName.c_str());
34     auto position = baseFileName.find(".abc");
35     if (position == std::string::npos) {
36         TAG_LOGE(AAFwkTag::JSRUNTIME, ".abc not found");
37         return false;
38     }
39     int baseFileNameLen = static_cast<int>(baseFileName.length());
40     int prefixLen = strlen(BUNDLE_INSTALL_PATH);
41     int suffixLen = strlen(MERGE_ABC_PATH);
42     int moduleLen = baseFileNameLen - prefixLen - suffixLen;
43     if (moduleLen < 0) {
44         TAG_LOGE(AAFwkTag::JSRUNTIME, "invalid moduleLen");
45         return false;
46     }
47     std::string moduleName = baseFileName.substr(prefixLen, moduleLen);
48     TAG_LOGD(AAFwkTag::JSRUNTIME, "moduleName: %{private}s", moduleName.c_str());
49 
50     auto it = moduleAndHqfPath_.find(moduleName);
51     if (it == moduleAndHqfPath_.end()) {
52         return false;
53     }
54 
55     std::string hqfFile = it->second;
56     std::string resolvedHqfFile(AbilityBase::GetLoadPath(hqfFile));
57     TAG_LOGD(AAFwkTag::JSRUNTIME, "hqfFile: %{private}s, resolvedHqfFile: %{private}s", hqfFile.c_str(),
58         resolvedHqfFile.c_str());
59 
60     auto data = JsRuntime::GetSafeData(resolvedHqfFile, patchFileName);
61     if (data == nullptr) {
62         if (patchFileName.empty()) {
63             TAG_LOGI(AAFwkTag::JSRUNTIME, "No need to load patch cause no ets. path: %{private}s",
64                 resolvedHqfFile.c_str());
65             return true;
66         }
67         return false;
68     }
69     *patchBuffer = data->GetDataPtr();
70     TAG_LOGD(AAFwkTag::JSRUNTIME, "patchFileName: %{private}s", patchFileName.c_str());
71     patchSize = data->GetDataLen();
72     return true;
73 }
74 } // namespace AbilityRuntime
75 } // namespace OHOS
76