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 #ifndef JS_CONCURRENT_MODULE_COMMON_HELPER_PATH_HELPER_H 17 #define JS_CONCURRENT_MODULE_COMMON_HELPER_PATH_HELPER_H 18 19 #include <vector> 20 #include <string> 21 22 #include "native_engine/native_engine.h" 23 #include "tools/log.h" 24 25 namespace Commonlibrary::Concurrent::Common::Helper { 26 class PathHelper { 27 public: 28 static constexpr char PREFIX_BUNDLE[] = "@bundle:"; 29 static constexpr char DOUBLE_POINT_TAG[] = ".."; 30 static constexpr char NAME_SPACE_TAG = '@'; 31 static constexpr char POINT_TAG[] = "."; 32 static constexpr char SLASH_TAG = '/'; 33 static constexpr char EXT_NAME_ETS[] = ".ets"; 34 static constexpr char EXT_NAME_TS[] = ".ts"; 35 static constexpr char EXT_NAME_JS[] = ".js"; 36 static constexpr char PAG_TAG[] = "pkg_modules"; 37 static constexpr char NORMALIZED_OHMURL_TAG = '&'; 38 static constexpr char PHYCICAL_FILE_PATH[] = "src/main"; 39 static constexpr size_t NORMALIZED_OHMURL_ARGS_NUM = 5; 40 CheckWorkerPath(napi_env env,std::string script,std::string fileName,bool isRelativePath)41 static bool CheckWorkerPath(napi_env env, std::string script, std::string fileName, bool isRelativePath) 42 { 43 std::string ohmurl = ""; 44 std::string moduleName = ""; 45 std::string bundleName = ""; 46 if (script.find(PAG_TAG) == 0 || script.find(NAME_SPACE_TAG) != std::string::npos) { 47 HILOG_INFO("worker:: the HAR path cannot be verified"); 48 return true; 49 } 50 51 bool isNormalizedOhmUrlPack = reinterpret_cast<NativeEngine*>(env)->GetIsNormalizedOhmUrlPack(); 52 if (isNormalizedOhmUrlPack) { 53 return CheckNormalizedWorkerPath(env, script, fileName, isRelativePath); 54 } 55 size_t prev = script.find_first_of(SLASH_TAG); 56 while (prev == 0 && script != "") { 57 script = script.substr(1); 58 prev = script.find_first_of(SLASH_TAG); 59 } 60 if (isRelativePath) { 61 if (prev != std::string::npos) { 62 bundleName = script.substr(0, prev); 63 } 64 std::string temp = script.substr(prev + 1); 65 prev = temp.find_first_of(SLASH_TAG); 66 if (prev != std::string::npos) { 67 moduleName = temp.substr(0, prev); 68 } 69 ohmurl = PREFIX_BUNDLE + script; 70 } else { 71 if (prev != std::string::npos) { 72 moduleName = script.substr(0, prev); 73 } 74 bundleName = reinterpret_cast<NativeEngine*>(env)->GetBundleName(); 75 prev = script.find_last_of(POINT_TAG); 76 if (prev != std::string::npos) { 77 script = script.substr(0, prev); 78 } 79 ohmurl = PREFIX_BUNDLE + bundleName + SLASH_TAG + script; 80 } 81 return reinterpret_cast<NativeEngine*>(env)->IsExecuteModuleInAbcFile(bundleName, moduleName, ohmurl); 82 } 83 CheckNormalizedWorkerPath(napi_env env,std::string script,std::string fileName,bool isRelativePath)84 static bool CheckNormalizedWorkerPath(napi_env env, std::string script, std::string fileName, bool isRelativePath) 85 { 86 std::string ohmurl = ""; 87 std::string moduleName = ""; 88 std::string bundleName = ""; 89 if (isRelativePath) { 90 size_t prev = fileName.find_first_of(SLASH_TAG); 91 if (prev != std::string::npos) { 92 moduleName = fileName.substr(0, prev); 93 } 94 ohmurl = script; 95 } else { 96 size_t prev = script.find_last_of(POINT_TAG); 97 if (prev != std::string::npos) { 98 script = script.substr(0, prev); 99 } 100 prev = script.find_first_of(SLASH_TAG); 101 std::string path; 102 if (prev != std::string::npos) { 103 moduleName = script.substr(0, prev); 104 path = script.substr(prev); 105 } 106 bundleName = reinterpret_cast<NativeEngine*>(env)->GetBundleName(); 107 std::string pkgName = reinterpret_cast<NativeEngine*>(env)->GetPkgName(moduleName); 108 ohmurl = NORMALIZED_OHMURL_TAG + pkgName + SLASH_TAG + PHYCICAL_FILE_PATH + path + NORMALIZED_OHMURL_TAG; 109 } 110 return reinterpret_cast<NativeEngine*>(env)->IsExecuteModuleInAbcFile(bundleName, moduleName, ohmurl); 111 } 112 ConcatFileNameForWorker(napi_env env,std::string & script,std::string & fileName,bool & isRelativePath)113 static void ConcatFileNameForWorker(napi_env env, std::string &script, std::string &fileName, bool &isRelativePath) 114 { 115 std::string moduleName; 116 if (script.find_first_of(POINT_TAG) == 0) { 117 isRelativePath = true; 118 } 119 reinterpret_cast<NativeEngine*>(env)->GetCurrentModuleInfo(moduleName, fileName, isRelativePath); 120 if (isRelativePath) { 121 // if input is relative path, need to concat new recordName. 122 std::string recordName = moduleName; 123 size_t pos = moduleName.rfind(SLASH_TAG); 124 if (pos != std::string::npos) { 125 moduleName = moduleName.substr(0, pos + 1); // from spcific file to dir 126 } 127 script = moduleName + script; 128 script = NormalizePath(script); // remove ../ and .ets 129 130 if (recordName.at(0) == NORMALIZED_OHMURL_TAG) { 131 script.append(1, NORMALIZED_OHMURL_TAG); 132 std::vector<std::string> normalizedRes = SplitNormalizedRecordName(recordName); 133 script += normalizedRes[NORMALIZED_OHMURL_ARGS_NUM - 1]; 134 } 135 } else { 136 script = moduleName + script; 137 } 138 } 139 NormalizePath(const std::string & entryPoint)140 static std::string NormalizePath(const std::string &entryPoint) 141 { 142 std::string res; 143 size_t prev = 0; 144 size_t curr = entryPoint.find(SLASH_TAG); 145 std::vector<std::string> elems; 146 // eliminate parent directory path 147 while (curr != std::string::npos) { 148 if (curr > prev) { 149 std::string elem = entryPoint.substr(prev, curr - prev); 150 if (elem == DOUBLE_POINT_TAG && entryPoint.at(curr) == SLASH_TAG 151 && !elems.empty()) { // looking for xxx/../ 152 elems.pop_back(); 153 } else if (elem != POINT_TAG && elem != DOUBLE_POINT_TAG) { // remove ./ 154 elems.push_back(elem); 155 } 156 } 157 prev = curr + 1; 158 curr = entryPoint.find(SLASH_TAG, prev); 159 } 160 if (prev != entryPoint.size()) { 161 elems.push_back(entryPoint.substr(prev)); 162 } 163 for (auto e : elems) { 164 if (res.size() == 0 && entryPoint.at(0) != SLASH_TAG) { 165 res.append(e); 166 continue; 167 } 168 res.append(1, SLASH_TAG).append(e); 169 } 170 // remore suffix 171 size_t pos = res.rfind(POINT_TAG); 172 if (pos != std::string::npos) { 173 std::string suffix = res.substr(pos); 174 if (suffix == EXT_NAME_ETS || suffix == EXT_NAME_TS || suffix == EXT_NAME_JS) { 175 res.erase(pos, suffix.length()); 176 } 177 } 178 return res; 179 } 180 181 /* 182 * Split the recordName of the new ohmurl rule 183 * recordName: &moduleName&bundleName&importPath&version 184 */ SplitNormalizedRecordName(const std::string & recordName)185 static std::vector<std::string> SplitNormalizedRecordName(const std::string &recordName) 186 { 187 std::vector<std::string> res(NORMALIZED_OHMURL_ARGS_NUM); 188 int index = NORMALIZED_OHMURL_ARGS_NUM - 1; 189 std::string temp; 190 int endIndex = static_cast<int>(recordName.size()) - 1; 191 for (int i = endIndex; i >= 0; i--) { 192 char element = recordName[i]; 193 if (element == NORMALIZED_OHMURL_TAG) { 194 res[index] = temp; 195 index--; 196 temp = ""; 197 continue; 198 } 199 temp = element + temp; 200 } 201 if (temp.size()) { 202 res[index] = temp; 203 } 204 return res; 205 } 206 }; 207 } // namespace Commonlibrary::Concurrent::Common::Helper 208 #endif // JS_CONCURRENT_MODULE_COMMON_HELPER_OBJECT_HELPER_H 209