mirror of
https://gitee.com/openharmony/ability_ability_runtime
synced 2024-10-07 00:13:56 +00:00
commit
e36a9bb4dc
@ -233,7 +233,7 @@ void JsRuntime::StartDebugMode(bool needBreakPoint, const std::string &processNa
|
||||
if (isDebugApp) {
|
||||
ConnectServerManager::Get().StartConnectServer(bundleName_, -1, true);
|
||||
}
|
||||
|
||||
|
||||
ConnectServerManager::Get().StoreInstanceMessage(gettid(), instanceId_);
|
||||
EcmaVM* vm = GetEcmaVm();
|
||||
auto debuggerPostTask = jsEnv_->GetDebuggerPostTask();
|
||||
@ -1360,6 +1360,7 @@ void JsRuntime::InitWorkerModule(const Options& options)
|
||||
workerInfo->hapPath = options.hapPath;
|
||||
workerInfo->isStageModel = options.isStageModel;
|
||||
workerInfo->moduleName = options.moduleName;
|
||||
workerInfo->apiTargetVersion = options.apiTargetVersion;
|
||||
if (options.isJsFramework) {
|
||||
SetJsFramework();
|
||||
}
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include "bundle_mgr_helper.h"
|
||||
#include "connect_server_manager.h"
|
||||
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
#include "declarative_module_preloader.h"
|
||||
#include "extractor.h"
|
||||
#include "file_mapper.h"
|
||||
#include "foundation/bundlemanager/bundle_framework/interfaces/inner_api/appexecfwk_base/include/bundle_info.h"
|
||||
#include "foundation/bundlemanager/bundle_framework/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h"
|
||||
#include "foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include/iservice_registry.h"
|
||||
@ -48,6 +49,7 @@ namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
namespace {
|
||||
constexpr int64_t ASSET_FILE_MAX_SIZE = 32 * 1024 * 1024;
|
||||
constexpr int32_t API8 = 8;
|
||||
const std::string BUNDLE_NAME_FLAG = "@bundle:";
|
||||
const std::string CACHE_DIRECTORY = "el2";
|
||||
const int PATH_THREE = 3;
|
||||
@ -125,6 +127,8 @@ void OffWorkerFunc(NativeEngine* nativeEngine)
|
||||
|
||||
using Extractor = AbilityBase::Extractor;
|
||||
using ExtractorUtil = AbilityBase::ExtractorUtil;
|
||||
using FileMapper = AbilityBase::FileMapper;
|
||||
using FileMapperType = AbilityBase::FileMapperType;
|
||||
using IBundleMgr = AppExecFwk::IBundleMgr;
|
||||
|
||||
std::string AssetHelper::NormalizedFileName(const std::string& fileName) const
|
||||
@ -144,16 +148,27 @@ std::string AssetHelper::NormalizedFileName(const std::string& fileName) const
|
||||
return normalizedFilePath;
|
||||
}
|
||||
|
||||
void AssetHelper::operator()(const std::string& uri, std::vector<uint8_t>& content, std::string &ami)
|
||||
AssetHelper::~AssetHelper()
|
||||
{
|
||||
if (uri.empty() || workerInfo_ == nullptr) {
|
||||
HILOG_ERROR("Uri is empty.");
|
||||
HILOG_DEBUG("destroyed.");
|
||||
if (fd_ != -1) {
|
||||
close(fd_);
|
||||
fd_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetHelper::operator()(const std::string& uri, uint8_t** buff, size_t* buffSize, std::string& ami,
|
||||
bool& useSecureMem, bool isRestricted)
|
||||
{
|
||||
if (uri.empty() || buff == nullptr || buffSize == nullptr || workerInfo_ == nullptr) {
|
||||
HILOG_ERROR("Input params invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
HILOG_DEBUG("RegisterAssetFunc called, uri: %{private}s", uri.c_str());
|
||||
std::string realPath;
|
||||
std::string filePath;
|
||||
useSecureMem = false;
|
||||
|
||||
// 1. compilemode is jsbundle
|
||||
// 2. compilemode is esmodule
|
||||
@ -189,11 +204,11 @@ void AssetHelper::operator()(const std::string& uri, std::vector<uint8_t>& conte
|
||||
|
||||
HILOG_DEBUG("Get asset, ami: %{private}s", ami.c_str());
|
||||
if (ami.find(CACHE_DIRECTORY) != std::string::npos) {
|
||||
if (!ReadAmiData(ami, content)) {
|
||||
HILOG_ERROR("Get asset content by ami failed.");
|
||||
if (!ReadAmiData(ami, buff, buffSize, useSecureMem, isRestricted)) {
|
||||
HILOG_ERROR("Get buffer by ami failed.");
|
||||
}
|
||||
} else if (!ReadFilePathData(filePath, content)) {
|
||||
HILOG_ERROR("Get asset content by filepath failed.");
|
||||
} else if (!ReadFilePathData(filePath, buff, buffSize, useSecureMem, isRestricted)) {
|
||||
HILOG_ERROR("Get buffer by filepath failed.");
|
||||
}
|
||||
} else {
|
||||
// 2.1 start with @bundle:bundlename/modulename
|
||||
@ -227,43 +242,108 @@ void AssetHelper::operator()(const std::string& uri, std::vector<uint8_t>& conte
|
||||
ami = workerInfo_->codePath + filePath;
|
||||
HILOG_DEBUG("Get asset, ami: %{private}s", ami.c_str());
|
||||
if (ami.find(CACHE_DIRECTORY) != std::string::npos) {
|
||||
if (!ReadAmiData(ami, content)) {
|
||||
HILOG_ERROR("Get asset content by ami failed.");
|
||||
if (!ReadAmiData(ami, buff, buffSize, useSecureMem, isRestricted)) {
|
||||
HILOG_ERROR("Get buffer by ami failed.");
|
||||
}
|
||||
} else if (!ReadFilePathData(filePath, content)) {
|
||||
HILOG_ERROR("Get asset content by filepath failed.");
|
||||
} else if (!ReadFilePathData(filePath, buff, buffSize, useSecureMem, isRestricted)) {
|
||||
HILOG_ERROR("Get buffer by filepath failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetHelper::ReadAmiData(const std::string& ami, std::vector<uint8_t>& content) const
|
||||
bool AssetHelper::GetSafeData(const std::string& ami, uint8_t** buff, size_t* buffSize)
|
||||
{
|
||||
HILOG_DEBUG("Use secure mem.");
|
||||
std::string resolvedPath;
|
||||
resolvedPath.reserve(PATH_MAX);
|
||||
resolvedPath.resize(PATH_MAX - 1);
|
||||
if (realpath(ami.c_str(), &(resolvedPath[0])) == nullptr) {
|
||||
HILOG_ERROR("Realpath file %{private}s caught error: %{public}d.", ami.c_str(), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = open(resolvedPath.c_str(), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
HILOG_ERROR("Open file %{private}s caught error: %{public}d.", resolvedPath.c_str(), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
HILOG_ERROR("Get fstat of file %{private}s caught error: %{public}d.", resolvedPath.c_str(), errno);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<FileMapper> fileMapper = std::make_unique<FileMapper>();
|
||||
if (fileMapper == nullptr) {
|
||||
HILOG_ERROR("Create file mapper failed.");
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = fileMapper->CreateFileMapper(resolvedPath, false, fd, 0, statbuf.st_size, FileMapperType::SAFE_ABC);
|
||||
if (!result) {
|
||||
HILOG_ERROR("Create file %{private}s mapper failed.", resolvedPath.c_str());
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
*buff = fileMapper->GetDataPtr();
|
||||
*buffSize = fileMapper->GetDataLen();
|
||||
fd_ = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetHelper::ReadAmiData(const std::string& ami, uint8_t** buff, size_t* buffSize,
|
||||
bool& useSecureMem, bool isRestricted)
|
||||
{
|
||||
// Current function is a private, validity of workerInfo_ has been checked by caller.
|
||||
bool apiSatisfy = workerInfo_->apiTargetVersion == 0 || workerInfo_->apiTargetVersion > API8;
|
||||
if (workerInfo_->isStageModel && !isRestricted && apiSatisfy && GetSafeData(ami, buff, buffSize)) {
|
||||
useSecureMem = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (realpath(ami.c_str(), path) == nullptr) {
|
||||
HILOG_ERROR("ReadAmiData realpath(%{private}s) failed, errno = %{public}d", ami.c_str(), errno);
|
||||
HILOG_ERROR("Realpath file %{private}s caught error: %{public}d.", ami.c_str(), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream stream(path, std::ios::binary | std::ios::ate);
|
||||
if (!stream.is_open()) {
|
||||
HILOG_ERROR("ReadAmiData failed to open file %{private}s", ami.c_str());
|
||||
HILOG_ERROR("Failed to open file %{private}s.", ami.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fileLen = stream.tellg();
|
||||
if (!workerInfo_->isDebugVersion && fileLen > ASSET_FILE_MAX_SIZE) {
|
||||
HILOG_ERROR("ReadAmiData failed, file is too large");
|
||||
HILOG_ERROR("File is too large.");
|
||||
return false;
|
||||
}
|
||||
|
||||
content.resize(fileLen);
|
||||
if (fileLen <= 0) {
|
||||
HILOG_ERROR("Invalid file length.");
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.seekg(0);
|
||||
stream.read(reinterpret_cast<char*>(content.data()), content.size());
|
||||
auto temp = std::make_unique<uint8_t[]>(fileLen);
|
||||
if (temp == nullptr) {
|
||||
HILOG_ERROR("Alloc mem failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.seekg(0, std::ios::beg);
|
||||
stream.read(reinterpret_cast<char*>(temp.get()), fileLen);
|
||||
|
||||
*buff = temp.get();
|
||||
*buffSize = fileLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetHelper::ReadFilePathData(const std::string& filePath, std::vector<uint8_t>& content)
|
||||
bool AssetHelper::ReadFilePathData(const std::string& filePath, uint8_t** buff, size_t* buffSize,
|
||||
bool& useSecureMem, bool isRestricted)
|
||||
{
|
||||
auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
|
||||
if (bundleMgrHelper == nullptr) {
|
||||
@ -323,6 +403,17 @@ bool AssetHelper::ReadFilePathData(const std::string& filePath, std::vector<uint
|
||||
} else {
|
||||
realfilePath = filePath.substr(pos + 1);
|
||||
HILOG_DEBUG("realfilePath: %{private}s", realfilePath.c_str());
|
||||
bool apiSatisfy = workerInfo_->apiTargetVersion == 0 || workerInfo_->apiTargetVersion > API8;
|
||||
if (workerInfo_->isStageModel && !isRestricted && apiSatisfy && !extractor->IsHapCompress(realfilePath)) {
|
||||
HILOG_DEBUG("Use secure mem.");
|
||||
auto safeData = extractor->GetSafeData(realfilePath);
|
||||
if (safeData != nullptr) {
|
||||
*buff = safeData->GetDataPtr();
|
||||
*buffSize = safeData->GetDataLen();
|
||||
useSecureMem = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!extractor->ExtractToBufByName(realfilePath, dataPtr, fileLen)) {
|
||||
HILOG_ERROR("get mergeAbc fileBuffer failed");
|
||||
return false;
|
||||
@ -333,7 +424,9 @@ bool AssetHelper::ReadFilePathData(const std::string& filePath, std::vector<uint
|
||||
HILOG_ERROR("ReadFilePathData failed, file is too large");
|
||||
return false;
|
||||
}
|
||||
content.assign(dataPtr.get(), dataPtr.get() + fileLen);
|
||||
|
||||
*buff = dataPtr.get();
|
||||
*buffSize = fileLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,17 +41,26 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~AssetHelper();
|
||||
|
||||
void operator()(const std::string& uri, uint8_t** buff, size_t* buffSize, std::string& ami,
|
||||
bool& useSecureMem, bool isRestricted = false);
|
||||
|
||||
private:
|
||||
std::string NormalizedFileName(const std::string& fileName) const;
|
||||
|
||||
void operator()(const std::string& uri, std::vector<uint8_t>& content, std::string &ami);
|
||||
bool ReadAmiData(const std::string& ami, uint8_t** buff, size_t* buffSize,
|
||||
bool& useSecureMem, bool isRestricted);
|
||||
|
||||
bool ReadAmiData(const std::string& ami, std::vector<uint8_t>& content) const;
|
||||
|
||||
bool ReadFilePathData(const std::string& filePath, std::vector<uint8_t>& content);
|
||||
bool ReadFilePathData(const std::string& filePath, uint8_t** buff, size_t* buffSize,
|
||||
bool& useSecureMem, bool isRestricted);
|
||||
|
||||
void GetAmi(std::string& ami, const std::string& filePath);
|
||||
private:
|
||||
std::shared_ptr<JsEnv::WorkerInfo> workerInfo_;
|
||||
|
||||
bool GetSafeData(const std::string& ami, uint8_t** buff, size_t* buffSize);
|
||||
|
||||
std::shared_ptr<JsEnv::WorkerInfo> workerInfo_ = nullptr;
|
||||
int fd_ = -1;
|
||||
};
|
||||
|
||||
} // namespace AbilityRuntime
|
||||
|
@ -33,6 +33,7 @@ struct WorkerInfo {
|
||||
std::string hapPath;
|
||||
bool isStageModel = true;
|
||||
std::string moduleName;
|
||||
int32_t apiTargetVersion = 0;
|
||||
};
|
||||
|
||||
class JsEnvironmentImpl {
|
||||
|
@ -163,12 +163,46 @@ ohos_unittest("ohos_js_environment_test") {
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("js_worker_test") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
include_dirs = [
|
||||
"${ability_runtime_native_path}/runtime",
|
||||
"${ability_runtime_native_path}/runtime/utils/include",
|
||||
"${ability_base_kits_path}/extractortool/include",
|
||||
"//third_party/zlib/contrib/minizip",
|
||||
"//third_party/zlib",
|
||||
]
|
||||
|
||||
sources = [
|
||||
# add mock file
|
||||
"js_worker_test.cpp",
|
||||
]
|
||||
|
||||
configs = [ "${ability_runtime_services_path}/abilitymgr:abilityms_config" ]
|
||||
deps = []
|
||||
|
||||
external_deps = [
|
||||
"ability_base:extractortool",
|
||||
"ability_runtime:js_environment",
|
||||
"ability_runtime:runtime",
|
||||
"bundle_framework:appexecfwk_core",
|
||||
"c_utils:utils",
|
||||
"ets_runtime:libark_jsruntime",
|
||||
"eventhandler:libeventhandler",
|
||||
"hilog:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":hdc_register_test",
|
||||
":js_runtime_test",
|
||||
":js_worker_test",
|
||||
":ohos_js_environment_test",
|
||||
":runtime_test",
|
||||
]
|
||||
|
121
test/unittest/runtime_test/js_worker_test.cpp
Normal file
121
test/unittest/runtime_test/js_worker_test.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <gtest/gtest.h>
|
||||
#include <cstdarg>
|
||||
#include <string>
|
||||
|
||||
#include "hilog_wrapper.h"
|
||||
#include "js_environment_impl.h"
|
||||
#define private public
|
||||
#define protected public
|
||||
#include "js_worker.h"
|
||||
#undef private
|
||||
#undef protected
|
||||
#include "native_engine.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS {
|
||||
namespace AbilityRuntime {
|
||||
class JsWorkerTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
void TestSetGetAssetFunc(GetAssetFunc func);
|
||||
GetAssetFunc TestGetGetAssetFunc() const;
|
||||
|
||||
private:
|
||||
GetAssetFunc getAssetFunc_ = nullptr;
|
||||
};
|
||||
|
||||
void JsWorkerTest::SetUpTestCase()
|
||||
{}
|
||||
|
||||
void JsWorkerTest::TearDownTestCase()
|
||||
{}
|
||||
|
||||
void JsWorkerTest::SetUp()
|
||||
{}
|
||||
|
||||
void JsWorkerTest::TearDown()
|
||||
{}
|
||||
|
||||
void JsWorkerTest::TestSetGetAssetFunc(GetAssetFunc func)
|
||||
{
|
||||
getAssetFunc_ = func;
|
||||
}
|
||||
|
||||
GetAssetFunc JsWorkerTest::TestGetGetAssetFunc() const
|
||||
{
|
||||
return getAssetFunc_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: AssetHelper_0100
|
||||
* @tc.desc: Asset helper.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issue#I948D4
|
||||
*/
|
||||
HWTEST_F(JsWorkerTest, AssetHelper_0100, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<JsEnv::WorkerInfo> workerInfo = std::make_shared<JsEnv::WorkerInfo>();
|
||||
workerInfo->codePath = "/data/test/codePath";
|
||||
workerInfo->packagePathStr = "/data/test/packagePath";
|
||||
workerInfo->hapPath = "/data/test/hapPath";
|
||||
workerInfo->moduleName = "moduleName";
|
||||
TestSetGetAssetFunc(AssetHelper(workerInfo));
|
||||
|
||||
std::string uri = "/data";
|
||||
uint8_t *buff = nullptr;
|
||||
size_t buffSize;
|
||||
std::string ami;
|
||||
bool useSecureMem;
|
||||
bool isRestricted = false;
|
||||
auto func = TestGetGetAssetFunc();
|
||||
func("/data", &buff, &buffSize, ami, useSecureMem, isRestricted);
|
||||
EXPECT_EQ(useSecureMem, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: AssetHelper_0200
|
||||
* @tc.desc: Asset helper GetSafeData.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issue#I948D4
|
||||
*/
|
||||
HWTEST_F(JsWorkerTest, AssetHelper_0200, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<JsEnv::WorkerInfo> workerInfo = std::make_shared<JsEnv::WorkerInfo>();
|
||||
workerInfo->codePath = "/data/test/codePath";
|
||||
workerInfo->packagePathStr = "/data/test/packagePath";
|
||||
workerInfo->hapPath = "/data/test/hapPath";
|
||||
workerInfo->moduleName = "moduleName";
|
||||
AssetHelper helper = AssetHelper(workerInfo);
|
||||
|
||||
FILE *fp = nullptr;
|
||||
fp = fopen("test.txt", "w+");
|
||||
ASSERT_NE(fp, nullptr);
|
||||
fclose(fp);
|
||||
|
||||
uint8_t *buff = nullptr;
|
||||
size_t buffSize;
|
||||
auto ret = helper.GetSafeData("test.txt", &buff, &buffSize);
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
} // namespace AbilityRuntime
|
||||
} // namespace OHOS
|
Loading…
Reference in New Issue
Block a user