From 20ae02dd184933fe75693a6e44b3d1f4ff58fe8c Mon Sep 17 00:00:00 2001 From: dy_study Date: Tue, 9 Aug 2022 19:59:59 +0800 Subject: [PATCH 1/4] =?UTF-8?q?IssueNo:#I5825N=20Description:=20=E4=B8=8D?= =?UTF-8?q?=E8=A7=A3=E5=8E=8BHAP=E5=8A=A0=E8=BD=BD=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20Sig:SIG=5FApplicationFramework=20Feature?= =?UTF-8?q?=20or=20Bugfix:Feature=20Binary=20Source:=20No?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dy_study Change-Id: I4255164c1df585e91f789f5b31d04c0eed976034 --- ability_runtime.gni | 1 + .../native/ability_runtime/js_ability.cpp | 2 +- .../native/form_runtime/js_form_extension.cpp | 2 +- .../ability/native/js_service_extension.cpp | 2 +- .../native/js_static_subscriber_extension.cpp | 2 +- .../runner_runtime/js_test_runner.cpp | 8 +- .../ability_runtime/app/js_ability_stage.cpp | 4 +- frameworks/native/appkit/app/main_thread.cpp | 2 + .../native/runtime/js_module_searcher.cpp | 91 ++++++++++--------- .../native/runtime/js_module_searcher.h | 9 ++ frameworks/native/runtime/js_runtime.cpp | 57 +++++++++--- .../native/runtime/js_runtime_utils.cpp | 42 +++++++++ .../native/runtime/runtime_extractor.cpp | 38 ++++++++ interfaces/inner_api/runtime/BUILD.gn | 30 +++++- .../inner_api/runtime/include/js_runtime.h | 12 +-- .../runtime/include/js_runtime_utils.h | 5 + .../inner_api/runtime/include/runtime.h | 1 + .../runtime/include/runtime_extractor.h | 38 ++++++++ .../runner_runtime/js_test_runner.h | 1 + .../common/include}/ability_constants.h | 2 + 20 files changed, 277 insertions(+), 72 deletions(-) create mode 100755 frameworks/native/runtime/runtime_extractor.cpp create mode 100755 interfaces/inner_api/runtime/include/runtime_extractor.h rename {interfaces/kits/native/appkit/ability_runtime/context => services/common/include}/ability_constants.h (95%) diff --git a/ability_runtime.gni b/ability_runtime.gni index 811145eef49..bebd583ee03 100644 --- a/ability_runtime.gni +++ b/ability_runtime.gni @@ -25,6 +25,7 @@ ace_engine_path = "//foundation/arkui/ace_engine" bundlefwk_path = "//foundation/bundlemanager/bundle_framework" bundlefwk_inner_api_path = "${bundlefwk_path}/interfaces/inner_api" +bundlefwk_services_path = "${bundlefwk_path}/services" multimedia_path = "//foundation/multimedia/image_standard" multimodalinput_path = "//foundation/multimodalinput/input" diff --git a/frameworks/native/ability/native/ability_runtime/js_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ability.cpp index c0fb7a80284..b1670cd8d85 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability.cpp @@ -113,7 +113,7 @@ void JsAbility::Init(const std::shared_ptr &abilityInfo, auto &engine = jsRuntime_.GetNativeEngine(); jsAbilityObj_ = - jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE); + jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, abilityInfo->hapPath); if (jsAbilityObj_ == nullptr) { HILOG_ERROR("Failed to get AbilityStage object"); return; diff --git a/frameworks/native/ability/native/form_runtime/js_form_extension.cpp b/frameworks/native/ability/native/form_runtime/js_form_extension.cpp index 63889b3f345..fa8740fdb76 100644 --- a/frameworks/native/ability/native/form_runtime/js_form_extension.cpp +++ b/frameworks/native/ability/native/form_runtime/js_form_extension.cpp @@ -92,7 +92,7 @@ void JsFormExtension::Init(const std::shared_ptr &record, HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/ability/native/js_service_extension.cpp b/frameworks/native/ability/native/js_service_extension.cpp index 8376805f17f..a17304d3158 100644 --- a/frameworks/native/ability/native/js_service_extension.cpp +++ b/frameworks/native/ability/native/js_service_extension.cpp @@ -90,7 +90,7 @@ void JsServiceExtension::Init(const std::shared_ptr &record, HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/ability/native/js_static_subscriber_extension.cpp b/frameworks/native/ability/native/js_static_subscriber_extension.cpp index 4a25b834ff8..aaecad01e8d 100644 --- a/frameworks/native/ability/native/js_static_subscriber_extension.cpp +++ b/frameworks/native/ability/native/js_static_subscriber_extension.cpp @@ -92,7 +92,7 @@ void JsStaticSubscriberExtension::Init(const std::shared_ptr HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp index dfaf7d7d7d8..40e9169e850 100644 --- a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp +++ b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp @@ -63,11 +63,13 @@ JsTestRunner::JsTestRunner( srcPath.append(".abc"); srcPath_ = srcPath; } - HILOG_INFO("JsTestRunner srcPath is %{public}s", srcPath_.c_str()); + HILOG_DEBUG("JsTestRunner srcPath is %{public}s", srcPath_.c_str()); if (!isFaJsModel) { std::string moduleName; + hapPath_ = bundleInfo.hapModuleInfos.back().hapPath; + HILOG_DEBUG("JsTestRunner hapPath is %{public}s", hapPath_.c_str()); jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, - bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE); + bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE, hapPath_); } } @@ -87,7 +89,7 @@ bool JsTestRunner::Initialize() HILOG_ERROR("mgmtResult init error"); return false; } - if (!jsRuntime_.RunSandboxScript(srcPath_)) { + if (!jsRuntime_.RunSandboxScript(srcPath_, hapPath_)) { HILOG_ERROR("RunScript srcPath_ err"); return false; } diff --git a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp index 6ea951aaa68..f2971a1a50a 100644 --- a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp @@ -69,7 +69,7 @@ std::shared_ptr JsAbilityStage::Create( std::string moduleName(hapModuleInfo.moduleName); moduleName.append("::").append("AbilityStage"); auto moduleObj = - jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE); + jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath); return std::make_shared(jsRuntime, std::move(moduleObj)); } @@ -82,7 +82,7 @@ std::shared_ptr JsAbilityStage::Create( std::string moduleName(hapModuleInfo.moduleName); moduleName.append("::").append("AbilityStage"); moduleObj = - jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE); + jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath); HILOG_INFO("JsAbilityStage srcPath is %{public}s", srcPath.c_str()); } return std::make_shared(jsRuntime, std::move(moduleObj)); diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index 26787b18fce..3e8b431a619 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -937,6 +937,7 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con AbilityRuntime::Runtime::Options options; options.bundleName = appInfo.bundleName; options.codePath = LOCAL_CODE_PATH; + options.hapPath = bundleInfo.hapModuleInfos.back().hapPath; options.eventRunner = mainHandler_->GetEventRunner(); options.loadAce = true; std::string nativeLibraryPath = appInfo.nativeLibraryPath; @@ -1225,6 +1226,7 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & AbilityRuntime::Runtime::Options options; options.codePath = LOCAL_CODE_PATH; options.eventRunner = mainHandler_->GetEventRunner(); + options.hapPath = bundleInfo.hapModuleInfos.back().hapPath; options.loadAce = false; if (bundleInfo.hapModuleInfos.empty() || bundleInfo.hapModuleInfos.front().abilityInfos.empty()) { HILOG_ERROR("Failed to abilityInfos"); diff --git a/frameworks/native/runtime/js_module_searcher.cpp b/frameworks/native/runtime/js_module_searcher.cpp index 2c44e47f989..d7af2b2e61a 100644 --- a/frameworks/native/runtime/js_module_searcher.cpp +++ b/frameworks/native/runtime/js_module_searcher.cpp @@ -20,6 +20,7 @@ #include #include "hilog_wrapper.h" +#include "js_runtime_utils.h" namespace OHOS { namespace AbilityRuntime { @@ -49,11 +50,6 @@ inline bool StringEndWith(const std::string& str, const char* endStr, size_t end return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0)); } -inline bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen) -{ - return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0)); -} - void SplitString(const std::string& str, std::vector& out, size_t pos = 0, const char* seps = "\\/") { if (str.empty() || pos >= str.length()) { @@ -101,44 +97,9 @@ inline std::string StripString(const std::string& str, const char* charSet = " \ std::string JsModuleSearcher::operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const { - HILOG_INFO("Search JS module (%{public}s, %{public}s) begin", - curJsModulePath.c_str(), newJsModuleUri.c_str()); - - std::string newJsModulePath; - - if (curJsModulePath.empty() || newJsModuleUri.empty()) { - return newJsModulePath; - } - std::string normalizeUri = newJsModuleUri; - replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/'); - - switch (normalizeUri[0]) { - case '.': { - newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri); - break; - } - case '@': { - newJsModulePath = ParseOhmUri(curJsModulePath, normalizeUri); - if (newJsModulePath.empty()) { - newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); - } - break; - } - default: { - newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); - break; - } - } - - FixExtName(newJsModulePath); - - HILOG_INFO("Search JS module (%{public}s, %{public}s) => %{public}s end", - curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str()); - - return newJsModulePath; + return ParseJsModuleUri(curJsModulePath, newJsModuleUri); } - void JsModuleSearcher::FixExtName(std::string& path) { if (path.empty()) { @@ -381,5 +342,53 @@ std::string JsModuleSearcher::ParseOhmUri(const std::string& curJsModulePath, co return FindNpmPackageInTopLevel(moduleInstallPath, JoinString(pathVector, '/', index + 1)); } + +std::string JsModuleSearcher::ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const +{ + HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) begin", curJsModulePath.c_str(), + newJsModuleUri.c_str()); + + std::string newJsModulePath; + if (curJsModulePath.empty() || newJsModuleUri.empty()) { + return newJsModulePath; + } + std::string normalizeUri = newJsModuleUri; + replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/'); + + switch (normalizeUri[0]) { + case '.': { + newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri); + break; + } + case '@': { + newJsModulePath = ParseOhmUri(curJsModulePath, normalizeUri); + if (newJsModulePath.empty()) { + newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); + } + break; + } + default: { + newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); + break; + } + } + + FixExtName(newJsModulePath); + HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) => %{public}s end", + curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str()); + return newJsModulePath; +} + +bool JsModuleSearcher::GetABCFileBuffer( + const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const +{ + std::string newJsModulePath = ParseJsModuleUri(curJsModulePath, newJsModuleUri); + + if (!GetABCFile(hapPath_, newJsModulePath, dest)) { + HILOG_ERROR("Get abc file failed"); + return false; + } + return true; +} } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/runtime/js_module_searcher.h b/frameworks/native/runtime/js_module_searcher.h index ce76271abd6..03790f2d470 100644 --- a/frameworks/native/runtime/js_module_searcher.h +++ b/frameworks/native/runtime/js_module_searcher.h @@ -16,6 +16,7 @@ #ifndef OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H #define OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H +#include #include namespace OHOS { @@ -23,6 +24,10 @@ namespace AbilityRuntime { class JsModuleSearcher final { public: explicit JsModuleSearcher(const std::string& bundleName) : bundleName_(bundleName) {} + explicit JsModuleSearcher(const std::string& bundleName, const std::string& hapPath) { + bundleName_ = bundleName; + hapPath_ = hapPath; + } ~JsModuleSearcher() = default; JsModuleSearcher(const JsModuleSearcher&) = default; @@ -31,6 +36,8 @@ public: JsModuleSearcher& operator=(JsModuleSearcher&&) = default; std::string operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; + bool GetABCFileBuffer( + const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const; private: static void FixExtName(std::string& path); @@ -42,8 +49,10 @@ private: static std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage); std::string ParseOhmUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; + std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; std::string bundleName_; + std::string hapPath_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index 7517137f3a2..a9d7f1659b6 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -22,6 +22,7 @@ #include #include + #include "connect_server_manager.h" #include "event_handler.h" #include "hdc_register.h" @@ -106,14 +107,25 @@ public: debugMode_ = true; } - bool RunScript(const std::string& path) override + bool RunScript(const std::string& path, const std::string& hapPath) override { - return nativeEngine_->RunScriptPath(path.c_str()) != nullptr; + bool result = false; + if (!hapPath.empty()) { + std::ostringstream outStreamForABC; + if (!GetABCFile(hapPath, path, outStreamForABC)) { + HILOG_ERROR("Get abc file failed"); + return result; + } + result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; //, (void *)outStreamForABC + } else { + result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; + } + return result; } - NativeValue* LoadJsModule(const std::string& path) override + NativeValue* LoadJsModule(const std::string& path, const std::string& hapPath) override { - if (!RunScript(path)) { + if (!RunScript(path, hapPath)) { HILOG_ERROR("Failed to run script: %{public}s", path.c_str()); return nullptr; } @@ -177,7 +189,11 @@ private: if (!options.preload) { bundleName_ = options.bundleName; - panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName)); + if (!options.hapPath.empty()) { + panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName, options.hapPath)); + } else { + panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName)); + } } return JsRuntime::Initialize(options); } @@ -226,7 +242,7 @@ void InitSyscapModule(NativeEngine& engine, NativeObject& globalObject) bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName) { std::string path(codePath); - path.append("/").append(modulePath); + path.append("/").append(modulePath);// phone/./ets/MainAbility6/MainAbility6.abc if (path.length() > PATH_MAX) { HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX); return false; @@ -468,13 +484,13 @@ void JsRuntime::Deinitialize() nativeEngine_.reset(); } -NativeValue* JsRuntime::LoadJsBundle(const std::string& path) +NativeValue* JsRuntime::LoadJsBundle(const std::string& path, const std::string& hapPath) { NativeObject* globalObj = ConvertNativeValueTo(nativeEngine_->GetGlobal()); NativeValue* exports = nativeEngine_->CreateObject(); globalObj->SetProperty("exports", exports); - if (!RunScript(path)) { + if (!RunScript(path, hapPath)) { HILOG_ERROR("Failed to run script: %{public}s", path.c_str()); return nullptr; } @@ -494,8 +510,8 @@ NativeValue* JsRuntime::LoadJsBundle(const std::string& path) return exportObj; } -std::unique_ptr JsRuntime::LoadModule( - const std::string& moduleName, const std::string& modulePath, bool esmodule) +std::unique_ptr JsRuntime::LoadModule(const std::string& moduleName, + const std::string& modulePath, bool esmodule, const std::string& hapPath) { HILOG_INFO("JsRuntime::LoadModule(%{public}s, %{public}s, %{public}s)", moduleName.c_str(), modulePath.c_str(), esmodule ? "true" : "false"); @@ -514,7 +530,7 @@ std::unique_ptr JsRuntime::LoadModule( return std::unique_ptr(); } - classValue = esmodule ? LoadJsModule(fileName) : LoadJsBundle(fileName); + classValue = esmodule ? LoadJsModule(fileName, hapPath) : LoadJsBundle(fileName, hapPath); if (classValue == nullptr) { return std::unique_ptr(); } @@ -550,12 +566,23 @@ std::unique_ptr JsRuntime::LoadSystemModule( return std::unique_ptr(nativeEngine_->CreateReference(instanceValue, 1)); } -bool JsRuntime::RunScript(const std::string& path) +bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath) { - return nativeEngine_->RunScript(path.c_str()) != nullptr; + bool result = false; + if (!hapPath.empty()) { + std::ostringstream outStreamForABC; + if (!GetABCFile(hapPath, path, outStreamForABC)) { + HILOG_ERROR("Get abc file failed"); + return result; + } + result = nativeEngine_->RunScript(path.c_str()) != nullptr; //, (void *)outStreamForABC + } else { + result = nativeEngine_->RunScript(path.c_str()) != nullptr; + } + return result; } -bool JsRuntime::RunSandboxScript(const std::string& path) +bool JsRuntime::RunSandboxScript(const std::string& path, const std::string& hapPath) { std::string fileName; if (!MakeFilePath(codePath_, path, fileName)) { @@ -563,7 +590,7 @@ bool JsRuntime::RunSandboxScript(const std::string& path) return false; } - if (!RunScript(fileName)) { + if (!RunScript(fileName, hapPath)) { HILOG_ERROR("Failed to run script: %{public}s", fileName.c_str()); return false; } diff --git a/frameworks/native/runtime/js_runtime_utils.cpp b/frameworks/native/runtime/js_runtime_utils.cpp index 109a756ccfc..31f3c652586 100644 --- a/frameworks/native/runtime/js_runtime_utils.cpp +++ b/frameworks/native/runtime/js_runtime_utils.cpp @@ -15,8 +15,12 @@ #include "js_runtime_utils.h" +#include + +#include "ability_constants.h" #include "hilog_wrapper.h" #include "js_runtime.h" +#include "runtime_extractor.h" namespace OHOS { namespace AbilityRuntime { @@ -38,6 +42,11 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na } // namespace // Help Functions +bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen) +{ + return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0)); +} + NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message) { return engine.CreateError(CreateJsValue(engine, errCode), CreateJsValue(engine, message)); @@ -237,5 +246,38 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na return CreateAsyncTaskWithLastParam(engine, lastParam, std::unique_ptr(), std::unique_ptr(), result); } + +bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest) +{ + if (hapPath.empty() || srcPath.empty()) { + HILOG_ERROR("GetABCFile::hapPath or srcPath is nullptr"); + return false; + } + + std::string loadPath; + if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { + std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + loadPath = std::regex_replace(hapPath, hapPattern, ""); + loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + + loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + } else { + loadPath = hapPath; + } + RuntimeExtractor runtimeExtractor(loadPath); + if (!runtimeExtractor.Init()) { + HILOG_ERROR("GetABCFile::Runtime extractor init failed"); + return false; + } + + std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); + relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + if (!runtimeExtractor.ExtractABCFile(relativePath, dest)) { + HILOG_ERROR("GetABCFile::Extract abc file failed"); + return false; + } + + return true; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/runtime_extractor.cpp b/frameworks/native/runtime/runtime_extractor.cpp new file mode 100755 index 00000000000..2b51e23cc65 --- /dev/null +++ b/frameworks/native/runtime/runtime_extractor.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "runtime_extractor.h" + +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +RuntimeExtractor::RuntimeExtractor(const std::string &source) : AppExecFwk::BaseExtractor(source) +{ + HILOG_DEBUG("RuntimeExtractor is created"); +} + +RuntimeExtractor::~RuntimeExtractor() +{ + HILOG_DEBUG("RuntimeExtractor destroyed"); +} + +bool RuntimeExtractor::ExtractABCFile(const std::string& srcPath, std::ostream &dest) const +{ + HILOG_DEBUG("%{public}s: hapPath is %{public}s", __func__, srcPath.c_str()); + return AppExecFwk::BaseExtractor::ExtractByName(srcPath, dest); +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index c1ee9caa044..b1740a1f35e 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -48,7 +48,6 @@ ohos_shared_library("runtime") { configs = [ ":runtime_config", "//arkcompiler/ets_runtime:ark_jsruntime_public_config", - "${ability_runtime_services_path}/common:common_config", ] public_configs = [ ":runtime_public_config" ] @@ -56,6 +55,7 @@ ohos_shared_library("runtime") { deps = [ "//arkcompiler/ets_runtime:libark_jsruntime", "//foundation/arkui/napi:ace_napi_ark", + ":runtime_extractor" ] external_deps = [ @@ -93,3 +93,31 @@ ohos_shared_library("runtime") { subsystem_name = "ability" part_name = "ability_runtime" } + +ohos_source_set("runtime_extractor") { + include_dirs = [ "include" ] + + sources = [ + "${ability_runtime_native_path}/runtime/runtime_extractor.cpp", + ] + + configs = [ + "${ability_runtime_services_path}/common:common_config", + ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + public_deps = [ + "${bundlefwk_services_path}/bundlemgr:parser_common", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/interfaces/inner_api/runtime/include/js_runtime.h b/interfaces/inner_api/runtime/include/js_runtime.h index a97f8884cce..d7d7191835c 100644 --- a/interfaces/inner_api/runtime/include/js_runtime.h +++ b/interfaces/inner_api/runtime/include/js_runtime.h @@ -55,8 +55,8 @@ public: return Language::JS; } - std::unique_ptr LoadModule( - const std::string& moduleName, const std::string& modulePath, bool esmodule = false); + std::unique_ptr LoadModule(const std::string& moduleName, + const std::string& modulePath, bool esmodule = false, const std::string& hapPath = nullptr); std::unique_ptr LoadSystemModule( const std::string& moduleName, NativeValue* const* argv = nullptr, size_t argc = 0); void PostTask(const std::function& task, const std::string& name, int64_t delayTime); @@ -65,8 +65,8 @@ public: std::string BuildJsStackTrace() override; void NotifyApplicationState(bool isBackground) override; - bool RunSandboxScript(const std::string& path); - virtual bool RunScript(const std::string& path) = 0; + bool RunSandboxScript(const std::string& path, const std::string& hapPath); + virtual bool RunScript(const std::string& path, const std::string& hapPath = nullptr) = 0; void PreloadSystemModule(const std::string& moduleName) override; @@ -76,8 +76,8 @@ protected: virtual bool Initialize(const Options& options); void Deinitialize(); - virtual NativeValue* LoadJsBundle(const std::string& path); - virtual NativeValue* LoadJsModule(const std::string& path) = 0; + virtual NativeValue* LoadJsBundle(const std::string& path, const std::string& hapPath); + virtual NativeValue* LoadJsModule(const std::string& path, const std::string& hapPath) = 0; bool isArkEngine_ = false; bool debugMode_ = false; diff --git a/interfaces/inner_api/runtime/include/js_runtime_utils.h b/interfaces/inner_api/runtime/include/js_runtime_utils.h index 0cb2b9b8555..706cce830de 100644 --- a/interfaces/inner_api/runtime/include/js_runtime_utils.h +++ b/interfaces/inner_api/runtime/include/js_runtime_utils.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "native_engine/native_engine.h" @@ -111,6 +112,8 @@ NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector& data) return arrayValue; } +bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen); +bool StringEndWith(const std::string& str, const char* endStr, size_t endStrLen); NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string()); void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name, NativeCallback func); void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter); @@ -184,6 +187,8 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, nullptr_t, nullptr_t, NativeValue** result); + +bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest); } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/runtime.h b/interfaces/inner_api/runtime/include/runtime.h index 090bfc56947..5fb3ccfd58f 100644 --- a/interfaces/inner_api/runtime/include/runtime.h +++ b/interfaces/inner_api/runtime/include/runtime.h @@ -34,6 +34,7 @@ public: std::string bundleName; std::string codePath; std::string packagePath; + std::string hapPath; std::shared_ptr eventRunner; bool loadAce = true; bool preload = false; diff --git a/interfaces/inner_api/runtime/include/runtime_extractor.h b/interfaces/inner_api/runtime/include/runtime_extractor.h new file mode 100755 index 00000000000..a76a9272dcd --- /dev/null +++ b/interfaces/inner_api/runtime/include/runtime_extractor.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_RUNTIME_EXTRACTOR_H +#define OHOS_ABILITY_RUNTIME_RUNTIME_EXTRACTOR_H + +#include "base_extractor.h" + +namespace OHOS { +namespace AbilityRuntime { +class RuntimeExtractor : public AppExecFwk::BaseExtractor { +public: + explicit RuntimeExtractor(const std::string &source); + virtual ~RuntimeExtractor() override; + + /** + * @brief Extract the abc file of a hap to dest stream. + * @param srcPath Indicates the src path of the abc file in hap. + * @param dest Indicates the obtained std::ostream object. + * @return Returns true if the Profile is successfully extracted; returns false otherwise. + */ + bool ExtractABCFile(const std::string& srcPath, std::ostream &dest) const; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_RUNTIME_EXTRACTOR_H diff --git a/interfaces/kits/native/appkit/ability_delegator/runner_runtime/js_test_runner.h b/interfaces/kits/native/appkit/ability_delegator/runner_runtime/js_test_runner.h index fd6025cb91c..11a7e22f0b3 100644 --- a/interfaces/kits/native/appkit/ability_delegator/runner_runtime/js_test_runner.h +++ b/interfaces/kits/native/appkit/ability_delegator/runner_runtime/js_test_runner.h @@ -69,6 +69,7 @@ private: JsRuntime &jsRuntime_; std::unique_ptr jsTestRunnerObj_; std::string srcPath_; + std::string hapPath_; bool isFaJsModel_ = false; }; } // namespace RunnerRuntime diff --git a/interfaces/kits/native/appkit/ability_runtime/context/ability_constants.h b/services/common/include/ability_constants.h similarity index 95% rename from interfaces/kits/native/appkit/ability_runtime/context/ability_constants.h rename to services/common/include/ability_constants.h index cd3a983357f..29707af6b35 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/ability_constants.h +++ b/services/common/include/ability_constants.h @@ -23,6 +23,8 @@ constexpr const char* ABS_CODE_PATH = "/data/app/el1/bundle/public"; constexpr const char* LOCAL_CODE_PATH = "/data/storage/el1/bundle"; constexpr const char* LOCAL_BUNDLES = "/data/bundles"; constexpr const char* FILE_SEPARATOR = "/"; + +constexpr const char SYSTEM_APP_PATH[] = "/system/app"; } // namespace Constants } // namespace AbilityRuntime } // namespace OHOS -- Gitee From e25916edc971d2ed01f76acee10d5186a66edd19 Mon Sep 17 00:00:00 2001 From: dy_study Date: Mon, 15 Aug 2022 15:10:23 +0800 Subject: [PATCH 2/4] Update unzip load code. Signed-off-by: dy_study Change-Id: I386bdc51a10afaaf0e5f30e84b1079b138b4b2c7 --- .../native/ability_runtime/js_ability.cpp | 3 +- .../native/form_runtime/js_form_extension.cpp | 3 +- .../ability/native/js_service_extension.cpp | 3 +- .../native/js_static_subscriber_extension.cpp | 3 +- .../runner_runtime/js_test_runner.cpp | 6 +- .../ability_runtime/app/js_ability_stage.cpp | 6 +- .../native/runtime/js_module_reader.cpp | 71 +++ frameworks/native/runtime/js_module_reader.h | 45 ++ .../native/runtime/js_module_searcher.cpp | 364 +------------- .../native/runtime/js_module_searcher.h | 23 +- frameworks/native/runtime/js_runtime.cpp | 69 +-- .../native/runtime/js_runtime_utils.cpp | 467 +++++++++++++++++- .../native/runtime/runtime_extractor.cpp | 6 - interfaces/inner_api/runtime/BUILD.gn | 25 +- .../inner_api/runtime/include/js_runtime.h | 4 +- .../runtime/include/js_runtime_utils.h | 17 +- .../runtime/include/runtime_extractor.h | 10 +- 17 files changed, 647 insertions(+), 478 deletions(-) create mode 100755 frameworks/native/runtime/js_module_reader.cpp create mode 100755 frameworks/native/runtime/js_module_reader.h diff --git a/frameworks/native/ability/native/ability_runtime/js_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ability.cpp index 0111d33a81f..db2867724c0 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability.cpp @@ -113,7 +113,8 @@ void JsAbility::Init(const std::shared_ptr &abilityInfo, auto &engine = jsRuntime_.GetNativeEngine(); jsAbilityObj_ = - jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, abilityInfo->hapPath); + jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->hapPath, + abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE); if (jsAbilityObj_ == nullptr) { HILOG_ERROR("Failed to get AbilityStage object"); return; diff --git a/frameworks/native/ability/native/form_runtime/js_form_extension.cpp b/frameworks/native/ability/native/form_runtime/js_form_extension.cpp index 2c0a29f4534..2b01a0d02ff 100644 --- a/frameworks/native/ability/native/form_runtime/js_form_extension.cpp +++ b/frameworks/native/ability/native/form_runtime/js_form_extension.cpp @@ -92,7 +92,8 @@ void JsFormExtension::Init(const std::shared_ptr &record, HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == CompileMode::ES_MODULE); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/ability/native/js_service_extension.cpp b/frameworks/native/ability/native/js_service_extension.cpp index a17304d3158..dca76a71c49 100644 --- a/frameworks/native/ability/native/js_service_extension.cpp +++ b/frameworks/native/ability/native/js_service_extension.cpp @@ -90,7 +90,8 @@ void JsServiceExtension::Init(const std::shared_ptr &record, HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == CompileMode::ES_MODULE); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/ability/native/js_static_subscriber_extension.cpp b/frameworks/native/ability/native/js_static_subscriber_extension.cpp index aaecad01e8d..2d1b65489c9 100644 --- a/frameworks/native/ability/native/js_static_subscriber_extension.cpp +++ b/frameworks/native/ability/native/js_static_subscriber_extension.cpp @@ -92,7 +92,8 @@ void JsStaticSubscriberExtension::Init(const std::shared_ptr HandleScope handleScope(jsRuntime_); auto& engine = jsRuntime_.GetNativeEngine(); - jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->compileMode == CompileMode::ES_MODULE, abilityInfo_->hapPath); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == CompileMode::ES_MODULE); if (jsObj_ == nullptr) { HILOG_ERROR("Failed to get jsObj_"); return; diff --git a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp index 40e9169e850..b1cdd70713b 100644 --- a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp +++ b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp @@ -68,8 +68,8 @@ JsTestRunner::JsTestRunner( std::string moduleName; hapPath_ = bundleInfo.hapModuleInfos.back().hapPath; HILOG_DEBUG("JsTestRunner hapPath is %{public}s", hapPath_.c_str()); - jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, - bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE, hapPath_); + jsTestRunnerObj_ = jsRuntime_.LoadModule(moduleName, srcPath_, hapPath_, + bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE); } } @@ -78,7 +78,7 @@ JsTestRunner::~JsTestRunner() = default; bool JsTestRunner::Initialize() { if (isFaJsModel_) { - if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc")) { + if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", hapPath_)) { HILOG_ERROR("RunScript err"); return false; } diff --git a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp index ba4d04b88b6..1b0ec10ae78 100644 --- a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp @@ -70,7 +70,8 @@ std::shared_ptr JsAbilityStage::Create( std::string moduleName(hapModuleInfo.moduleName); moduleName.append("::").append("AbilityStage"); auto moduleObj = - jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath); + jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath, + hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE); return std::make_shared(jsRuntime, std::move(moduleObj)); } @@ -83,7 +84,8 @@ std::shared_ptr JsAbilityStage::Create( std::string moduleName(hapModuleInfo.moduleName); moduleName.append("::").append("AbilityStage"); moduleObj = - jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, hapModuleInfo.hapPath); + jsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath, + hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE); HILOG_INFO("JsAbilityStage srcPath is %{public}s", srcPath.c_str()); } return std::make_shared(jsRuntime, std::move(moduleObj)); diff --git a/frameworks/native/runtime/js_module_reader.cpp b/frameworks/native/runtime/js_module_reader.cpp new file mode 100755 index 00000000000..fae8f6ead56 --- /dev/null +++ b/frameworks/native/runtime/js_module_reader.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_module_reader.h" + +#include "hilog_wrapper.h" +#include "js_runtime_utils.h" + +namespace OHOS { +namespace AbilityRuntime { +std::vector JsModuleReader::operator()( + const std::string& curJsModulePath, const std::string& newJsModuleUri) const +{ + HILOG_INFO("Read JS module (%{public}s, %{public}s) begin", curJsModulePath.c_str(), newJsModuleUri.c_str()); + + std::vector buffer; + if (curJsModulePath.empty() || newJsModuleUri.empty()) { + return buffer; + } + + std::string normalizeUri = newJsModuleUri; + std::replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/'); + + std::string newJsModulePath; + switch (normalizeUri[0]) { + case '.': { + newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri); + break; + } + case '@': { + newJsModulePath = ParseOhmUri(bundleName_, curJsModulePath, normalizeUri); + if (newJsModulePath.empty()) { + newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); + } + break; + } + default: { + newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); + break; + } + } + FixExtName(newJsModulePath); + + std::ostringstream dest; + if (!GetFileBufferFromHap(hapPath_, newJsModulePath, dest)) { + HILOG_ERROR("Get abc file failed"); + return buffer; + } + + const auto& outStr = dest.str(); + buffer.assign(outStr.begin(), outStr.end()); + + HILOG_INFO("Read JS module (%{public}s, %{public}s) => %{public}s end", + curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str()); + + return buffer; +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/runtime/js_module_reader.h b/frameworks/native/runtime/js_module_reader.h new file mode 100755 index 00000000000..fd5f47634f1 --- /dev/null +++ b/frameworks/native/runtime/js_module_reader.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_JS_MODULE_READER_H +#define OHOS_ABILITY_RUNTIME_JS_MODULE_READER_H + +#include +#include + +namespace OHOS { +namespace AbilityRuntime { +class JsModuleReader final { +public: + explicit JsModuleReader(const std::string& bundleName, const std::string& hapPath) + : bundleName_(bundleName), hapPath_(hapPath) + {} + ~JsModuleReader() = default; + + JsModuleReader(const JsModuleReader&) = default; + JsModuleReader(JsModuleReader&&) = default; + JsModuleReader& operator=(const JsModuleReader&) = default; + JsModuleReader& operator=(JsModuleReader&&) = default; + + std::vector operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; + +private: + std::string bundleName_; + std::string hapPath_; +}; +} // namespace AbilityRuntime +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_JS_MODULE_READER_H \ No newline at end of file diff --git a/frameworks/native/runtime/js_module_searcher.cpp b/frameworks/native/runtime/js_module_searcher.cpp index 7153b3cfb4b..486a33d9969 100644 --- a/frameworks/native/runtime/js_module_searcher.cpp +++ b/frameworks/native/runtime/js_module_searcher.cpp @@ -15,370 +15,32 @@ #include "js_module_searcher.h" -#include -#include -#include - #include "hilog_wrapper.h" #include "js_runtime_utils.h" -#ifdef WINDOWS_PLATFORM -#include - -namespace { -char* realpath(const char* path, char* resolvedPath) -{ - if (_access(path, 0) < 0) { - return nullptr; - } - if (strcpy_s(resolvedPath, PATH_MAX, path) != 0) { - return nullptr; - } - return resolvedPath; -} -} -#endif - namespace OHOS { namespace AbilityRuntime { -namespace { -constexpr char PREFIX_BUNDLE[] = "@bundle:"; -constexpr char PREFIX_MODULE[] = "@module:"; -constexpr char PREFIX_LOCAL[] = "@local:"; - -constexpr char NPM_PATH_SEGMENT[] = "node_modules"; - -constexpr char NPM_ENTRY_FILE[] = "index.abc"; -constexpr char NPM_ENTRY_LINK[] = "entry.txt"; - -constexpr char EXT_NAME_ABC[] = ".abc"; -constexpr char EXT_NAME_ETS[] = ".ets"; -constexpr char EXT_NAME_TS[] = ".ts"; -constexpr char EXT_NAME_JS[] = ".js"; - -constexpr size_t MAX_NPM_LEVEL = 1; - -inline bool StringEndWith(const std::string& str, const char* endStr, size_t endStrLen) -{ - size_t len = str.length(); - return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0)); -} - -void SplitString(const std::string& str, std::vector& out, size_t pos = 0, const char* seps = "\\/") -{ - if (str.empty() || pos >= str.length()) { - return; - } - - size_t startPos = pos; - size_t endPos = 0; - while ((endPos = str.find_first_of(seps, startPos)) != std::string::npos) { - if (endPos > startPos) { - out.emplace_back(str.substr(startPos, endPos - startPos)); - } - startPos = endPos + 1; - } - - if (startPos < str.length()) { - out.emplace_back(str.substr(startPos)); - } -} - -std::string JoinString(const std::vector& strs, char sep, size_t startIndex = 0) -{ - std::string out; - for (size_t index = startIndex; index < strs.size(); ++index) { - if (!strs[index].empty()) { - out.append(strs[index]) += sep; - } - } - if (!out.empty()) { - out.pop_back(); - } - return out; -} - -inline std::string StripString(const std::string& str, const char* charSet = " \t\n\r") -{ - size_t startPos = str.find_first_not_of(charSet); - if (startPos == std::string::npos) { - return std::string(); - } - - return str.substr(startPos, str.find_last_not_of(charSet) - startPos + 1); -} -} - std::string JsModuleSearcher::operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const { - return ParseJsModuleUri(curJsModulePath, newJsModuleUri); -} - -void JsModuleSearcher::FixExtName(std::string& path) -{ - if (path.empty()) { - return; - } - - if (StringEndWith(path, EXT_NAME_ABC, sizeof(EXT_NAME_ABC) - 1)) { - return; - } - - if (StringEndWith(path, EXT_NAME_ETS, sizeof(EXT_NAME_ETS) - 1)) { - path.erase(path.length() - (sizeof(EXT_NAME_ETS) - 1), sizeof(EXT_NAME_ETS) - 1); - } else if (StringEndWith(path, EXT_NAME_TS, sizeof(EXT_NAME_TS) - 1)) { - path.erase(path.length() - (sizeof(EXT_NAME_TS) - 1), sizeof(EXT_NAME_TS) - 1); - } else if (StringEndWith(path, EXT_NAME_JS, sizeof(EXT_NAME_JS) - 1)) { - path.erase(path.length() - (sizeof(EXT_NAME_JS) - 1), sizeof(EXT_NAME_JS) - 1); - } - - path.append(EXT_NAME_ABC); -} - -std::string JsModuleSearcher::GetInstallPath(const std::string& curJsModulePath, bool module) const -{ - size_t pos = std::string::npos; - if (StringStartWith(curJsModulePath, bundleInstallPath_.c_str(), bundleInstallPath_.length())) { - pos = bundleInstallPath_.length() - 1; - } else { - if (!StringStartWith(curJsModulePath, otherBundleInstallPath_.c_str(), otherBundleInstallPath_.length())) { - return std::string(); - } - - pos = curJsModulePath.find('/', otherBundleInstallPath_.length()); - if (pos == std::string::npos) { - return std::string(); - } - } - - if (module) { - pos = curJsModulePath.find('/', pos + 1); - if (pos == std::string::npos) { - return std::string(); - } - } - - return curJsModulePath.substr(0, pos + 1); -} - -std::string JsModuleSearcher::MakeNewJsModulePath( - const std::string& curJsModulePath, const std::string& newJsModuleUri) const -{ - std::string moduleInstallPath = GetInstallPath(curJsModulePath, true); - if (moduleInstallPath.empty()) { - return std::string(); - } - - std::vector pathVector; - SplitString(curJsModulePath, pathVector, moduleInstallPath.length()); - - if (pathVector.empty()) { - return std::string(); - } - - // Remove file name, reserve only dir name - pathVector.pop_back(); - - std::vector relativePathVector; - SplitString(newJsModuleUri, relativePathVector); - - for (auto& value : relativePathVector) { - if (value == ".") { - continue; - } else if (value == "..") { - if (pathVector.empty()) { - return std::string(); - } - pathVector.pop_back(); - } else { - pathVector.emplace_back(std::move(value)); - } - } - - std::string jsModulePath = moduleInstallPath + JoinString(pathVector, '/'); - FixExtName(jsModulePath); - if (jsModulePath.size() >= PATH_MAX) { - return std::string(); - } - - char path[PATH_MAX]; - if (realpath(jsModulePath.c_str(), path) != nullptr) { - return std::string(path); - } - return std::string(); -} - -std::string JsModuleSearcher::FindNpmPackageInPath(const std::string& npmPath) const -{ - std::string fileName = npmPath + "/" + NPM_ENTRY_FILE; - - char path[PATH_MAX]; - if (fileName.size() >= PATH_MAX) { - return std::string(); - } - if (realpath(fileName.c_str(), path) != nullptr) { - return path; - } - - fileName = npmPath + "/" + NPM_ENTRY_LINK; - if (fileName.size() >= PATH_MAX) { - return std::string(); - } - if (realpath(fileName.c_str(), path) == nullptr) { - return std::string(); - } - - std::ifstream stream(path, std::ios::ate); - if (!stream.is_open()) { - return std::string(); - } - - auto fileLen = stream.tellg(); - if (fileLen >= PATH_MAX) { - return std::string(); - } - - stream.seekg(0); - stream.read(path, fileLen); - path[fileLen] = '\0'; - return npmPath + '/' + StripString(path); -} - -std::string JsModuleSearcher::FindNpmPackageInTopLevel( - const std::string& moduleInstallPath, const std::string& npmPackage, size_t start) const -{ - for (size_t level = start; level <= MAX_NPM_LEVEL; ++level) { - std::string path = moduleInstallPath + NPM_PATH_SEGMENT + '/' + std::to_string(level) + '/' + npmPackage; - path = FindNpmPackageInPath(path); - if (!path.empty()) { - return path; - } - } - - return std::string(); -} - -std::string JsModuleSearcher::FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage) const -{ - std::string newJsModulePath = MakeNewJsModulePath(curJsModulePath, npmPackage); - if (!newJsModulePath.empty()) { - return newJsModulePath; - } - std::string moduleInstallPath = GetInstallPath(curJsModulePath); - if (moduleInstallPath.empty()) { - return std::string(); - } - std::vector pathVector; - SplitString(curJsModulePath, pathVector, moduleInstallPath.length()); - if (pathVector.empty()) { - return std::string(); - } - - if (pathVector[0] != NPM_PATH_SEGMENT) { - return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage); - } - - // Remove file name, reserve only dir name - pathVector.pop_back(); - - // Find npm package until reach top level npm path such as 'node_modules/0', - // so there must be 2 element in vector - while (pathVector.size() > 2) { - std::string path = - moduleInstallPath + JoinString(pathVector, '/') + '/' + NPM_PATH_SEGMENT + '/' + npmPackage; - path = FindNpmPackageInPath(path); - if (!path.empty()) { - return path; - } - - pathVector.pop_back(); - } - - char* p = nullptr; - size_t index = std::strtoul(pathVector.back().c_str(), &p, 10); - if (p == nullptr || *p != '\0') { - return std::string(); - } - - return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage, index); -} - -std::string JsModuleSearcher::ParseOhmUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const -{ - std::string moduleInstallPath; - std::vector pathVector; - size_t index = 0; - - if (StringStartWith(newJsModuleUri, PREFIX_BUNDLE, sizeof(PREFIX_BUNDLE) - 1)) { - SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_BUNDLE) - 1); - - // Uri should have atleast 3 segments - if (pathVector.size() < 3) { - return std::string(); - } - - const auto& bundleName = pathVector[index++]; - if (bundleName == bundleName_) { - moduleInstallPath = bundleInstallPath_; - } else { - moduleInstallPath = otherBundleInstallPath_; - moduleInstallPath.append(bundleName).append("/"); - } - moduleInstallPath.append(pathVector[index++]).append("/"); - } else if (StringStartWith(newJsModuleUri, PREFIX_MODULE, sizeof(PREFIX_MODULE) - 1)) { - SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_MODULE) - 1); - - // Uri should have atleast 2 segments - if (pathVector.size() < 2) { - return std::string(); - } - - moduleInstallPath = GetInstallPath(curJsModulePath, false); - if (moduleInstallPath.empty()) { - return std::string(); - } - moduleInstallPath.append(pathVector[index++]).append("/"); - } else if (StringStartWith(newJsModuleUri, PREFIX_LOCAL, sizeof(PREFIX_LOCAL) - 1)) { - SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_LOCAL) - 1); - - if (pathVector.empty()) { - return std::string(); - } - - moduleInstallPath = GetInstallPath(curJsModulePath); - if (moduleInstallPath.empty()) { - return std::string(); - } - } else { - return std::string(); - } - - if (pathVector[index] != NPM_PATH_SEGMENT) { - return moduleInstallPath + JoinString(pathVector, '/', index); - } - - return FindNpmPackageInTopLevel(moduleInstallPath, JoinString(pathVector, '/', index + 1)); -} - -std::string JsModuleSearcher::ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const -{ - HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) begin", curJsModulePath.c_str(), - newJsModuleUri.c_str()); + HILOG_INFO("Search JS module (%{public}s, %{public}s) begin", + curJsModulePath.c_str(), newJsModuleUri.c_str()); std::string newJsModulePath; + if (curJsModulePath.empty() || newJsModuleUri.empty()) { return newJsModulePath; } std::string normalizeUri = newJsModuleUri; std::replace(normalizeUri.begin(), normalizeUri.end(), '\\', '/'); + switch (normalizeUri[0]) { case '.': { newJsModulePath = MakeNewJsModulePath(curJsModulePath, normalizeUri); break; } case '@': { - newJsModulePath = ParseOhmUri(curJsModulePath, normalizeUri); + newJsModulePath = ParseOhmUri(bundleName_, curJsModulePath, normalizeUri); if (newJsModulePath.empty()) { newJsModulePath = FindNpmPackage(curJsModulePath, normalizeUri); } @@ -391,21 +53,11 @@ std::string JsModuleSearcher::ParseJsModuleUri(const std::string& curJsModulePat } FixExtName(newJsModulePath); - HILOG_DEBUG("Search JS module ParseJsModuleUri (%{public}s, %{public}s) => %{public}s end", - curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str()); - return newJsModulePath; -} -bool JsModuleSearcher::GetABCFileBuffer( - const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const -{ - std::string newJsModulePath = ParseJsModuleUri(curJsModulePath, newJsModuleUri); + HILOG_INFO("Search JS module (%{public}s, %{public}s) => %{public}s end", + curJsModulePath.c_str(), normalizeUri.c_str(), newJsModulePath.c_str()); - if (!GetABCFile(hapPath_, newJsModulePath, dest)) { - HILOG_ERROR("Get abc file failed"); - return false; - } - return true; + return newJsModulePath; } } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/runtime/js_module_searcher.h b/frameworks/native/runtime/js_module_searcher.h index 8c60d8d26c3..1a844a17e48 100644 --- a/frameworks/native/runtime/js_module_searcher.h +++ b/frameworks/native/runtime/js_module_searcher.h @@ -16,18 +16,13 @@ #ifndef OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H #define OHOS_ABILITY_RUNTIME_JS_MODULE_SEARCHER_H -#include #include namespace OHOS { namespace AbilityRuntime { class JsModuleSearcher final { public: - explicit JsModuleSearcher(const std::string& bundleName, const std::string& hapPath, - const std::string& bundleInstallPath = "/data/storage/el1/bundle/", - const std::string& otherBundleInstallPath = "/data/bundles/") - : bundleName_(bundleName), hapPath_(hapPath), bundleInstallPath_(bundleInstallPath), - otherBundleInstallPath_(otherBundleInstallPath) + explicit JsModuleSearcher(const std::string& bundleName) : bundleName_(bundleName) {} ~JsModuleSearcher() = default; @@ -37,25 +32,9 @@ public: JsModuleSearcher& operator=(JsModuleSearcher&&) = default; std::string operator()(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; - bool GetABCFileBuffer( - const std::string& curJsModulePath, const std::string& newJsModuleUri, std::ostream &dest) const; private: - static void FixExtName(std::string& path); - - std::string GetInstallPath(const std::string& curJsModulePath, bool module = true) const; - std::string MakeNewJsModulePath(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; - std::string FindNpmPackageInPath(const std::string& npmPath) const; - std::string FindNpmPackageInTopLevel( - const std::string& moduleInstallPath, const std::string& npmPackage, size_t start = 0) const; - std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage) const; - std::string ParseOhmUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; - std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri) const; - std::string bundleName_; - std::string hapPath_; - std::string bundleInstallPath_; - std::string otherBundleInstallPath_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index 2e18dcae4a4..93b8ffc0320 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -22,13 +22,13 @@ #include #include - #include "connect_server_manager.h" #include "event_handler.h" #include "hdc_register.h" #include "hilog_wrapper.h" #include "js_console_log.h" #include "js_module_searcher.h" +#include "js_module_reader.h" #include "js_runtime_utils.h" #include "js_timer.h" #include "js_worker.h" @@ -111,12 +111,17 @@ public: { bool result = false; if (!hapPath.empty()) { - std::ostringstream outStreamForABC; - if (!GetABCFile(hapPath, path, outStreamForABC)) { + std::ostringstream outStream; + if (!GetFileBufferFromHap(hapPath, path, outStream)) { HILOG_ERROR("Get abc file failed"); return result; } - result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; //, (void *)outStreamForABC + + const auto& outStr = outStream.str(); + std::vector buffer; + buffer.assign(outStr.begin(), outStr.end()); + + result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr; } else { result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; } @@ -189,7 +194,8 @@ private: if (!options.preload) { bundleName_ = options.bundleName; - panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName, options.hapPath)); + panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName)); + panda::JSNApi::SetHostResolveBufferTracker(vm_, JsModuleReader(options.bundleName, options.hapPath)); } return JsRuntime::Initialize(options); } @@ -234,46 +240,6 @@ void InitSyscapModule(NativeEngine& engine, NativeObject& globalObject) { BindNativeFunction(engine, globalObject, "canIUse", CanIUse); } - -bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName) -{ - std::string path(codePath); - path.append("/").append(modulePath);// phone/./ets/MainAbility6/MainAbility6.abc - if (path.length() > PATH_MAX) { - HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX); - return false; - } - char resolvedPath[PATH_MAX + 1] = { 0 }; - if (realpath(path.c_str(), resolvedPath) != nullptr) { - fileName = resolvedPath; - return true; - } - - auto start = path.find_last_of('/'); - auto end = path.find_last_of('.'); - if (end == std::string::npos || end == 0) { - HILOG_ERROR("No secondary file path"); - return false; - } - - auto pos = path.find_last_of('.', end - 1); - if (pos == std::string::npos) { - HILOG_ERROR("No secondary file path"); - return false; - } - - path.erase(start + 1, pos - start); - HILOG_INFO("Try using secondary file path: %{public}s", path.c_str()); - - if (realpath(path.c_str(), resolvedPath) == nullptr) { - HILOG_ERROR("Failed to call realpath, errno = %{public}d", errno); - return false; - } - - fileName = resolvedPath; - return true; -} - class UvLoopHandler : public AppExecFwk::FileDescriptorListener, public std::enable_shared_from_this { public: explicit UvLoopHandler(uv_loop_t* uvLoop) : uvLoop_(uvLoop) {} @@ -507,7 +473,7 @@ NativeValue* JsRuntime::LoadJsBundle(const std::string& path, const std::string& } std::unique_ptr JsRuntime::LoadModule(const std::string& moduleName, - const std::string& modulePath, bool esmodule, const std::string& hapPath) + const std::string& modulePath, const std::string& hapPath, bool esmodule) { HILOG_INFO("JsRuntime::LoadModule(%{public}s, %{public}s, %{public}s)", moduleName.c_str(), modulePath.c_str(), esmodule ? "true" : "false"); @@ -566,12 +532,17 @@ bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath) { bool result = false; if (!hapPath.empty()) { - std::ostringstream outStreamForABC; - if (!GetABCFile(hapPath, path, outStreamForABC)) { + std::ostringstream outStream; + if (!GetFileBufferFromHap(hapPath, path, outStream)) { HILOG_ERROR("Get abc file failed"); return result; } - result = nativeEngine_->RunScript(path.c_str()) != nullptr; //, (void *)outStreamForABC + + const auto& outStr = outStream.str(); + std::vector buffer; + buffer.assign(outStr.begin(), outStr.end()); + + result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr; } else { result = nativeEngine_->RunScript(path.c_str()) != nullptr; } diff --git a/frameworks/native/runtime/js_runtime_utils.cpp b/frameworks/native/runtime/js_runtime_utils.cpp index 31f3c652586..f179c8dedb4 100644 --- a/frameworks/native/runtime/js_runtime_utils.cpp +++ b/frameworks/native/runtime/js_runtime_utils.cpp @@ -15,16 +15,49 @@ #include "js_runtime_utils.h" +#include #include +#include #include "ability_constants.h" #include "hilog_wrapper.h" #include "js_runtime.h" #include "runtime_extractor.h" +#ifdef WINDOWS_PLATFORM +#include + +namespace { +char* realpath(const char* path, char* resolvedPath) +{ + if (_access(path, 0) < 0) { + return nullptr; + } + if (strcpy_s(resolvedPath, PATH_MAX, path) != 0) { + return nullptr; + } + return resolvedPath; +} +} +#endif namespace OHOS { namespace AbilityRuntime { namespace { +constexpr char EXT_NAME_ABC[] = ".abc"; +constexpr char EXT_NAME_ETS[] = ".ets"; +constexpr char EXT_NAME_TS[] = ".ts"; +constexpr char EXT_NAME_JS[] = ".js"; +constexpr char PREFIX_BUNDLE[] = "@bundle:"; +constexpr char PREFIX_MODULE[] = "@module:"; +constexpr char PREFIX_LOCAL[] = "@local:"; +constexpr char NPM_PATH_SEGMENT[] = "node_modules"; +constexpr char NPM_ENTRY_FILE[] = "index.abc"; +constexpr char NPM_ENTRY_LINK[] = "entry.txt"; +constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/"; +constexpr char OTHER_BUNDLE_INSTALL_PATH[] = "/data/bundles/"; + +constexpr size_t MAX_NPM_LEVEL = 1; + std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, std::unique_ptr&& execute, std::unique_ptr&& complete, NativeValue** result) @@ -39,14 +72,64 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na return std::make_unique(callbackRef, std::move(execute), std::move(complete)); } } -} // namespace -// Help Functions -bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen) +inline bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen) { return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0)); } +inline bool StringEndWith(const std::string& str, const char* endStr, size_t endStrLen) +{ + size_t len = str.length(); + return ((len >= endStrLen) && (str.compare(len - endStrLen, endStrLen, endStr) == 0)); +} + +void SplitString(const std::string& str, std::vector& out, size_t pos = 0, const char* seps = "\\/") +{ + if (str.empty() || pos >= str.length()) { + return; + } + + size_t startPos = pos; + size_t endPos = 0; + while ((endPos = str.find_first_of(seps, startPos)) != std::string::npos) { + if (endPos > startPos) { + out.emplace_back(str.substr(startPos, endPos - startPos)); + } + startPos = endPos + 1; + } + + if (startPos < str.length()) { + out.emplace_back(str.substr(startPos)); + } +} + +std::string JoinString(const std::vector& strs, char sep, size_t startIndex = 0) +{ + std::string out; + for (size_t index = startIndex; index < strs.size(); ++index) { + if (!strs[index].empty()) { + out.append(strs[index]) += sep; + } + } + if (!out.empty()) { + out.pop_back(); + } + return out; +} + +inline std::string StripString(const std::string& str, const char* charSet = " \t\n\r") +{ + size_t startPos = str.find_first_not_of(charSet); + if (startPos == std::string::npos) { + return std::string(); + } + + return str.substr(startPos, str.find_last_not_of(charSet) - startPos + 1); +} +} // namespace + +// Help Functions NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message) { return engine.CreateError(CreateJsValue(engine, errCode), CreateJsValue(engine, message)); @@ -247,10 +330,365 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na std::unique_ptr(), result); } -bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest) +void FixExtName(std::string& path) +{ + if (path.empty()) { + return; + } + + if (StringEndWith(path, EXT_NAME_ABC, sizeof(EXT_NAME_ABC) - 1)) { + return; + } + + if (StringEndWith(path, EXT_NAME_ETS, sizeof(EXT_NAME_ETS) - 1)) { + path.erase(path.length() - (sizeof(EXT_NAME_ETS) - 1), sizeof(EXT_NAME_ETS) - 1); + } else if (StringEndWith(path, EXT_NAME_TS, sizeof(EXT_NAME_TS) - 1)) { + path.erase(path.length() - (sizeof(EXT_NAME_TS) - 1), sizeof(EXT_NAME_TS) - 1); + } else if (StringEndWith(path, EXT_NAME_JS, sizeof(EXT_NAME_JS) - 1)) { + path.erase(path.length() - (sizeof(EXT_NAME_JS) - 1), sizeof(EXT_NAME_JS) - 1); + } + + path.append(EXT_NAME_ABC); +} + +std::string GetInstallPath(const std::string& curJsModulePath, bool module) +{ + size_t pos = std::string::npos; + if (StringStartWith(curJsModulePath, BUNDLE_INSTALL_PATH, std::string(BUNDLE_INSTALL_PATH).length())) { + pos = std::string(BUNDLE_INSTALL_PATH).length() - 1; + } else { + if (!StringStartWith(curJsModulePath, OTHER_BUNDLE_INSTALL_PATH, + std::string(OTHER_BUNDLE_INSTALL_PATH).length())) { + return std::string(); + } + + pos = curJsModulePath.find('/', std::string(OTHER_BUNDLE_INSTALL_PATH).length()); + if (pos == std::string::npos) { + return std::string(); + } + } + + if (module) { + pos = curJsModulePath.find('/', pos + 1); + if (pos == std::string::npos) { + return std::string(); + } + } + + return curJsModulePath.substr(0, pos + 1); +} + +std::string MakeNewJsModulePath( + const std::string& curJsModulePath, const std::string& newJsModuleUri) +{ + std::string moduleInstallPath = GetInstallPath(curJsModulePath, true); + if (moduleInstallPath.empty()) { + return std::string(); + } + + std::vector pathVector; + SplitString(curJsModulePath, pathVector, moduleInstallPath.length()); + + if (pathVector.empty()) { + return std::string(); + } + + // Remove file name, reserve only dir name + pathVector.pop_back(); + + std::vector relativePathVector; + SplitString(newJsModuleUri, relativePathVector); + + for (auto& value : relativePathVector) { + if (value == ".") { + continue; + } else if (value == "..") { + if (pathVector.empty()) { + return std::string(); + } + pathVector.pop_back(); + } else { + pathVector.emplace_back(std::move(value)); + } + } + + std::string jsModulePath = moduleInstallPath + JoinString(pathVector, '/'); + FixExtName(jsModulePath); + if (jsModulePath.size() >= PATH_MAX) { + return std::string(); + } + + char path[PATH_MAX]; + if (realpath(jsModulePath.c_str(), path) != nullptr) { + return std::string(path); + } + return std::string(); +} + +std::string FindNpmPackageInPath(const std::string& npmPath) +{ + std::string fileName = npmPath + "/" + NPM_ENTRY_FILE; + + char path[PATH_MAX]; + if (fileName.size() >= PATH_MAX) { + return std::string(); + } + if (realpath(fileName.c_str(), path) != nullptr) { + return path; + } + + fileName = npmPath + "/" + NPM_ENTRY_LINK; + if (fileName.size() >= PATH_MAX) { + return std::string(); + } + if (realpath(fileName.c_str(), path) == nullptr) { + return std::string(); + } + + std::ifstream stream(path, std::ios::ate); + if (!stream.is_open()) { + return std::string(); + } + + auto fileLen = stream.tellg(); + if (fileLen >= PATH_MAX) { + return std::string(); + } + + stream.seekg(0); + stream.read(path, fileLen); + path[fileLen] = '\0'; + return npmPath + '/' + StripString(path); +} + +std::string FindNpmPackageInTopLevel( + const std::string& moduleInstallPath, const std::string& npmPackage, size_t start) +{ + for (size_t level = start; level <= MAX_NPM_LEVEL; ++level) { + std::string path = moduleInstallPath + NPM_PATH_SEGMENT + '/' + std::to_string(level) + '/' + npmPackage; + path = FindNpmPackageInPath(path); + if (!path.empty()) { + return path; + } + } + + return std::string(); +} + +std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage) +{ + std::string newJsModulePath = MakeNewJsModulePath(curJsModulePath, npmPackage); + if (!newJsModulePath.empty()) { + return newJsModulePath; + } + std::string moduleInstallPath = GetInstallPath(curJsModulePath); + if (moduleInstallPath.empty()) { + return std::string(); + } + std::vector pathVector; + SplitString(curJsModulePath, pathVector, moduleInstallPath.length()); + if (pathVector.empty()) { + return std::string(); + } + + if (pathVector[0] != NPM_PATH_SEGMENT) { + return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage); + } + + // Remove file name, reserve only dir name + pathVector.pop_back(); + + // Find npm package until reach top level npm path such as 'node_modules/0', + // so there must be 2 element in vector + while (pathVector.size() > 2) { + std::string path = + moduleInstallPath + JoinString(pathVector, '/') + '/' + NPM_PATH_SEGMENT + '/' + npmPackage; + path = FindNpmPackageInPath(path); + if (!path.empty()) { + return path; + } + + pathVector.pop_back(); + } + + char* p = nullptr; + size_t index = std::strtoul(pathVector.back().c_str(), &p, 10); + if (p == nullptr || *p != '\0') { + return std::string(); + } + + return FindNpmPackageInTopLevel(moduleInstallPath, npmPackage, index); +} + +std::string ParseOhmUri( + const std::string originBundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri) +{ + std::string moduleInstallPath; + std::vector pathVector; + size_t index = 0; + + if (StringStartWith(newJsModuleUri, PREFIX_BUNDLE, sizeof(PREFIX_BUNDLE) - 1)) { + SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_BUNDLE) - 1); + + // Uri should have atleast 3 segments + if (pathVector.size() < 3) { + return std::string(); + } + + const auto& bundleName = pathVector[index++]; + if (bundleName == originBundleName) { + moduleInstallPath = std::string(BUNDLE_INSTALL_PATH); + } else { + moduleInstallPath = std::string(OTHER_BUNDLE_INSTALL_PATH); + moduleInstallPath.append(bundleName).append("/"); + } + moduleInstallPath.append(pathVector[index++]).append("/"); + } else if (StringStartWith(newJsModuleUri, PREFIX_MODULE, sizeof(PREFIX_MODULE) - 1)) { + SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_MODULE) - 1); + + // Uri should have atleast 2 segments + if (pathVector.size() < 2) { + return std::string(); + } + + moduleInstallPath = GetInstallPath(curJsModulePath, false); + if (moduleInstallPath.empty()) { + return std::string(); + } + moduleInstallPath.append(pathVector[index++]).append("/"); + } else if (StringStartWith(newJsModuleUri, PREFIX_LOCAL, sizeof(PREFIX_LOCAL) - 1)) { + SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_LOCAL) - 1); + + if (pathVector.empty()) { + return std::string(); + } + + moduleInstallPath = GetInstallPath(curJsModulePath); + if (moduleInstallPath.empty()) { + return std::string(); + } + } else { + return std::string(); + } + + if (pathVector[index] != NPM_PATH_SEGMENT) { + return moduleInstallPath + JoinString(pathVector, '/', index); + } + + return FindNpmPackageInTopLevel(moduleInstallPath, JoinString(pathVector, '/', index + 1)); +} + +bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName) +{ + std::string path(codePath); + path.append("/").append(modulePath); + if (path.length() > PATH_MAX) { + HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX); + return false; + } + char resolvedPath[PATH_MAX + 1] = { 0 }; + if (realpath(path.c_str(), resolvedPath) != nullptr) { + fileName = resolvedPath; + return true; + } + + auto start = path.find_last_of('/'); + auto end = path.find_last_of('.'); + if (end == std::string::npos || end == 0) { + HILOG_ERROR("No secondary file path"); + return false; + } + + auto pos = path.find_last_of('.', end - 1); + if (pos == std::string::npos) { + HILOG_ERROR("No secondary file path"); + return false; + } + + path.erase(start + 1, pos - start); + HILOG_INFO("Try using secondary file path: %{public}s", path.c_str()); + + if (realpath(path.c_str(), resolvedPath) == nullptr) { + HILOG_ERROR("Failed to call realpath, errno = %{public}d", errno); + return false; + } + + fileName = resolvedPath; + return true; +} + +std::string GetOhmUri(const std::shared_ptr &abilityInfo) +{ + std::string ohmUri; + if (!abilityInfo) { + HILOG_ERROR("GetOhmUri::AbilityInfo is nullptr"); + return ohmUri; + } + + std::string srcPath(abilityInfo->package); + if (!abilityInfo->isModuleJson) { + /* temporary compatibility api8 + config.json */ + srcPath.append("/assets/js/"); + if (!abilityInfo->srcPath.empty()) { + srcPath.append(abilityInfo->srcPath); + } + srcPath.append("/").append(abilityInfo->name).append(".abc"); + } else { + if (abilityInfo->srcEntrance.empty()) { + HILOG_ERROR("GetOhmUri::AbilityInfo srcEntrance is empty"); + return ohmUri; + } + srcPath.append("/"); + srcPath.append(abilityInfo->srcEntrance); + srcPath.erase(srcPath.rfind(".")); + srcPath.append(".abc"); + } + HILOG_DEBUG("GetOhmUri::JsAbility srcPath is %{public}s", srcPath.c_str()); + + if (!MakeFilePath(Constants::LOCAL_CODE_PATH, srcPath, ohmUri)) { + HILOG_ERROR("GetOhmUri::Failed to make module file path: %{private}s", srcPath.c_str()); + } + + return ohmUri; +} + +bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest) +{ + if (hapPath.empty() || srcPath.empty()) { + HILOG_ERROR("GetFileBufferFromHap::hapPath or srcPath is nullptr"); + return false; + } + + std::string loadPath; + if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { + std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + loadPath = std::regex_replace(hapPath, hapPattern, ""); + loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + + loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + } else { + loadPath = hapPath; + } + RuntimeExtractor runtimeExtractor(loadPath); + if (!runtimeExtractor.Init()) { + HILOG_ERROR("GetFileBufferFromHap::Runtime extractor init failed"); + return false; + } + + std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); + relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + if (!runtimeExtractor.ExtractByName(relativePath, dest)) { + HILOG_ERROR("GetFileBufferFromHap::Extract abc file failed"); + return false; + } + + return true; +} + +bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList) { if (hapPath.empty() || srcPath.empty()) { - HILOG_ERROR("GetABCFile::hapPath or srcPath is nullptr"); + HILOG_ERROR("GetFileListFromHap::hapPath or srcPath is nullptr"); return false; } @@ -265,18 +703,31 @@ bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ost } RuntimeExtractor runtimeExtractor(loadPath); if (!runtimeExtractor.Init()) { - HILOG_ERROR("GetABCFile::Runtime extractor init failed"); + HILOG_ERROR("GetFileListFromHap::Runtime extractor init failed"); return false; } std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - if (!runtimeExtractor.ExtractABCFile(relativePath, dest)) { - HILOG_ERROR("GetABCFile::Extract abc file failed"); + + std::vector fileList; + if (!runtimeExtractor.GetZipFileNames(fileList)) { + HILOG_ERROR("GetFileListFromHap::Get file list failed"); return false; } + std::regex replacePattern(relativePath); + for (auto value : fileList) { + if (StringStartWith(value, relativePath.c_str(), sizeof(relativePath.c_str()) - 1)) { + std::string realpath = std::regex_replace(value, replacePattern, ""); + if (realpath.find(Constants::FILE_SEPARATOR) != std::string::npos) { + continue; + } + assetList.emplace_back(value); + } + } + return true; } } // namespace AbilityRuntime diff --git a/frameworks/native/runtime/runtime_extractor.cpp b/frameworks/native/runtime/runtime_extractor.cpp index 2b51e23cc65..831cee93a45 100755 --- a/frameworks/native/runtime/runtime_extractor.cpp +++ b/frameworks/native/runtime/runtime_extractor.cpp @@ -28,11 +28,5 @@ RuntimeExtractor::~RuntimeExtractor() { HILOG_DEBUG("RuntimeExtractor destroyed"); } - -bool RuntimeExtractor::ExtractABCFile(const std::string& srcPath, std::ostream &dest) const -{ - HILOG_DEBUG("%{public}s: hapPath is %{public}s", __func__, srcPath.c_str()); - return AppExecFwk::BaseExtractor::ExtractByName(srcPath, dest); -} } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index b1740a1f35e..e5b82d43f75 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -37,6 +37,7 @@ ohos_shared_library("runtime") { "${ability_runtime_native_path}/runtime/hdc_register.cpp", "${ability_runtime_native_path}/runtime/js_console_log.cpp", "${ability_runtime_native_path}/runtime/js_data_struct_converter.cpp", + "${ability_runtime_native_path}/runtime/js_module_reader.cpp", "${ability_runtime_native_path}/runtime/js_module_searcher.cpp", "${ability_runtime_native_path}/runtime/js_runtime.cpp", "${ability_runtime_native_path}/runtime/js_runtime_utils.cpp", @@ -53,11 +54,14 @@ ohos_shared_library("runtime") { public_configs = [ ":runtime_public_config" ] deps = [ + ":runtime_extractor", "//arkcompiler/ets_runtime:libark_jsruntime", "//foundation/arkui/napi:ace_napi_ark", - ":runtime_extractor" ] + public_deps = + [ "${bundlefwk_inner_api_path}/appexecfwk_base:appexecfwk_base" ] + external_deps = [ "ability_base:base", "ability_base:configuration", @@ -65,7 +69,6 @@ ohos_shared_library("runtime") { "ability_base:zuri", "ability_runtime:ability_manager", "ability_runtime:app_manager", - "bundle_framework:appexecfwk_base", "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "napi:ace_napi", @@ -97,26 +100,18 @@ ohos_shared_library("runtime") { ohos_source_set("runtime_extractor") { include_dirs = [ "include" ] - sources = [ - "${ability_runtime_native_path}/runtime/runtime_extractor.cpp", - ] + sources = [ "${ability_runtime_native_path}/runtime/runtime_extractor.cpp" ] - configs = [ - "${ability_runtime_services_path}/common:common_config", - ] + configs = [ "${ability_runtime_services_path}/common:common_config" ] cflags = [] if (target_cpu == "arm") { cflags += [ "-DBINDER_IPC_32BIT" ] } - public_deps = [ - "${bundlefwk_services_path}/bundlemgr:parser_common", - ] - - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - ] + public_deps = [ "${bundlefwk_services_path}/bundlemgr:parser_common" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] subsystem_name = "ability" part_name = "ability_runtime" diff --git a/interfaces/inner_api/runtime/include/js_runtime.h b/interfaces/inner_api/runtime/include/js_runtime.h index d7d7191835c..19631c7a879 100644 --- a/interfaces/inner_api/runtime/include/js_runtime.h +++ b/interfaces/inner_api/runtime/include/js_runtime.h @@ -56,7 +56,7 @@ public: } std::unique_ptr LoadModule(const std::string& moduleName, - const std::string& modulePath, bool esmodule = false, const std::string& hapPath = nullptr); + const std::string& modulePath, const std::string& hapPath, bool esmodule = false); std::unique_ptr LoadSystemModule( const std::string& moduleName, NativeValue* const* argv = nullptr, size_t argc = 0); void PostTask(const std::function& task, const std::string& name, int64_t delayTime); @@ -66,7 +66,7 @@ public: void NotifyApplicationState(bool isBackground) override; bool RunSandboxScript(const std::string& path, const std::string& hapPath); - virtual bool RunScript(const std::string& path, const std::string& hapPath = nullptr) = 0; + virtual bool RunScript(const std::string& path, const std::string& hapPath) = 0; void PreloadSystemModule(const std::string& moduleName) override; diff --git a/interfaces/inner_api/runtime/include/js_runtime_utils.h b/interfaces/inner_api/runtime/include/js_runtime_utils.h index 9091fb79358..146b74210c5 100644 --- a/interfaces/inner_api/runtime/include/js_runtime_utils.h +++ b/interfaces/inner_api/runtime/include/js_runtime_utils.h @@ -23,6 +23,7 @@ #include "native_engine/native_engine.h" +#include "ability_info.h" #include "js_runtime.h" namespace OHOS { @@ -112,7 +113,6 @@ NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector& data) return arrayValue; } -bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen); NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string()); void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name, NativeCallback func); void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter); @@ -187,7 +187,20 @@ std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, Na std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, nullptr_t, nullptr_t, NativeValue** result); -bool GetABCFile(const std::string& hapPath, const std::string& srcPath, std::ostream &dest); +void FixExtName(std::string& path); +std::string GetInstallPath(const std::string& curJsModulePath, bool module = true); +std::string MakeNewJsModulePath(const std::string& curJsModulePath, const std::string& newJsModuleUri); +std::string FindNpmPackageInPath(const std::string& npmPath); +std::string FindNpmPackageInTopLevel( + const std::string& moduleInstallPath, const std::string& npmPackage, size_t start = 0); +std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage); +std::string ParseOhmUri( + const std::string bundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri); +std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri); +bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName); +std::string GetOhmUri(const std::shared_ptr &abilityInfo); +bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest); +bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList); } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/runtime_extractor.h b/interfaces/inner_api/runtime/include/runtime_extractor.h index a76a9272dcd..26c09333a77 100755 --- a/interfaces/inner_api/runtime/include/runtime_extractor.h +++ b/interfaces/inner_api/runtime/include/runtime_extractor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -24,14 +24,6 @@ class RuntimeExtractor : public AppExecFwk::BaseExtractor { public: explicit RuntimeExtractor(const std::string &source); virtual ~RuntimeExtractor() override; - - /** - * @brief Extract the abc file of a hap to dest stream. - * @param srcPath Indicates the src path of the abc file in hap. - * @param dest Indicates the obtained std::ostream object. - * @return Returns true if the Profile is successfully extracted; returns false otherwise. - */ - bool ExtractABCFile(const std::string& srcPath, std::ostream &dest) const; }; } // namespace AbilityRuntime } // namespace OHOS -- Gitee From c531a5407929ad41b6dde9b84bdadccd2e9ddd2d Mon Sep 17 00:00:00 2001 From: dy_study Date: Tue, 23 Aug 2022 18:33:58 +0800 Subject: [PATCH 3/4] Add base extractor. Signed-off-by: dy_study Change-Id: I732f8048df77f193030ca79977f20f5d0053e3b2 --- .../runner_runtime/js_test_runner.cpp | 2 +- frameworks/native/runtime/base_extractor.cpp | 137 ++++ frameworks/native/runtime/extractor_utils.cpp | 133 ++++ .../native/runtime/js_module_reader.cpp | 1 + frameworks/native/runtime/js_runtime.cpp | 1 + .../native/runtime/js_runtime_utils.cpp | 104 --- .../native/runtime/runtime_extractor.cpp | 4 +- frameworks/native/runtime/zip_file.cpp | 614 ++++++++++++++++++ .../simulator/ability_simulator/BUILD.gn | 7 +- .../ability_simulator/src/simulator.cpp | 1 - interfaces/inner_api/runtime/BUILD.gn | 35 +- .../runtime/include/base_extractor.h | 73 +++ .../runtime/include/extractor_utils.h | 31 + .../runtime/include/js_runtime_utils.h | 5 - .../runtime/include/runtime_extractor.h | 2 +- .../inner_api/runtime/include/zip_file.h | 308 +++++++++ 16 files changed, 1335 insertions(+), 123 deletions(-) create mode 100755 frameworks/native/runtime/base_extractor.cpp create mode 100755 frameworks/native/runtime/extractor_utils.cpp create mode 100755 frameworks/native/runtime/zip_file.cpp create mode 100755 interfaces/inner_api/runtime/include/base_extractor.h create mode 100755 interfaces/inner_api/runtime/include/extractor_utils.h create mode 100755 interfaces/inner_api/runtime/include/zip_file.h diff --git a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp index b1cdd70713b..1261da73ba8 100644 --- a/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp +++ b/frameworks/native/appkit/ability_delegator/runner_runtime/js_test_runner.cpp @@ -78,7 +78,7 @@ JsTestRunner::~JsTestRunner() = default; bool JsTestRunner::Initialize() { if (isFaJsModel_) { - if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", hapPath_)) { + if (!jsRuntime_.RunScript("/system/etc/strip.native.min.abc", "")) { HILOG_ERROR("RunScript err"); return false; } diff --git a/frameworks/native/runtime/base_extractor.cpp b/frameworks/native/runtime/base_extractor.cpp new file mode 100755 index 00000000000..d3ff4ae2333 --- /dev/null +++ b/frameworks/native/runtime/base_extractor.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base_extractor.h" + +#include + +#include "hilog_wrapper.h" +#include "string_ex.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char* MODULE_PROFILE_NAME = "module.json"; +} + +BaseExtractor::BaseExtractor(const std::string &source) : sourceFile_(source), zipFile_(source) +{ + HILOG_DEBUG("BaseExtractor instance is created"); +} + +BaseExtractor::~BaseExtractor() +{ + HILOG_DEBUG("BaseExtractor instance is destroyed"); +} + +bool BaseExtractor::Init() +{ + if (!zipFile_.Open()) { + HILOG_ERROR("open zip file failed"); + return false; + } + ZipEntry zipEntry; + isNewVersion_ = zipFile_.GetEntry(MODULE_PROFILE_NAME, zipEntry); + initial_ = true; + HILOG_DEBUG("success"); + return true; +} + +bool BaseExtractor::HasEntry(const std::string &fileName) const +{ + if (!initial_) { + HILOG_ERROR("extractor is not initial"); + return false; + } + + return zipFile_.HasEntry(fileName); +} + +bool BaseExtractor::IsDirExist(const std::string &dir) const +{ + if (!initial_) { + HILOG_ERROR("extractor is not initial"); + return false; + } + if (dir.empty()) { + HILOG_ERROR("param dir empty"); + return false; + } + return zipFile_.IsDirExist(dir); +} + +bool BaseExtractor::ExtractByName(const std::string &fileName, std::ostream &dest) const +{ + if (!initial_) { + HILOG_ERROR("extractor is not initial"); + return false; + } + if (!zipFile_.ExtractFile(fileName, dest)) { + HILOG_ERROR("extractor is not ExtractFile"); + return false; + } + return true; +} + +bool BaseExtractor::ExtractFile(const std::string &fileName, const std::string &targetPath) const +{ + HILOG_DEBUG("begin to extract %{public}s file into %{private}s targetPath", fileName.c_str(), targetPath.c_str()); + std::ofstream fileStream; + fileStream.open(targetPath, std::ios_base::out | std::ios_base::binary); + if (!fileStream.is_open()) { + HILOG_ERROR("fail to open %{private}s file to write", targetPath.c_str()); + return false; + } + if ((!ExtractByName(fileName, fileStream)) || (!fileStream.good())) { + HILOG_ERROR("fail to extract %{public}s zip file into stream", fileName.c_str()); + fileStream.clear(); + fileStream.close(); + if (remove(targetPath.c_str()) != 0) { + HILOG_ERROR("fail to remove %{private}s file which writes stream error", targetPath.c_str()); + } + return false; + } + fileStream.clear(); + fileStream.close(); + return true; +} + +bool BaseExtractor::GetZipFileNames(std::vector &fileNames) +{ + auto &entryMap = zipFile_.GetAllEntries(); + for (auto &entry : entryMap) { + fileNames.emplace_back(entry.first); + } + return true; +} + +bool BaseExtractor::IsStageBasedModel(std::string abilityName) +{ + auto &entryMap = zipFile_.GetAllEntries(); + std::vector splitStrs; + OHOS::SplitStr(abilityName, ".", splitStrs); + std::string name = splitStrs.empty() ? abilityName : splitStrs.back(); + std::string entry = "assets/js/" + name + "/" + name + ".js"; + bool isStageBasedModel = entryMap.find(entry) != entryMap.end(); + HILOG_DEBUG("name:%{public}s isStageBasedModel:%{public}d", abilityName.c_str(), isStageBasedModel); + return isStageBasedModel; +} + +bool BaseExtractor::IsNewVersion() const +{ + return isNewVersion_; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/native/runtime/extractor_utils.cpp b/frameworks/native/runtime/extractor_utils.cpp new file mode 100755 index 00000000000..811173e81c7 --- /dev/null +++ b/frameworks/native/runtime/extractor_utils.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "extractor_utils.h" + +#include + +#include "ability_constants.h" +#include "hilog_wrapper.h" +#include "runtime_extractor.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +inline bool StringStartWith(const std::string& str, const char* startStr, size_t startStrLen) +{ + return ((str.length() >= startStrLen) && (str.compare(0, startStrLen, startStr) == 0)); +} +} // namespace + +std::shared_ptr InitRuntimeExtractor(const std::string& hapPath) +{ + if (hapPath.empty()) { + HILOG_ERROR("InitRuntimeExtractor::hapPath is nullptr"); + return nullptr; + } + + std::string loadPath; + if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { + std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + loadPath = std::regex_replace(hapPath, hapPattern, ""); + loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + + loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + } else { + loadPath = hapPath; + } + auto runtimeExtractor = std::make_shared(loadPath, hapPath); + if (!runtimeExtractor->Init()) { + HILOG_ERROR("InitRuntimeExtractor::Runtime extractor init failed"); + return nullptr; + } + + return runtimeExtractor; +} + +bool GetFileBuffer( + const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream &dest) +{ + if (runtimeExtractor == nullptr || srcPath.empty()) { + HILOG_ERROR("GetFileBuffer::runtimeExtractor or srcPath is nullptr"); + return false; + } + + std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); + relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + if (!runtimeExtractor->ExtractByName(relativePath, dest)) { + HILOG_ERROR("GetFileBuffer::Extract file failed"); + return false; + } + + return true; +} + +bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostringstream &dest) +{ + if (hapPath.empty() || srcPath.empty()) { + HILOG_ERROR("GetFileBufferFromHap::hapPath or srcPath is nullptr"); + return false; + } + + return GetFileBuffer(InitRuntimeExtractor(hapPath), srcPath, dest); +} + +bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList) +{ + if (hapPath.empty() || srcPath.empty()) { + HILOG_ERROR("GetFileListFromHap::hapPath or srcPath is nullptr"); + return false; + } + + std::string loadPath; + if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { + std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + loadPath = std::regex_replace(hapPath, hapPattern, ""); + loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + + loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + } else { + loadPath = hapPath; + } + RuntimeExtractor runtimeExtractor(loadPath); + if (!runtimeExtractor.Init()) { + HILOG_ERROR("GetFileListFromHap::Runtime extractor init failed"); + return false; + } + + std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); + relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + + std::vector fileList; + if (!runtimeExtractor.GetZipFileNames(fileList)) { + HILOG_ERROR("GetFileListFromHap::Get file list failed"); + return false; + } + + std::regex replacePattern(relativePath); + for (auto value : fileList) { + if (StringStartWith(value, relativePath.c_str(), sizeof(relativePath.c_str()) - 1)) { + std::string realpath = std::regex_replace(value, replacePattern, ""); + if (realpath.find(Constants::FILE_SEPARATOR) != std::string::npos) { + continue; + } + assetList.emplace_back(value); + } + } + + return true; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/native/runtime/js_module_reader.cpp b/frameworks/native/runtime/js_module_reader.cpp index 6d99409db92..7bc07c6d53d 100755 --- a/frameworks/native/runtime/js_module_reader.cpp +++ b/frameworks/native/runtime/js_module_reader.cpp @@ -15,6 +15,7 @@ #include "js_module_reader.h" +#include "extractor_utils.h" #include "hilog_wrapper.h" #include "js_runtime_utils.h" #include "runtime_extractor.h" diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index d2e7aac2299..e8064c856c6 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -24,6 +24,7 @@ #include "connect_server_manager.h" #include "event_handler.h" +#include "extractor_utils.h" #include "hdc_register.h" #include "hilog_wrapper.h" #include "js_console_log.h" diff --git a/frameworks/native/runtime/js_runtime_utils.cpp b/frameworks/native/runtime/js_runtime_utils.cpp index 835da1fc512..be9cad23b41 100644 --- a/frameworks/native/runtime/js_runtime_utils.cpp +++ b/frameworks/native/runtime/js_runtime_utils.cpp @@ -16,13 +16,9 @@ #include "js_runtime_utils.h" #include -#include -#include -#include "ability_constants.h" #include "hilog_wrapper.h" #include "js_runtime.h" -#include "runtime_extractor.h" #ifdef WINDOWS_PLATFORM #include @@ -653,105 +649,5 @@ std::string NormalizeUri( FixExtName(newJsModulePath); return newJsModulePath; } - -std::shared_ptr InitRuntimeExtractor(const std::string& hapPath) -{ - if (hapPath.empty()) { - HILOG_ERROR("InitRuntimeExtractor::hapPath is nullptr"); - return nullptr; - } - - std::string loadPath; - if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { - std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - loadPath = std::regex_replace(hapPath, hapPattern, ""); - loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + - loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - } else { - loadPath = hapPath; - } - auto runtimeExtractor = std::make_shared(loadPath, hapPath); - if (!runtimeExtractor->Init()) { - HILOG_ERROR("GetFileBufferFromHap::Runtime extractor init failed"); - return nullptr; - } - - return runtimeExtractor; -} - -bool GetFileBuffer( - const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostream &dest) -{ - if (runtimeExtractor == nullptr || srcPath.empty()) { - HILOG_ERROR("GetFileBuffer::runtimeExtractor or srcPath is nullptr"); - return false; - } - - std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); - relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - if (!runtimeExtractor->ExtractByName(relativePath, dest)) { - HILOG_ERROR("GetFileBufferFromHap::Extract file failed"); - return false; - } - - return true; -} - -bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest) -{ - if (hapPath.empty() || srcPath.empty()) { - HILOG_ERROR("GetFileBufferFromHap::hapPath or srcPath is nullptr"); - return false; - } - - return GetFileBuffer(InitRuntimeExtractor(hapPath), srcPath, dest); -} - -bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList) -{ - if (hapPath.empty() || srcPath.empty()) { - HILOG_ERROR("GetFileListFromHap::hapPath or srcPath is nullptr"); - return false; - } - - std::string loadPath; - if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { - std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - loadPath = std::regex_replace(hapPath, hapPattern, ""); - loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + - loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - } else { - loadPath = hapPath; - } - RuntimeExtractor runtimeExtractor(loadPath); - if (!runtimeExtractor.Init()) { - HILOG_ERROR("GetFileListFromHap::Runtime extractor init failed"); - return false; - } - - std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); - relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - - std::vector fileList; - if (!runtimeExtractor.GetZipFileNames(fileList)) { - HILOG_ERROR("GetFileListFromHap::Get file list failed"); - return false; - } - - std::regex replacePattern(relativePath); - for (auto value : fileList) { - if (StringStartWith(value, relativePath.c_str(), sizeof(relativePath.c_str()) - 1)) { - std::string realpath = std::regex_replace(value, replacePattern, ""); - if (realpath.find(Constants::FILE_SEPARATOR) != std::string::npos) { - continue; - } - assetList.emplace_back(value); - } - } - - return true; -} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/runtime_extractor.cpp b/frameworks/native/runtime/runtime_extractor.cpp index dfa1932baf9..bb8cf64cc3c 100755 --- a/frameworks/native/runtime/runtime_extractor.cpp +++ b/frameworks/native/runtime/runtime_extractor.cpp @@ -19,13 +19,13 @@ namespace OHOS { namespace AbilityRuntime { -RuntimeExtractor::RuntimeExtractor(const std::string &source) : AppExecFwk::BaseExtractor(source) +RuntimeExtractor::RuntimeExtractor(const std::string &source) : BaseExtractor(source) { HILOG_DEBUG("RuntimeExtractor is created"); } RuntimeExtractor::RuntimeExtractor( - const std::string &source, const std::string &hapPath) : AppExecFwk::BaseExtractor(source) + const std::string &source, const std::string &hapPath) : BaseExtractor(source) { hapPath_ = hapPath; } diff --git a/frameworks/native/runtime/zip_file.cpp b/frameworks/native/runtime/zip_file.cpp new file mode 100755 index 00000000000..ac6983d6cb7 --- /dev/null +++ b/frameworks/native/runtime/zip_file.cpp @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "zip_file.h" + +#include +#include +#include + +#include "hilog_wrapper.h" +#include "securec.h" +#include "zlib.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr uint32_t MAX_FILE_NAME = 256; +constexpr uint32_t UNZIP_BUFFER_SIZE = 1024; +constexpr uint32_t UNZIP_BUF_IN_LEN = 160 * UNZIP_BUFFER_SIZE; // in buffer length: 160KB +constexpr uint32_t UNZIP_BUF_OUT_LEN = 320 * UNZIP_BUFFER_SIZE; // out buffer length: 320KB +constexpr uint32_t LOCAL_HEADER_SIGNATURE = 0x04034b50; +constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50; +constexpr uint32_t EOCD_SIGNATURE = 0x06054b50; +constexpr uint32_t DATA_DESC_SIGNATURE = 0x08074b50; +constexpr uint32_t FLAG_DATA_DESC = 0x8; +constexpr size_t FILE_READ_COUNT = 1; +constexpr uint8_t INFLATE_ERROR_TIMES = 5; +const char FILE_SEPARATOR_CHAR = '/'; +} // namespace + +ZipEntry::ZipEntry(const CentralDirEntry ¢ralEntry) +{ + compressionMethod = centralEntry.compressionMethod; + uncompressedSize = centralEntry.uncompressedSize; + compressedSize = centralEntry.compressedSize; + localHeaderOffset = centralEntry.localHeaderOffset; + crc = centralEntry.crc; + flags = centralEntry.flags; +} + +ZipFile::ZipFile(const std::string &pathName) : pathName_(pathName) +{ + HILOG_DEBUG("create instance from %{private}s", pathName_.c_str()); +} + +ZipFile::~ZipFile() +{ + Close(); +} + +void ZipFile::SetContentLocation(const ZipPos start, const size_t length) +{ + HILOG_DEBUG("set content location start position(%{public}llu), length(%{public}zu)", start, length); + fileStartPos_ = start; + fileLength_ = length; +} + +bool ZipFile::CheckEndDir(const EndDir &endDir) const +{ + size_t lenEndDir = sizeof(EndDir); + if ((endDir.numDisk != 0) || (endDir.signature != EOCD_SIGNATURE) || (endDir.startDiskOfCentralDir != 0) || + (endDir.offset >= fileLength_) || (endDir.totalEntriesInThisDisk != endDir.totalEntries) || + (endDir.commentLen != 0) || + // central dir can't overlap end of central dir + ((endDir.offset + endDir.sizeOfCentralDir + lenEndDir) > fileLength_)) { + HILOG_ERROR("end dir format error"); + return false; + } + return true; +} + +bool ZipFile::ParseEndDirectory() +{ + size_t endDirLen = sizeof(EndDir); + size_t endFilePos = fileStartPos_ + fileLength_; + + if (fileLength_ <= endDirLen) { + HILOG_ERROR("parse EOCD file length(%{public}llu) <= end dir length(%{public}llu)", fileStartPos_, fileLength_); + return false; + } + + size_t eocdPos = endFilePos - endDirLen; + if (fseek(file_, eocdPos, SEEK_SET) != 0) { + HILOG_ERROR("locate EOCD seek failed, error: %{public}d", errno); + return false; + } + + if (fread(&endDir_, sizeof(EndDir), FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("read EOCD struct failed, error: %{public}d", errno); + return false; + } + + centralDirPos_ = endDir_.offset + fileStartPos_; + HILOG_DEBUG("parse EOCD offset(0x%{public}08x) file start position(0x%{public}08llx)", + endDir_.offset, fileStartPos_); + + return CheckEndDir(endDir_); +} + +bool ZipFile::ParseAllEntries() +{ + bool ret = true; + ZipPos currentPos = centralDirPos_; + CentralDirEntry directoryEntry = {0}; + size_t fileLength = 0; + + for (uint16_t i = 0; i < endDir_.totalEntries; i++) { + std::string fileName; + fileName.reserve(MAX_FILE_NAME); + fileName.resize(MAX_FILE_NAME - 1); + + if (fseek(file_, currentPos, SEEK_SET) != 0) { + HILOG_ERROR("parse entry(%{public}d) seek zipEntry failed, error: %{public}d", i, errno); + ret = false; + break; + } + + if (fread(&directoryEntry, sizeof(CentralDirEntry), FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("parse entry(%{public}d) read ZipEntry failed, error: %{public}d", i, errno); + ret = false; + break; + } + + if (directoryEntry.signature != CENTRAL_SIGNATURE) { + HILOG_ERROR("parse entry(%{public}d) check signature(0x%08x) at pos(0x%08llx) failed", + i, + directoryEntry.signature, + currentPos); + ret = false; + break; + } + + fileLength = (directoryEntry.nameSize >= MAX_FILE_NAME) ? (MAX_FILE_NAME - 1) : directoryEntry.nameSize; + if (fread(&(fileName[0]), fileLength, FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("parse entry(%{public}d) read file name failed, error: %{public}d", i, errno); + ret = false; + break; + } + fileName.resize(fileLength); + + ZipEntry currentEntry(directoryEntry); + currentEntry.fileName = fileName; + entriesMap_[fileName] = currentEntry; + + currentPos += sizeof(directoryEntry); + currentPos += directoryEntry.nameSize + directoryEntry.extraSize + directoryEntry.commentSize; + } + + HILOG_DEBUG("parse %{public}d central entries from %{private}s", endDir_.totalEntries, pathName_.c_str()); + return ret; +} + +bool ZipFile::Open() +{ + HILOG_DEBUG("open: %{private}s", pathName_.c_str()); + + if (isOpen_) { + HILOG_ERROR("has already opened"); + return true; + } + + if (pathName_.length() > PATH_MAX) { + HILOG_ERROR("path length(%{public}u) longer than max path length(%{public}d)", + static_cast(pathName_.length()), + PATH_MAX); + return false; + } + std::string realPath; + realPath.reserve(PATH_MAX); + realPath.resize(PATH_MAX - 1); + if (realpath(pathName_.c_str(), &(realPath[0])) == nullptr) { + HILOG_ERROR("transform real path error: %{public}d", errno); + return false; + } + + FILE *tmpFile = fopen(realPath.c_str(), "rb"); + if (tmpFile == nullptr) { + HILOG_ERROR("open file(%{private}s) failed, error: %{public}d", pathName_.c_str(), errno); + return false; + } + + if (fileLength_ == 0) { + if (fseek(tmpFile, 0, SEEK_END) != 0) { + HILOG_ERROR("file seek failed, error: %{public}d", errno); + fclose(tmpFile); + return false; + } + int64_t fileLength = ftell(tmpFile); + if (fileLength == -1) { + HILOG_ERROR("open file %{private}s failed", pathName_.c_str()); + fclose(tmpFile); + return false; + } + fileLength_ = static_cast(fileLength); + if (fileStartPos_ >= fileLength_) { + HILOG_ERROR("open start pos > length failed"); + fclose(tmpFile); + return false; + } + + fileLength_ -= fileStartPos_; + } + + file_ = tmpFile; + bool result = ParseEndDirectory(); + if (result) { + result = ParseAllEntries(); + } + // it means open file success. + isOpen_ = true; + return result; +} + +void ZipFile::Close() +{ + HILOG_DEBUG("close: %{private}s", pathName_.c_str()); + + if (!isOpen_ || file_ == nullptr) { + HILOG_WARN("file is not opened"); + return; + } + + entriesMap_.clear(); + pathName_ = ""; + isOpen_ = false; + + if (fclose(file_) != 0) { + HILOG_WARN("close failed, error: %{public}d", errno); + } + file_ = nullptr; +} + +// Get all file zipEntry in this file +const ZipEntryMap &ZipFile::GetAllEntries() const +{ + return entriesMap_; +} + +bool ZipFile::HasEntry(const std::string &entryName) const +{ + return entriesMap_.find(entryName) != entriesMap_.end(); +} + +bool ZipFile::IsDirExist(const std::string &dir) const +{ + HILOG_DEBUG("target dir: %{public}s", dir.c_str()); + if (dir.empty()) { + HILOG_ERROR("target dir is empty"); + return false; + } + + auto tempDir = dir; + if (tempDir.back() != FILE_SEPARATOR_CHAR) { + tempDir.push_back(FILE_SEPARATOR_CHAR); + } + + for (const auto &item : entriesMap_) { + if (item.first.find(tempDir) == 0) { + HILOG_DEBUG("find target dir, fileName : %{public}s", item.first.c_str()); + return true; + } + } + HILOG_DEBUG("target dir not found, dir : %{public}s", dir.c_str()); + return false; +} + +bool ZipFile::GetEntry(const std::string &entryName, ZipEntry &resultEntry) const +{ + HILOG_DEBUG("get entry by name: %{public}s", entryName.c_str()); + auto iter = entriesMap_.find(entryName); + if (iter != entriesMap_.end()) { + resultEntry = iter->second; + HILOG_DEBUG("get entry succeed"); + return true; + } + HILOG_ERROR("get entry failed"); + return false; +} + +size_t ZipFile::GetLocalHeaderSize(const uint16_t nameSize, const uint16_t extraSize) const +{ + return sizeof(LocalHeader) + nameSize + extraSize; +} + +bool ZipFile::CheckDataDesc(const ZipEntry &zipEntry, const LocalHeader &localHeader) const +{ + uint32_t crcLocal = 0; + uint32_t compressedLocal = 0; + uint32_t uncompressedLocal = 0; + + if (localHeader.flags & FLAG_DATA_DESC) { // use data desc + DataDesc dataDesc; + auto descPos = zipEntry.localHeaderOffset + GetLocalHeaderSize(localHeader.nameSize, localHeader.extraSize); + descPos += fileStartPos_ + zipEntry.compressedSize; + + if (fseek(file_, descPos, SEEK_SET) != 0) { + HILOG_ERROR("check local header seek datadesc failed, error: %{public}d", errno); + return false; + } + + if (fread(&dataDesc, sizeof(DataDesc), FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("check local header read datadesc failed, error: %{public}d", errno); + return false; + } + + if (dataDesc.signature != DATA_DESC_SIGNATURE) { + HILOG_ERROR("check local header check datadesc signature failed"); + return false; + } + + crcLocal = dataDesc.crc; + compressedLocal = dataDesc.compressedSize; + uncompressedLocal = dataDesc.uncompressedSize; + } else { + crcLocal = localHeader.crc; + compressedLocal = localHeader.compressedSize; + uncompressedLocal = localHeader.uncompressedSize; + } + + if ((zipEntry.crc != crcLocal) || (zipEntry.compressedSize != compressedLocal) || + (zipEntry.uncompressedSize != uncompressedLocal)) { + HILOG_ERROR("check local header compressed size corrupted"); + return false; + } + + return true; +} + +bool ZipFile::CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const +{ + LocalHeader localHeader = {0}; + + if (zipEntry.localHeaderOffset >= fileLength_) { + HILOG_ERROR("check local file header offset is overflow %{public}d", zipEntry.localHeaderOffset); + return false; + } + + if (fseek(file_, fileStartPos_ + zipEntry.localHeaderOffset, SEEK_SET) != 0) { + HILOG_ERROR("check local header seek failed, error: %{public}d", errno); + return false; + } + + if (fread(&localHeader, sizeof(LocalHeader), FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("check local header read localheader failed, error: %{public}d", errno); + return false; + } + + if ((localHeader.signature != LOCAL_HEADER_SIGNATURE) || + (zipEntry.compressionMethod != localHeader.compressionMethod)) { + HILOG_ERROR("check local header signature or compressionMethod failed"); + return false; + } + + // current only support store and Z_DEFLATED method + if ((zipEntry.compressionMethod != Z_DEFLATED) && (zipEntry.compressionMethod != 0)) { + HILOG_ERROR("check local header compressionMethod(%{public}d) not support", zipEntry.compressionMethod); + return false; + } + + std::string fileName; + fileName.reserve(MAX_FILE_NAME); + fileName.resize(MAX_FILE_NAME - 1); + size_t fileLength = (localHeader.nameSize >= MAX_FILE_NAME) ? (MAX_FILE_NAME - 1) : localHeader.nameSize; + if (fileLength != zipEntry.fileName.length()) { + HILOG_ERROR("check local header file name size failed"); + return false; + } + if (fread(&(fileName[0]), fileLength, FILE_READ_COUNT, file_) != FILE_READ_COUNT) { + HILOG_ERROR("check local header read file name failed, error: %{public}d", errno); + return false; + } + fileName.resize(fileLength); + if (zipEntry.fileName != fileName) { + HILOG_ERROR("check local header file name corrupted"); + return false; + } + + if (!CheckDataDesc(zipEntry, localHeader)) { + HILOG_ERROR("check data desc failed"); + return false; + } + + extraSize = localHeader.extraSize; + return true; +} + +bool ZipFile::SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSize) const +{ + ZipPos startOffset = zipEntry.localHeaderOffset; + // get data offset, add signature+localheader+namesize+extrasize + startOffset += GetLocalHeaderSize(zipEntry.fileName.length(), extraSize); + if (startOffset + zipEntry.compressedSize > fileLength_) { + HILOG_ERROR("startOffset(%{public}lld)+entryCompressedSize(%{public}ud) > fileLength(%{public}llu)", + startOffset, + zipEntry.compressedSize, + fileLength_); + return false; + } + startOffset += fileStartPos_; // add file start relative to file stream + + HILOG_DEBUG("seek to entry start 0x%{public}08llx", startOffset); + if (fseek(file_, startOffset, SEEK_SET) != 0) { + HILOG_ERROR("seek failed, error: %{public}d", errno); + return false; + } + return true; +} + +bool ZipFile::UnzipWithStore(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const +{ + HILOG_DEBUG("unzip with store"); + + if (!SeekToEntryStart(zipEntry, extraSize)) { + HILOG_ERROR("seek to entry start failed"); + return false; + } + + uint32_t remainSize = zipEntry.compressedSize; + std::string readBuffer; + readBuffer.reserve(UNZIP_BUF_OUT_LEN); + readBuffer.resize(UNZIP_BUF_OUT_LEN - 1); + while (remainSize > 0) { + size_t readBytes; + size_t readLen = (remainSize > UNZIP_BUF_OUT_LEN) ? UNZIP_BUF_OUT_LEN : remainSize; + readBytes = fread(&(readBuffer[0]), sizeof(Byte), readLen, file_); + if (readBytes == 0) { + HILOG_ERROR("unzip store read failed, error: %{public}d", ferror(file_)); + return false; + } + remainSize -= readBytes; + dest.write(&(readBuffer[0]), readBytes); + } + + return true; +} + +bool ZipFile::InitZStream(z_stream &zstream) const +{ + // init zlib stream + if (memset_s(&zstream, sizeof(z_stream), 0, sizeof(z_stream))) { + HILOG_ERROR("unzip stream buffer init failed"); + return false; + } + int32_t zlibErr = inflateInit2(&zstream, -MAX_WBITS); + if (zlibErr != Z_OK) { + HILOG_ERROR("unzip inflated init failed"); + return false; + } + + BytePtr bufOut = new (std::nothrow) Byte[UNZIP_BUF_OUT_LEN]; + if (bufOut == nullptr) { + HILOG_ERROR("unzip inflated new out buffer failed"); + return false; + } + + BytePtr bufIn = new (std::nothrow) Byte[UNZIP_BUF_IN_LEN]; + if (bufIn == nullptr) { + HILOG_ERROR("unzip inflated new in buffer failed"); + delete[] bufOut; + return false; + } + zstream.next_out = bufOut; + zstream.next_in = bufIn; + zstream.avail_out = UNZIP_BUF_OUT_LEN; + return true; +} + +bool ZipFile::ReadZStream(const BytePtr &buffer, z_stream &zstream, uint32_t &remainCompressedSize) const +{ + if (zstream.avail_in == 0) { + size_t readBytes; + size_t remainBytes = (remainCompressedSize > UNZIP_BUF_IN_LEN) ? UNZIP_BUF_IN_LEN : remainCompressedSize; + readBytes = fread(buffer, sizeof(Byte), remainBytes, file_); + if (readBytes == 0) { + HILOG_ERROR("unzip inflated read failed, error: %{public}d", ferror(file_)); + return false; + } + + remainCompressedSize -= readBytes; + zstream.avail_in = readBytes; + zstream.next_in = buffer; + } + return true; +} + +bool ZipFile::UnzipWithInflated(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const +{ + HILOG_DEBUG("unzip with inflated"); + + z_stream zstream; + if (!SeekToEntryStart(zipEntry, extraSize) || !InitZStream(zstream)) { + return false; + } + + BytePtr bufIn = zstream.next_in; + BytePtr bufOut = zstream.next_out; + + bool ret = true; + int32_t zlibErr = Z_OK; + uint32_t remainCompressedSize = zipEntry.compressedSize; + size_t inflateLen = 0; + uint8_t errorTimes = 0; + while ((remainCompressedSize > 0) || (zstream.avail_in > 0)) { + if (!ReadZStream(bufIn, zstream, remainCompressedSize)) { + ret = false; + break; + } + + zlibErr = inflate(&zstream, Z_SYNC_FLUSH); + if ((zlibErr >= Z_OK) && (zstream.msg != nullptr)) { + HILOG_ERROR("unzip inflated inflate, error: %{public}d, err msg: %{public}s", zlibErr, zstream.msg); + ret = false; + break; + } + + inflateLen = UNZIP_BUF_OUT_LEN - zstream.avail_out; + if (inflateLen > 0) { + dest.write((const char *)bufOut, inflateLen); + zstream.next_out = bufOut; + zstream.avail_out = UNZIP_BUF_OUT_LEN; + errorTimes = 0; + } else { + errorTimes++; + } + if (errorTimes >= INFLATE_ERROR_TIMES) { + HILOG_ERROR("unzip inflated data is abnormal!"); + ret = false; + break; + } + } + + // free all dynamically allocated data structures except the next_in and next_out for this stream. + zlibErr = inflateEnd(&zstream); + if (zlibErr != Z_OK) { + HILOG_ERROR("unzip inflateEnd error, error: %{public}d", zlibErr); + ret = false; + } + + delete[] bufOut; + delete[] bufIn; + return ret; +} + +ZipPos ZipFile::GetEntryDataOffset(const ZipEntry &zipEntry, const uint16_t extraSize) const +{ + // get entry data offset relative file + ZipPos offset = zipEntry.localHeaderOffset; + + offset += GetLocalHeaderSize(zipEntry.fileName.length(), extraSize); + offset += fileStartPos_; + + return offset; +} + +bool ZipFile::GetDataOffsetRelative(const std::string &file, ZipPos &offset, uint32_t &length) const +{ + HILOG_DEBUG("get data relative offset for file %{private}s", file.c_str()); + + ZipEntry zipEntry; + if (!GetEntry(file, zipEntry)) { + HILOG_ERROR("extract file: not find file"); + return false; + } + + uint16_t extraSize = 0; + if (!CheckCoherencyLocalHeader(zipEntry, extraSize)) { + HILOG_ERROR("check coherency local header failed"); + return false; + } + + offset = GetEntryDataOffset(zipEntry, extraSize); + length = zipEntry.compressedSize; + return true; +} + +bool ZipFile::ExtractFile(const std::string &file, std::ostream &dest) const +{ + HILOG_DEBUG("extract file %{private}s", file.c_str()); + + ZipEntry zipEntry; + if (!GetEntry(file, zipEntry)) { + HILOG_ERROR("extract file: not find file"); + return false; + } + + uint16_t extraSize = 0; + if (!CheckCoherencyLocalHeader(zipEntry, extraSize)) { + HILOG_ERROR("check coherency local header failed"); + return false; + } + + bool ret = true; + if (zipEntry.compressionMethod == 0) { + ret = UnzipWithStore(zipEntry, extraSize, dest); + } else { + ret = UnzipWithInflated(zipEntry, extraSize, dest); + } + + return ret; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/simulator/ability_simulator/BUILD.gn b/frameworks/simulator/ability_simulator/BUILD.gn index a781d446cd5..dcc50680f0a 100644 --- a/frameworks/simulator/ability_simulator/BUILD.gn +++ b/frameworks/simulator/ability_simulator/BUILD.gn @@ -67,14 +67,16 @@ ohos_shared_library("ability_simulator") { sources = [ "//foundation/ability/ability_runtime/frameworks/native/runtime/js_console_log.cpp", - "//foundation/ability/ability_runtime/frameworks/native/runtime/js_module_reader.cpp", "//foundation/ability/ability_runtime/frameworks/native/runtime/js_module_searcher.cpp", "//foundation/ability/ability_runtime/frameworks/native/runtime/js_runtime_utils.cpp", "src/js_timer.cpp", "src/simulator.cpp", ] - public_configs = [ ":ability_simulator_public_config" ] + public_configs = [ + ":ability_simulator_public_config", + "${ability_runtime_services_path}/common:common_config", + ] configs = [ "//arkcompiler/ets_runtime:ark_jsruntime_public_config" ] @@ -84,7 +86,6 @@ ohos_shared_library("ability_simulator") { "//arkcompiler/ets_runtime/ecmascript/tooling:libark_ecma_debugger", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_$platform", "//foundation/ability/ability_runtime/frameworks/simulator/osal:simulator_osal", - "//foundation/ability/ability_runtime/interfaces/inner_api/runtime:runtime_extractor", "//foundation/arkui/ace_engine/frameworks/bridge/js_frontend/engine/jsi/debugger:ark_debugger", "//foundation/arkui/napi:ace_napi", "//foundation/arkui/napi:ace_napi_ark", diff --git a/frameworks/simulator/ability_simulator/src/simulator.cpp b/frameworks/simulator/ability_simulator/src/simulator.cpp index 0e619130ff0..d369819a6db 100644 --- a/frameworks/simulator/ability_simulator/src/simulator.cpp +++ b/frameworks/simulator/ability_simulator/src/simulator.cpp @@ -348,7 +348,6 @@ bool SimulatorImpl::OnInit() std::bind(&DebuggerTask::OnPostTask, &debuggerTask_, std::placeholders::_1)); panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher("")); - panda::JSNApi::SetHostResolveBufferTracker(vm_, JsModuleReader("", "")); auto nativeEngine = std::make_unique(vm_, nullptr); HandleScope handleScope(*nativeEngine); diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index cee29bd7c77..303b7e3ba5b 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -34,6 +34,7 @@ config("runtime_public_config") { ohos_shared_library("runtime") { sources = [ "${ability_runtime_native_path}/runtime/connect_server_manager.cpp", + "${ability_runtime_native_path}/runtime/extractor_utils.cpp", "${ability_runtime_native_path}/runtime/hdc_register.cpp", "${ability_runtime_native_path}/runtime/js_console_log.cpp", "${ability_runtime_native_path}/runtime/js_data_struct_converter.cpp", @@ -51,7 +52,10 @@ ohos_shared_library("runtime") { "//arkcompiler/ets_runtime:ark_jsruntime_public_config", ] - public_configs = [ ":runtime_public_config" ] + public_configs = [ + ":runtime_public_config", + "${ability_runtime_services_path}/common:common_config", + ] deps = [ ":runtime_extractor", @@ -93,21 +97,40 @@ ohos_shared_library("runtime") { part_name = "ability_runtime" } +config("ability_extractor_config") { + include_dirs = [ + "include", + "//third_party/json/include", + "//third_party/zlib/contrib/minizip", + "//third_party/zlib", + ] +} + ohos_source_set("runtime_extractor") { include_dirs = [ "include" ] - sources = [ "${ability_runtime_native_path}/runtime/runtime_extractor.cpp" ] - - configs = [ "${ability_runtime_services_path}/common:common_config" ] + sources = [ + "${ability_runtime_native_path}/runtime/base_extractor.cpp", + "${ability_runtime_native_path}/runtime/runtime_extractor.cpp", + "${ability_runtime_native_path}/runtime/zip_file.cpp", + ] cflags = [] if (target_cpu == "arm") { cflags += [ "-DBINDER_IPC_32BIT" ] } - public_deps = [ "${bundlefwk_services_path}/bundlemgr:parser_common" ] + public_configs = [ + ":ability_extractor_config", + "${ability_runtime_services_path}/common:common_config", + ] + + deps = [ "//third_party/zlib:shared_libz" ] - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] subsystem_name = "ability" part_name = "ability_runtime" diff --git a/interfaces/inner_api/runtime/include/base_extractor.h b/interfaces/inner_api/runtime/include/base_extractor.h new file mode 100755 index 00000000000..4dcfc15fa53 --- /dev/null +++ b/interfaces/inner_api/runtime/include/base_extractor.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_BASE_EXTRACTOR_H +#define OHOS_ABILITY_RUNTIME_BASE_EXTRACTOR_H + +#include + +#include "zip_file.h" + +namespace OHOS { +namespace AbilityRuntime { +class BaseExtractor { +public: + explicit BaseExtractor(const std::string &source); + virtual ~BaseExtractor(); + /** + * @brief Open compressed file. + * @return Returns true if the file is successfully opened; returns false otherwise. + */ + virtual bool Init(); + /** + * @brief Extract to dest stream by file name. + * @param fileName Indicates the file name. + * @param dest Indicates the obtained std::ostream object. + * @return Returns true if the file extracted successfully; returns false otherwise. + */ + bool ExtractByName(const std::string &fileName, std::ostream &dest) const; + /** + * @brief Extract to dest path on filesystem. + * @param fileName Indicates the file name. + * @param targetPath Indicates the target Path. + * @return Returns true if the file extracted to filesystem successfully; returns false otherwise. + */ + bool ExtractFile(const std::string &fileName, const std::string &targetPath) const; + /** + * @brief Get all file names in a hap file. + * @param fileName Indicates the obtained file names in hap. + * @return Returns true if the file names obtained successfully; returns false otherwise. + */ + bool GetZipFileNames(std::vector &fileNames); + /** + * @brief Has entry by name. + * @param entryName Indicates the entry name. + * @return Returns true if the ZipEntry is successfully finded; returns false otherwise. + */ + bool HasEntry(const std::string &fileName) const; + bool IsDirExist(const std::string &dir) const; + bool IsStageBasedModel(std::string abilityName); + bool IsNewVersion() const; + +protected: + const std::string sourceFile_; + ZipFile zipFile_; + bool initial_ = false; +private: + bool isNewVersion_ = true; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_BASE_EXTRACTOR_H diff --git a/interfaces/inner_api/runtime/include/extractor_utils.h b/interfaces/inner_api/runtime/include/extractor_utils.h new file mode 100755 index 00000000000..a7ed7dfb22a --- /dev/null +++ b/interfaces/inner_api/runtime/include/extractor_utils.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_EXTRACTOR_UTILS_H +#define OHOS_ABILITY_RUNTIME_EXTRACTOR_UTILS_H + +#include "js_runtime_utils.h" + +namespace OHOS { +namespace AbilityRuntime { +std::shared_ptr InitRuntimeExtractor(const std::string& hapPath); +bool GetFileBuffer( + const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream &dest); +bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostringstream &dest); +bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList); +} // namespace AbilityRuntime +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_EXTRACTOR_UTILS_H diff --git a/interfaces/inner_api/runtime/include/js_runtime_utils.h b/interfaces/inner_api/runtime/include/js_runtime_utils.h index c6430f2fb1c..4cd37fbd955 100644 --- a/interfaces/inner_api/runtime/include/js_runtime_utils.h +++ b/interfaces/inner_api/runtime/include/js_runtime_utils.h @@ -200,12 +200,7 @@ std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::stri bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName); std::string NormalizeUri( const std::string& bundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri); -std::shared_ptr InitRuntimeExtractor(const std::string& hapPath); std::string ParseHapPath(const std::string& hapPath); -bool GetFileBuffer( - const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostream &dest); -bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostream &dest); -bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList); } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/runtime_extractor.h b/interfaces/inner_api/runtime/include/runtime_extractor.h index e8b6a52689a..f5ebaefc58b 100755 --- a/interfaces/inner_api/runtime/include/runtime_extractor.h +++ b/interfaces/inner_api/runtime/include/runtime_extractor.h @@ -20,7 +20,7 @@ namespace OHOS { namespace AbilityRuntime { -class RuntimeExtractor : public AppExecFwk::BaseExtractor { +class RuntimeExtractor : public BaseExtractor { public: explicit RuntimeExtractor(const std::string &source); explicit RuntimeExtractor(const std::string &source, const std::string &hapPath); diff --git a/interfaces/inner_api/runtime/include/zip_file.h b/interfaces/inner_api/runtime/include/zip_file.h new file mode 100755 index 00000000000..6624b7c23f9 --- /dev/null +++ b/interfaces/inner_api/runtime/include/zip_file.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_ZIP_FILE_H +#define OHOS_ABILITY_RUNTIME_ZIP_FILE_H + +#include +#include +#include + +#include "unzip.h" + +namespace OHOS { +namespace AbilityRuntime { +struct CentralDirEntry; +struct ZipEntry; +using ZipPos = ZPOS64_T; +using ZipEntryMap = std::map; +using BytePtr = Byte *; + +// Local file header: descript in APPNOTE-6.3.4 +// local file header signature 4 bytes (0x04034b50) +// version needed to extract 2 bytes +// general purpose bit flag 2 bytes +// compression method 2 bytes 10 +// last mod file time 2 bytes +// last mod file date 2 bytes +// crc-32 4 bytes +// compressed size 4 bytes 22 +// uncompressed size 4 bytes +// file name length 2 bytes +// extra field length 2 bytes 30 +struct __attribute__((packed)) LocalHeader { + uint32_t signature = 0; + uint16_t versionNeeded = 0; + uint16_t flags = 0; + uint16_t compressionMethod = 0; + uint16_t modifiedTime = 0; + uint16_t modifiedDate = 0; + uint32_t crc = 0; + uint32_t compressedSize = 0; + uint32_t uncompressedSize = 0; + uint16_t nameSize = 0; + uint16_t extraSize = 0; +}; + +// central file header +// Central File header: +// central file header signature 4 bytes (0x02014b50) +// version made by 2 bytes +// version needed to extract 2 bytes +// general purpose bit flag 2 bytes 10 +// compression method 2 bytes +// last mod file time 2 bytes +// last mod file date 2 bytes +// crc-32 4 bytes 20 +// compressed size 4 bytes +// uncompressed size 4 bytes +// file name length 2 bytes 30 +// extra field length 2 bytes +// file comment length 2 bytes +// disk number start 2 bytes +// internal file attributes 2 bytes +// external file attributes 4 bytes +// relative offset of local header 4 bytes 46byte +struct __attribute__((packed)) CentralDirEntry { + uint32_t signature = 0; + uint16_t versionMade = 0; + uint16_t versionNeeded = 0; + uint16_t flags = 0; // general purpose bit flag + uint16_t compressionMethod = 0; + uint16_t modifiedTime = 0; + uint16_t modifiedDate = 0; + uint32_t crc = 0; + uint32_t compressedSize = 0; + uint32_t uncompressedSize = 0; + uint16_t nameSize = 0; + uint16_t extraSize = 0; + uint16_t commentSize = 0; + uint16_t diskNumStart = 0; + uint16_t internalAttr = 0; + uint32_t externalAttr = 0; + uint32_t localHeaderOffset = 0; +}; + +// end of central directory packed structure +// end of central dir signature 4 bytes (0x06054b50) +// number of this disk 2 bytes +// number of the disk with the +// start of the central directory 2 bytes +// total number of entries in the +// central directory on this disk 2 bytes +// total number of entries in +// the central directory 2 bytes +// size of the central directory 4 bytes +// offset of start of central +// directory with respect to +// the starting disk number 4 bytes +// .ZIP file comment length 2 bytes +struct __attribute__((packed)) EndDir { + uint32_t signature = 0; + uint16_t numDisk = 0; + uint16_t startDiskOfCentralDir = 0; + uint16_t totalEntriesInThisDisk = 0; + uint16_t totalEntries = 0; + uint32_t sizeOfCentralDir = 0; + uint32_t offset = 0; + uint16_t commentLen = 0; +}; + +// Data descriptor: +// data descriptor signature 4 bytes (0x06054b50) +// crc-32 4 bytes +// compressed size 4 bytes +// uncompressed size 4 bytes +// This descriptor MUST exist if bit 3 of the general purpose bit flag is set (see below). +// It is byte aligned and immediately follows the last byte of compressed data. +struct __attribute__((packed)) DataDesc { + uint32_t signature = 0; + uint32_t crc = 0; + uint32_t compressedSize = 0; + uint32_t uncompressedSize = 0; +}; + +struct ZipEntry { + ZipEntry() = default; + explicit ZipEntry(const CentralDirEntry ¢ralEntry); + ~ZipEntry() = default; // for CodeDEX warning + + uint16_t compressionMethod = 0; + uint32_t uncompressedSize = 0; + uint32_t compressedSize = 0; + uint32_t localHeaderOffset = 0; + uint32_t crc = 0; + uint16_t flags = 0; + std::string fileName; +}; + +// zip file extract class for bundle format. +class ZipFile { +public: + explicit ZipFile(const std::string &pathName); + ~ZipFile(); + /** + * @brief Open zip file. + * @return Returns true if the zip file is successfully opened; returns false otherwise. + */ + bool Open(); + /** + * @brief Close zip file. + */ + void Close(); + /** + * @brief Set this zip content start offset and length in the zip file form pathName. + * @param start Indicates the zip content location start position. + * @param length Indicates the zip content length. + */ + void SetContentLocation(ZipPos start, size_t length); + /** + * @brief Get all entries in the zip file. + * @param start Indicates the zip content location start position. + * @param length Indicates the zip content length. + * @return Returns the ZipEntryMap object cotain all entries. + */ + const ZipEntryMap &GetAllEntries() const; + /** + * @brief Has entry by name. + * @param entryName Indicates the entry name. + * @return Returns true if the ZipEntry is successfully finded; returns false otherwise. + */ + bool HasEntry(const std::string &entryName) const; + + bool IsDirExist(const std::string &dir) const; + + /** + * @brief Get entry by name. + * @param entryName Indicates the entry name. + * @param resultEntry Indicates the obtained ZipEntry object. + * @return Returns true if the ZipEntry is successfully finded; returns false otherwise. + */ + bool GetEntry(const std::string &entryName, ZipEntry &resultEntry) const; + /** + * @brief Get data relative offset for file. + * @param file Indicates the entry name. + * @param offset Indicates the obtained offset. + * @param length Indicates the length. + * @return Returns true if this function is successfully called; returns false otherwise. + */ + bool GetDataOffsetRelative(const std::string &file, ZipPos &offset, uint32_t &length) const; + /** + * @brief Get data relative offset for file. + * @param file Indicates the entry name. + * @param dest Indicates the obtained ostream object. + * @return Returns true if file is successfully extracted; returns false otherwise. + */ + bool ExtractFile(const std::string &file, std::ostream &dest) const; + +private: + /** + * @brief Check the EndDir object. + * @param endDir Indicates the EndDir object to check. + * @return Returns true if successfully checked; returns false otherwise. + */ + bool CheckEndDir(const EndDir &endDir) const; + /** + * @brief Parse the EndDir. + * @return Returns true if successfully Parsed; returns false otherwise. + */ + bool ParseEndDirectory(); + /** + * @brief Parse all Entries. + * @return Returns true if successfully parsed; returns false otherwise. + */ + bool ParseAllEntries(); + /** + * @brief Get LocalHeader object size. + * @param nameSize Indicates the nameSize. + * @param extraSize Indicates the extraSize. + * @return Returns size of LocalHeader. + */ + size_t GetLocalHeaderSize(const uint16_t nameSize = 0, const uint16_t extraSize = 0) const; + /** + * @brief Get entry data offset. + * @param zipEntry Indicates the ZipEntry object. + * @param extraSize Indicates the extraSize. + * @return Returns position. + */ + ZipPos GetEntryDataOffset(const ZipEntry &zipEntry, const uint16_t extraSize) const; + /** + * @brief Check data description. + * @param zipEntry Indicates the ZipEntry object. + * @param localHeader Indicates the localHeader object. + * @return Returns true if successfully checked; returns false otherwise. + */ + bool CheckDataDesc(const ZipEntry &zipEntry, const LocalHeader &localHeader) const; + /** + * @brief Check coherency LocalHeader object. + * @param zipEntry Indicates the ZipEntry object. + * @param extraSize Indicates the obtained size. + * @return Returns true if successfully checked; returns false otherwise. + */ + bool CheckCoherencyLocalHeader(const ZipEntry &zipEntry, uint16_t &extraSize) const; + /** + * @brief Unzip ZipEntry object to ostream. + * @param zipEntry Indicates the ZipEntry object. + * @param extraSize Indicates the size. + * @param dest Indicates the obtained ostream object. + * @return Returns true if successfully Unzip; returns false otherwise. + */ + bool UnzipWithStore(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const; + /** + * @brief Unzip ZipEntry object to ostream. + * @param zipEntry Indicates the ZipEntry object. + * @param extraSize Indicates the size. + * @param dest Indicates the obtained ostream object. + * @return Returns true if successfully Unzip; returns false otherwise. + */ + bool UnzipWithInflated(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const; + /** + * @brief Seek to Entry start. + * @param zipEntry Indicates the ZipEntry object. + * @param extraSize Indicates the extra size. + * @return Returns true if successfully Seeked; returns false otherwise. + */ + bool SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSize) const; + /** + * @brief Init zlib stream. + * @param zstream Indicates the obtained z_stream object. + * @return Returns true if successfully init; returns false otherwise. + */ + bool InitZStream(z_stream &zstream) const; + /** + * @brief Read zlib stream. + * @param buffer Indicates the buffer to read. + * @param zstream Indicates the obtained z_stream object. + * @param remainCompressedSize Indicates the obtained size. + * @return Returns true if successfully read; returns false otherwise. + */ + bool ReadZStream(const BytePtr &buffer, z_stream &zstream, uint32_t &remainCompressedSize) const; + +private: + std::string pathName_; + FILE *file_ = nullptr; + EndDir endDir_; + ZipEntryMap entriesMap_; + // offset of central directory relative to zip file. + ZipPos centralDirPos_ = 0; + // this zip content start offset relative to zip file. + ZipPos fileStartPos_ = 0; + // this zip content length in the zip file. + ZipPos fileLength_ = 0; + bool isOpen_ = false; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ZIP_FILE_H -- Gitee From a60333e1a5e4b5d2f702d7a7d39f0465d571d4fe Mon Sep 17 00:00:00 2001 From: dy_study Date: Fri, 26 Aug 2022 15:35:25 +0800 Subject: [PATCH 4/4] Fix review comments. Signed-off-by: dy_study Change-Id: I8852176d392e54993817aab446bc8c648f9df16f --- ability_runtime.gni | 1 - frameworks/native/runtime/base_extractor.cpp | 23 +---- frameworks/native/runtime/extractor_utils.cpp | 86 +++++-------------- frameworks/native/runtime/js_module_reader.h | 2 +- frameworks/native/runtime/js_runtime.cpp | 37 ++++---- .../native/runtime/js_runtime_utils.cpp | 25 ++++-- .../native/runtime/runtime_extractor.cpp | 14 ++- frameworks/native/runtime/zip_file.cpp | 32 +------ .../runtime/include/base_extractor.h | 5 +- .../runtime/include/extractor_utils.h | 4 +- .../runtime/include/js_runtime_utils.h | 4 +- .../runtime/include/runtime_extractor.h | 6 +- .../inner_api/runtime/include/zip_file.h | 2 +- 13 files changed, 80 insertions(+), 161 deletions(-) diff --git a/ability_runtime.gni b/ability_runtime.gni index 7173b2a8920..78440521c9b 100644 --- a/ability_runtime.gni +++ b/ability_runtime.gni @@ -25,7 +25,6 @@ ace_engine_path = "//foundation/arkui/ace_engine" bundlefwk_path = "//foundation/bundlemanager/bundle_framework" bundlefwk_inner_api_path = "${bundlefwk_path}/interfaces/inner_api" -bundlefwk_services_path = "${bundlefwk_path}/services" multimedia_path = "//foundation/multimedia/image_standard" multimodalinput_path = "//foundation/multimodalinput/input" diff --git a/frameworks/native/runtime/base_extractor.cpp b/frameworks/native/runtime/base_extractor.cpp index d3ff4ae2333..aca143a852c 100755 --- a/frameworks/native/runtime/base_extractor.cpp +++ b/frameworks/native/runtime/base_extractor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,19 +22,11 @@ namespace OHOS { namespace AbilityRuntime { -namespace { -constexpr const char* MODULE_PROFILE_NAME = "module.json"; -} - BaseExtractor::BaseExtractor(const std::string &source) : sourceFile_(source), zipFile_(source) -{ - HILOG_DEBUG("BaseExtractor instance is created"); -} +{} BaseExtractor::~BaseExtractor() -{ - HILOG_DEBUG("BaseExtractor instance is destroyed"); -} +{} bool BaseExtractor::Init() { @@ -43,9 +35,7 @@ bool BaseExtractor::Init() return false; } ZipEntry zipEntry; - isNewVersion_ = zipFile_.GetEntry(MODULE_PROFILE_NAME, zipEntry); initial_ = true; - HILOG_DEBUG("success"); return true; } @@ -87,7 +77,6 @@ bool BaseExtractor::ExtractByName(const std::string &fileName, std::ostream &des bool BaseExtractor::ExtractFile(const std::string &fileName, const std::string &targetPath) const { - HILOG_DEBUG("begin to extract %{public}s file into %{private}s targetPath", fileName.c_str(), targetPath.c_str()); std::ofstream fileStream; fileStream.open(targetPath, std::ios_base::out | std::ios_base::binary); if (!fileStream.is_open()) { @@ -125,13 +114,7 @@ bool BaseExtractor::IsStageBasedModel(std::string abilityName) std::string name = splitStrs.empty() ? abilityName : splitStrs.back(); std::string entry = "assets/js/" + name + "/" + name + ".js"; bool isStageBasedModel = entryMap.find(entry) != entryMap.end(); - HILOG_DEBUG("name:%{public}s isStageBasedModel:%{public}d", abilityName.c_str(), isStageBasedModel); return isStageBasedModel; } - -bool BaseExtractor::IsNewVersion() const -{ - return isNewVersion_; -} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/extractor_utils.cpp b/frameworks/native/runtime/extractor_utils.cpp index 811173e81c7..4976fa221b4 100755 --- a/frameworks/native/runtime/extractor_utils.cpp +++ b/frameworks/native/runtime/extractor_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -30,6 +30,23 @@ inline bool StringStartWith(const std::string& str, const char* startStr, size_t } } // namespace +std::string GetLoadPath(const std::string& hapPath) +{ + std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string loadPath = std::regex_replace(hapPath, hapPattern, ""); + loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + + loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + return loadPath; +} + +std::string GetRelativePath(const std::string& srcPath) +{ + std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); + std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); + relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + return relativePath; +} + std::shared_ptr InitRuntimeExtractor(const std::string& hapPath) { if (hapPath.empty()) { @@ -39,10 +56,7 @@ std::shared_ptr InitRuntimeExtractor(const std::string& hapPat std::string loadPath; if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { - std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - loadPath = std::regex_replace(hapPath, hapPattern, ""); - loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + - loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + loadPath = GetLoadPath(hapPath); } else { loadPath = hapPath; } @@ -56,16 +70,14 @@ std::shared_ptr InitRuntimeExtractor(const std::string& hapPat } bool GetFileBuffer( - const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream &dest) + const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream& dest) { if (runtimeExtractor == nullptr || srcPath.empty()) { HILOG_ERROR("GetFileBuffer::runtimeExtractor or srcPath is nullptr"); return false; } - std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); - relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); + std::string relativePath = GetRelativePath(srcPath); if (!runtimeExtractor->ExtractByName(relativePath, dest)) { HILOG_ERROR("GetFileBuffer::Extract file failed"); return false; @@ -73,61 +85,5 @@ bool GetFileBuffer( return true; } - -bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostringstream &dest) -{ - if (hapPath.empty() || srcPath.empty()) { - HILOG_ERROR("GetFileBufferFromHap::hapPath or srcPath is nullptr"); - return false; - } - - return GetFileBuffer(InitRuntimeExtractor(hapPath), srcPath, dest); -} - -bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList) -{ - if (hapPath.empty() || srcPath.empty()) { - HILOG_ERROR("GetFileListFromHap::hapPath or srcPath is nullptr"); - return false; - } - - std::string loadPath; - if (!StringStartWith(hapPath, Constants::SYSTEM_APP_PATH, sizeof(Constants::SYSTEM_APP_PATH) - 1)) { - std::regex hapPattern(std::string(Constants::ABS_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - loadPath = std::regex_replace(hapPath, hapPattern, ""); - loadPath = std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR) + - loadPath.substr(loadPath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - } else { - loadPath = hapPath; - } - RuntimeExtractor runtimeExtractor(loadPath); - if (!runtimeExtractor.Init()) { - HILOG_ERROR("GetFileListFromHap::Runtime extractor init failed"); - return false; - } - - std::regex srcPattern(std::string(Constants::LOCAL_CODE_PATH) + std::string(Constants::FILE_SEPARATOR)); - std::string relativePath = std::regex_replace(srcPath, srcPattern, ""); - relativePath = relativePath.substr(relativePath.find(std::string(Constants::FILE_SEPARATOR)) + 1); - - std::vector fileList; - if (!runtimeExtractor.GetZipFileNames(fileList)) { - HILOG_ERROR("GetFileListFromHap::Get file list failed"); - return false; - } - - std::regex replacePattern(relativePath); - for (auto value : fileList) { - if (StringStartWith(value, relativePath.c_str(), sizeof(relativePath.c_str()) - 1)) { - std::string realpath = std::regex_replace(value, replacePattern, ""); - if (realpath.find(Constants::FILE_SEPARATOR) != std::string::npos) { - continue; - } - assetList.emplace_back(value); - } - } - - return true; -} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/js_module_reader.h b/frameworks/native/runtime/js_module_reader.h index 1b1e44d8314..d7db756d7e7 100755 --- a/frameworks/native/runtime/js_module_reader.h +++ b/frameworks/native/runtime/js_module_reader.h @@ -25,7 +25,7 @@ class RuntimeExtractor; class JsModuleReader final { public: - explicit JsModuleReader(const std::string& bundleName, const std::string& hapPath, + JsModuleReader(const std::string& bundleName, const std::string& hapPath, const std::shared_ptr& runtimeExtractor) : bundleName_(bundleName), hapPath_(hapPath), runtimeExtractor_(runtimeExtractor) {} diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index e8064c856c6..f2656927956 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -28,8 +28,8 @@ #include "hdc_register.h" #include "hilog_wrapper.h" #include "js_console_log.h" -#include "js_module_searcher.h" #include "js_module_reader.h" +#include "js_module_searcher.h" #include "js_runtime_utils.h" #include "js_timer.h" #include "js_worker.h" @@ -109,7 +109,7 @@ public: debugMode_ = true; } - bool RunScript(const std::string& path, const std::string& hapPath) override + bool RunScript(const std::string& srcPath, const std::string& hapPath) override { bool result = false; if (!hapPath.empty()) { @@ -117,7 +117,7 @@ public: if (runtimeExtractor_ == nullptr) { runtimeExtractor_ = InitRuntimeExtractor(hapPath); } - if (!GetFileBuffer(runtimeExtractor_, path, outStream)) { + if (!GetFileBuffer(runtimeExtractor_, srcPath, outStream)) { HILOG_ERROR("Get abc file failed"); return result; } @@ -126,9 +126,9 @@ public: std::vector buffer; buffer.assign(outStr.begin(), outStr.end()); - result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr; + result = nativeEngine_->RunScriptBuffer(srcPath.c_str(), buffer) != nullptr; } else { - result = nativeEngine_->RunScriptPath(path.c_str()) != nullptr; + result = nativeEngine_->RunScriptPath(srcPath.c_str()) != nullptr; } return result; } @@ -136,7 +136,7 @@ public: NativeValue* LoadJsModule(const std::string& path, const std::string& hapPath) override { if (!RunScript(path, hapPath)) { - HILOG_ERROR("Failed to run script: %{public}s", path.c_str()); + HILOG_ERROR("Failed to run script: %{private}s", path.c_str()); return nullptr; } @@ -200,9 +200,12 @@ private: if (!options.preload) { bundleName_ = options.bundleName; runtimeExtractor_ = InitRuntimeExtractor(options.hapPath); - panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName)); - panda::JSNApi::SetHostResolveBufferTracker( - vm_, JsModuleReader(options.bundleName, options.hapPath, runtimeExtractor_)); + if (!options.hapPath.empty()) { + panda::JSNApi::SetHostResolveBufferTracker( + vm_, JsModuleReader(options.bundleName, options.hapPath, runtimeExtractor_)); + } else { + panda::JSNApi::SetHostResolvePathTracker(vm_, JsModuleSearcher(options.bundleName)); + } } return JsRuntime::Initialize(options); } @@ -462,19 +465,19 @@ NativeValue* JsRuntime::LoadJsBundle(const std::string& path, const std::string& globalObj->SetProperty("exports", exports); if (!RunScript(path, hapPath)) { - HILOG_ERROR("Failed to run script: %{public}s", path.c_str()); + HILOG_ERROR("Failed to run script: %{private}s", path.c_str()); return nullptr; } NativeObject* exportsObj = ConvertNativeValueTo(globalObj->GetProperty("exports")); if (exportsObj == nullptr) { - HILOG_ERROR("Failed to get exports objcect: %{public}s", path.c_str()); + HILOG_ERROR("Failed to get exports objcect: %{private}s", path.c_str()); return nullptr; } NativeValue* exportObj = exportsObj->GetProperty("default"); if (exportObj == nullptr) { - HILOG_ERROR("Failed to get default objcect: %{public}s", path.c_str()); + HILOG_ERROR("Failed to get default objcect: %{private}s", path.c_str()); return nullptr; } @@ -484,7 +487,7 @@ NativeValue* JsRuntime::LoadJsBundle(const std::string& path, const std::string& std::unique_ptr JsRuntime::LoadModule( const std::string& moduleName, const std::string& modulePath, const std::string& hapPath, bool esmodule) { - HILOG_DEBUG("JsRuntime::LoadModule(%{public}s, %{public}s, %{public}s, %{public}s)", + HILOG_DEBUG("JsRuntime::LoadModule(%{public}s, %{private}s, %{private}s, %{public}s)", moduleName.c_str(), modulePath.c_str(), hapPath.c_str(), esmodule ? "true" : "false"); HandleScope handleScope(*this); @@ -537,7 +540,7 @@ std::unique_ptr JsRuntime::LoadSystemModule( return std::unique_ptr(nativeEngine_->CreateReference(instanceValue, 1)); } -bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath) +bool JsRuntime::RunScript(const std::string& srcPath, const std::string& hapPath) { bool result = false; if (!hapPath.empty()) { @@ -545,7 +548,7 @@ bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath) if (runtimeExtractor_ == nullptr) { runtimeExtractor_ = InitRuntimeExtractor(hapPath); } - if (!GetFileBuffer(runtimeExtractor_, path, outStream)) { + if (!GetFileBuffer(runtimeExtractor_, srcPath, outStream)) { HILOG_ERROR("Get abc file failed"); return result; } @@ -554,9 +557,9 @@ bool JsRuntime::RunScript(const std::string& path, const std::string& hapPath) std::vector buffer; buffer.assign(outStr.begin(), outStr.end()); - result = nativeEngine_->RunScriptBuffer(path.c_str(), buffer) != nullptr; + result = nativeEngine_->RunScriptBuffer(srcPath.c_str(), buffer) != nullptr; } else { - result = nativeEngine_->RunScript(path.c_str()) != nullptr; + result = nativeEngine_->RunScript(srcPath.c_str()) != nullptr; } return result; } diff --git a/frameworks/native/runtime/js_runtime_utils.cpp b/frameworks/native/runtime/js_runtime_utils.cpp index be9cad23b41..b33ddb3c581 100644 --- a/frameworks/native/runtime/js_runtime_utils.cpp +++ b/frameworks/native/runtime/js_runtime_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -53,6 +53,8 @@ constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/"; constexpr char OTHER_BUNDLE_INSTALL_PATH[] = "/data/bundles/"; constexpr size_t MAX_NPM_LEVEL = 1; +constexpr size_t SEGMENTS_LIMIT_TWO = 2; +constexpr size_t SEGMENTS_LIMIT_THREE = 3; std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, std::unique_ptr&& execute, std::unique_ptr&& complete, @@ -458,7 +460,16 @@ std::string FindNpmPackageInPath(const std::string& npmPath) stream.seekg(0); stream.read(path, fileLen); path[fileLen] = '\0'; - return npmPath + '/' + StripString(path); + stream.close(); + + std::string npmPackagePath = npmPath + '/' + StripString(path); + if (npmPackagePath.size() >= PATH_MAX) { + return std::string(); + } + if (realpath(npmPackagePath.c_str(), path) == nullptr) { + return std::string(); + } + return path; } std::string FindNpmPackageInTopLevel( @@ -521,7 +532,7 @@ std::string FindNpmPackage(const std::string& curJsModulePath, const std::string } std::string ParseOhmUri( - const std::string originBundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri) + const std::string& originBundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri) { std::string moduleInstallPath; std::vector pathVector; @@ -531,7 +542,7 @@ std::string ParseOhmUri( SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_BUNDLE) - 1); // Uri should have atleast 3 segments - if (pathVector.size() < 3) { + if (pathVector.size() < SEGMENTS_LIMIT_THREE) { return std::string(); } @@ -547,7 +558,7 @@ std::string ParseOhmUri( SplitString(newJsModuleUri, pathVector, sizeof(PREFIX_MODULE) - 1); // Uri should have atleast 2 segments - if (pathVector.size() < 2) { + if (pathVector.size() < SEGMENTS_LIMIT_TWO) { return std::string(); } @@ -583,7 +594,7 @@ bool MakeFilePath(const std::string& codePath, const std::string& modulePath, st std::string path(codePath); path.append("/").append(modulePath); if (path.length() > PATH_MAX) { - HILOG_ERROR("Path length(%{public}d) longer than MAX(%{public}d)", (int32_t)path.length(), PATH_MAX); + HILOG_ERROR("Path length(%{public}zu) longer than MAX(%{public}d)", path.length(), PATH_MAX); return false; } char resolvedPath[PATH_MAX + 1] = { 0 }; @@ -606,7 +617,7 @@ bool MakeFilePath(const std::string& codePath, const std::string& modulePath, st } path.erase(start + 1, pos - start); - HILOG_INFO("Try using secondary file path: %{public}s", path.c_str()); + HILOG_DEBUG("Try using secondary file path: %{private}s", path.c_str()); if (realpath(path.c_str(), resolvedPath) == nullptr) { HILOG_ERROR("Failed to call realpath, errno = %{public}d", errno); diff --git a/frameworks/native/runtime/runtime_extractor.cpp b/frameworks/native/runtime/runtime_extractor.cpp index bb8cf64cc3c..86140ee9ecf 100755 --- a/frameworks/native/runtime/runtime_extractor.cpp +++ b/frameworks/native/runtime/runtime_extractor.cpp @@ -19,23 +19,19 @@ namespace OHOS { namespace AbilityRuntime { -RuntimeExtractor::RuntimeExtractor(const std::string &source) : BaseExtractor(source) -{ - HILOG_DEBUG("RuntimeExtractor is created"); -} +RuntimeExtractor::RuntimeExtractor(const std::string& source) : BaseExtractor(source) +{} RuntimeExtractor::RuntimeExtractor( - const std::string &source, const std::string &hapPath) : BaseExtractor(source) + const std::string& source, const std::string& hapPath) : BaseExtractor(source) { hapPath_ = hapPath; } RuntimeExtractor::~RuntimeExtractor() -{ - HILOG_DEBUG("RuntimeExtractor destroyed"); -} +{} -bool RuntimeExtractor::isSameHap(const std::string &hapPath) const +bool RuntimeExtractor::isSameHap(const std::string& hapPath) const { return !hapPath_.empty() && !hapPath.empty() && hapPath_ == hapPath; } diff --git a/frameworks/native/runtime/zip_file.cpp b/frameworks/native/runtime/zip_file.cpp index ac6983d6cb7..ac08e66de22 100755 --- a/frameworks/native/runtime/zip_file.cpp +++ b/frameworks/native/runtime/zip_file.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -51,9 +51,7 @@ ZipEntry::ZipEntry(const CentralDirEntry ¢ralEntry) } ZipFile::ZipFile(const std::string &pathName) : pathName_(pathName) -{ - HILOG_DEBUG("create instance from %{private}s", pathName_.c_str()); -} +{} ZipFile::~ZipFile() { @@ -62,7 +60,6 @@ ZipFile::~ZipFile() void ZipFile::SetContentLocation(const ZipPos start, const size_t length) { - HILOG_DEBUG("set content location start position(%{public}llu), length(%{public}zu)", start, length); fileStartPos_ = start; fileLength_ = length; } @@ -103,8 +100,6 @@ bool ZipFile::ParseEndDirectory() } centralDirPos_ = endDir_.offset + fileStartPos_; - HILOG_DEBUG("parse EOCD offset(0x%{public}08x) file start position(0x%{public}08llx)", - endDir_.offset, fileStartPos_); return CheckEndDir(endDir_); } @@ -157,15 +152,11 @@ bool ZipFile::ParseAllEntries() currentPos += sizeof(directoryEntry); currentPos += directoryEntry.nameSize + directoryEntry.extraSize + directoryEntry.commentSize; } - - HILOG_DEBUG("parse %{public}d central entries from %{private}s", endDir_.totalEntries, pathName_.c_str()); return ret; } bool ZipFile::Open() { - HILOG_DEBUG("open: %{private}s", pathName_.c_str()); - if (isOpen_) { HILOG_ERROR("has already opened"); return true; @@ -225,8 +216,6 @@ bool ZipFile::Open() void ZipFile::Close() { - HILOG_DEBUG("close: %{private}s", pathName_.c_str()); - if (!isOpen_ || file_ == nullptr) { HILOG_WARN("file is not opened"); return; @@ -255,7 +244,6 @@ bool ZipFile::HasEntry(const std::string &entryName) const bool ZipFile::IsDirExist(const std::string &dir) const { - HILOG_DEBUG("target dir: %{public}s", dir.c_str()); if (dir.empty()) { HILOG_ERROR("target dir is empty"); return false; @@ -268,24 +256,21 @@ bool ZipFile::IsDirExist(const std::string &dir) const for (const auto &item : entriesMap_) { if (item.first.find(tempDir) == 0) { - HILOG_DEBUG("find target dir, fileName : %{public}s", item.first.c_str()); return true; } } - HILOG_DEBUG("target dir not found, dir : %{public}s", dir.c_str()); + HILOG_ERROR("target dir not found, dir : %{private}s", dir.c_str()); return false; } bool ZipFile::GetEntry(const std::string &entryName, ZipEntry &resultEntry) const { - HILOG_DEBUG("get entry by name: %{public}s", entryName.c_str()); auto iter = entriesMap_.find(entryName); if (iter != entriesMap_.end()) { resultEntry = iter->second; - HILOG_DEBUG("get entry succeed"); return true; } - HILOG_ERROR("get entry failed"); + HILOG_ERROR("get entry %{public}s failed", entryName.c_str()); return false; } @@ -410,7 +395,6 @@ bool ZipFile::SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSiz } startOffset += fileStartPos_; // add file start relative to file stream - HILOG_DEBUG("seek to entry start 0x%{public}08llx", startOffset); if (fseek(file_, startOffset, SEEK_SET) != 0) { HILOG_ERROR("seek failed, error: %{public}d", errno); return false; @@ -420,8 +404,6 @@ bool ZipFile::SeekToEntryStart(const ZipEntry &zipEntry, const uint16_t extraSiz bool ZipFile::UnzipWithStore(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const { - HILOG_DEBUG("unzip with store"); - if (!SeekToEntryStart(zipEntry, extraSize)) { HILOG_ERROR("seek to entry start failed"); return false; @@ -497,8 +479,6 @@ bool ZipFile::ReadZStream(const BytePtr &buffer, z_stream &zstream, uint32_t &re bool ZipFile::UnzipWithInflated(const ZipEntry &zipEntry, const uint16_t extraSize, std::ostream &dest) const { - HILOG_DEBUG("unzip with inflated"); - z_stream zstream; if (!SeekToEntryStart(zipEntry, extraSize) || !InitZStream(zstream)) { return false; @@ -566,8 +546,6 @@ ZipPos ZipFile::GetEntryDataOffset(const ZipEntry &zipEntry, const uint16_t extr bool ZipFile::GetDataOffsetRelative(const std::string &file, ZipPos &offset, uint32_t &length) const { - HILOG_DEBUG("get data relative offset for file %{private}s", file.c_str()); - ZipEntry zipEntry; if (!GetEntry(file, zipEntry)) { HILOG_ERROR("extract file: not find file"); @@ -587,8 +565,6 @@ bool ZipFile::GetDataOffsetRelative(const std::string &file, ZipPos &offset, uin bool ZipFile::ExtractFile(const std::string &file, std::ostream &dest) const { - HILOG_DEBUG("extract file %{private}s", file.c_str()); - ZipEntry zipEntry; if (!GetEntry(file, zipEntry)) { HILOG_ERROR("extract file: not find file"); diff --git a/interfaces/inner_api/runtime/include/base_extractor.h b/interfaces/inner_api/runtime/include/base_extractor.h index 4dcfc15fa53..02bb15db076 100755 --- a/interfaces/inner_api/runtime/include/base_extractor.h +++ b/interfaces/inner_api/runtime/include/base_extractor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -59,14 +59,11 @@ public: bool HasEntry(const std::string &fileName) const; bool IsDirExist(const std::string &dir) const; bool IsStageBasedModel(std::string abilityName); - bool IsNewVersion() const; protected: const std::string sourceFile_; ZipFile zipFile_; bool initial_ = false; -private: - bool isNewVersion_ = true; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/extractor_utils.h b/interfaces/inner_api/runtime/include/extractor_utils.h index a7ed7dfb22a..28d80268e6f 100755 --- a/interfaces/inner_api/runtime/include/extractor_utils.h +++ b/interfaces/inner_api/runtime/include/extractor_utils.h @@ -22,9 +22,7 @@ namespace OHOS { namespace AbilityRuntime { std::shared_ptr InitRuntimeExtractor(const std::string& hapPath); bool GetFileBuffer( - const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream &dest); -bool GetFileBufferFromHap(const std::string& hapPath, const std::string& srcPath, std::ostringstream &dest); -bool GetFileListFromHap(const std::string& hapPath, const std::string& srcPath, std::vector& assetList); + const std::shared_ptr& runtimeExtractor, const std::string& srcPath, std::ostringstream& dest); } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/js_runtime_utils.h b/interfaces/inner_api/runtime/include/js_runtime_utils.h index 4cd37fbd955..7d4ebe543f0 100644 --- a/interfaces/inner_api/runtime/include/js_runtime_utils.h +++ b/interfaces/inner_api/runtime/include/js_runtime_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -195,7 +195,7 @@ std::string FindNpmPackageInTopLevel( const std::string& moduleInstallPath, const std::string& npmPackage, size_t start = 0); std::string FindNpmPackage(const std::string& curJsModulePath, const std::string& npmPackage); std::string ParseOhmUri( - const std::string bundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri); + const std::string& originBundleName, const std::string& curJsModulePath, const std::string& newJsModuleUri); std::string ParseJsModuleUri(const std::string& curJsModulePath, const std::string& newJsModuleUri); bool MakeFilePath(const std::string& codePath, const std::string& modulePath, std::string& fileName); std::string NormalizeUri( diff --git a/interfaces/inner_api/runtime/include/runtime_extractor.h b/interfaces/inner_api/runtime/include/runtime_extractor.h index f5ebaefc58b..2f2ecf8b942 100755 --- a/interfaces/inner_api/runtime/include/runtime_extractor.h +++ b/interfaces/inner_api/runtime/include/runtime_extractor.h @@ -22,11 +22,11 @@ namespace OHOS { namespace AbilityRuntime { class RuntimeExtractor : public BaseExtractor { public: - explicit RuntimeExtractor(const std::string &source); - explicit RuntimeExtractor(const std::string &source, const std::string &hapPath); + explicit RuntimeExtractor(const std::string& source); + RuntimeExtractor(const std::string& source, const std::string& hapPath); virtual ~RuntimeExtractor() override; - bool isSameHap(const std::string &hapPath) const; + bool isSameHap(const std::string& hapPath) const; private: std::string hapPath_; diff --git a/interfaces/inner_api/runtime/include/zip_file.h b/interfaces/inner_api/runtime/include/zip_file.h index 6624b7c23f9..118b8a6a628 100755 --- a/interfaces/inner_api/runtime/include/zip_file.h +++ b/interfaces/inner_api/runtime/include/zip_file.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at -- Gitee