diff --git a/BUILD.gn b/BUILD.gn index 6d80a18e11ddf82ab728a46e17ddebb56079dbb8..4bffdf8623639e6e9445daa171e55f581da2ec19 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -19,6 +19,7 @@ group("build_native_test") { "services/distributeddataservice/app/test:unittest", "services/distributeddataservice/framework/test:unittest", "services/distributeddataservice/service/test:unittest", + "services/distributeddataservice/rust/test:unittest", ] } diff --git a/services/distributeddataservice/framework/include/dfx/dfx_types.h b/services/distributeddataservice/framework/include/dfx/dfx_types.h index bb1a0e91d8307aca630b684b3b4ab65c9f0d6955..a83fd25292be9d924a942eaec6c381a5a6058594 100644 --- a/services/distributeddataservice/framework/include/dfx/dfx_types.h +++ b/services/distributeddataservice/framework/include/dfx/dfx_types.h @@ -88,6 +88,7 @@ enum class Fault { CSF_DOWNLOAD_ASSETS = 82, CSF_GS_CREATE_DISTRIBUTED_TABLE = 83, CSF_GS_CLOUD_SYNC = 84, + CSF_GS_CLOUD_CLEAN = 85, }; enum class FaultType { diff --git a/services/distributeddataservice/rust/extension/extension_util.cpp b/services/distributeddataservice/rust/extension/extension_util.cpp index 6c6a46543d14f9a5d816c595526208ee935578b3..5f232141c5ec9b662d7aa9a387883d42b31a6290 100644 --- a/services/distributeddataservice/rust/extension/extension_util.cpp +++ b/services/distributeddataservice/rust/extension/extension_util.cpp @@ -424,8 +424,23 @@ DBInfo ExtensionUtil::ConvertAppInfo(OhCloudExtAppInfo *appInfo) return info; } +bool ExtensionUtil::ContainNullChar(const std::string &path) +{ + uint32_t pathLength = path.length(); + const char *cStrPath = path.c_str(); + uint32_t cStrLength = strlen(cStrPath); + if (pathLength != cStrLength) { + ZLOGW("The string contains null characters."); + return true; + } + return false; +} + std::pair ExtensionUtil::Convert(const DBAsset &dbAsset) { + if (ContainNullChar(dbAsset.path) || ContainNullChar(dbAsset.uri)) { + return { nullptr, 0 }; + } OhCloudExtCloudAssetBuilder builder { .version = dbAsset.version, .status = ConvertAssetStatus(static_cast(dbAsset.status)), diff --git a/services/distributeddataservice/rust/extension/extension_util.h b/services/distributeddataservice/rust/extension/extension_util.h index 71465ede28cbd369cbefd0d77fbcb4e3716d4d91..fc422f520f6ae19df8b37ba88324a6984a9d8434 100644 --- a/services/distributeddataservice/rust/extension/extension_util.h +++ b/services/distributeddataservice/rust/extension/extension_util.h @@ -58,6 +58,7 @@ public: static std::pair Convert(const DBAssets &dbAssets); static std::pair Convert(const DBTable &dbTable); static OhCloudExtAssetStatus ConvertAssetStatus(DBAssetStatus status); + static bool ContainNullChar(const std::string &path); private: static void ConvertAssetLeft(OhCloudExtCloudAsset *asset, DBAsset &dbAsset); diff --git a/services/distributeddataservice/rust/test/BUILD.gn b/services/distributeddataservice/rust/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ade7f57f2a6ba3f956ef371e6a8ad31a2737af83 --- /dev/null +++ b/services/distributeddataservice/rust/test/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2025 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. +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +module_output_path = "datamgr_service/datamgr_service/distributeddatafwk" + +############################################################################### +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "../extension", + "../ylong_cloud_extension/include", + ] + + cflags = [ "-Werror" ] + defines = [ + "TEST_ON_DEVICE", + "OPENSSL_SUPPRESS_DEPRECATED", + ] +} + +ohos_unittest("ExtensionUtilTest") { + module_out_path = module_output_path + sources = [ + "../extension/extension_util.cpp", + "unittest/extension_util_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "${data_service_path}/rust/extension:opencloudextension", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/rust/ylong_cloud_extension:ylong_cloud_extension", + ] + external_deps = [ + "hilog:libhilog", + "kv_store:datamgr_common", + ] + + part_name = "datamgr_service" +} + +############################################################################### + +group("unittest") { + testonly = true + deps = [] + + deps += [ + ":ExtensionUtilTest", + ] +} diff --git a/services/distributeddataservice/rust/test/unittest/extension_util_test.cpp b/services/distributeddataservice/rust/test/unittest/extension_util_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31fb7bd9d0ebe0e8c6ad907fb8e439b2a4707926 --- /dev/null +++ b/services/distributeddataservice/rust/test/unittest/extension_util_test.cpp @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2025 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 "extension_util.h" +#include + +using namespace testing::ext; +using namespace OHOS::CloudData; + +namespace OHOS::Test { +class ExtensionUtilTest : public testing::Test {}; + +/** +* @tc.name: Convert001 +* @tc.desc: Check that the character string does not contain null characters. +* @tc.type: FUNC +*/ +HWTEST_F(ExtensionUtilTest, Convert001, TestSize.Level1) +{ + DBAsset dbAsset; + dbAsset.version = 1; + dbAsset.status = DBAsset::STATUS_NORMAL; + dbAsset.expiresTime = 1234567890; + dbAsset.id = "12345"; + dbAsset.name = "test_asset"; + dbAsset.createTime = "2025-07-03T00:00:00Z"; + dbAsset.modifyTime = "2025-07-04T00:00:00Z"; + dbAsset.size = "1024"; + dbAsset.hash = "abc123"; + dbAsset.uri = "http://example.com/path/to/file"; + dbAsset.path = "/path/to/file"; + + auto [asset, assetLen] = ExtensionUtil::Convert(dbAsset); + EXPECT_NE(asset, nullptr); + EXPECT_GT(assetLen, 0); + delete asset; +} + +/** +* @tc.name: Convert002 +* @tc.desc: Check whether the path contains null characters. +* @tc.type: FUNC +*/ +HWTEST_F(ExtensionUtilTest, Convert002, TestSize.Level1) +{ + const char data[] = "/path\0/to/file"; + std::string path(data, 13); + DBAsset dbAsset; + dbAsset.version = 1; + dbAsset.status = DBAsset::STATUS_NORMAL; + dbAsset.expiresTime = 1234567890; + dbAsset.id = "12345"; + dbAsset.name = "test_asset"; + dbAsset.createTime = "2025-07-03T00:00:00Z"; + dbAsset.modifyTime = "2025-07-04T00:00:00Z"; + dbAsset.size = "1024"; + dbAsset.hash = "abc123"; + dbAsset.uri = "http://example.com/path/to/file"; + dbAsset.path = path; + + auto [asset, assetLen] = ExtensionUtil::Convert(dbAsset); + EXPECT_EQ(asset, nullptr); + EXPECT_EQ(assetLen, 0); +} + +/** +* @tc.name: Convert003 +* @tc.desc: Check whether the URI contains null characters. +* @tc.type: FUNC +*/ +HWTEST_F(ExtensionUtilTest, Convert003, TestSize.Level1) +{ + const char data[] = "http://example.com/path\0to/file"; + std::string uri(data, 32); + DBAsset dbAsset; + dbAsset.version = 1; + dbAsset.status = DBAsset::STATUS_NORMAL; + dbAsset.expiresTime = 1234567890; + dbAsset.id = "12345"; + dbAsset.name = "test_asset"; + dbAsset.createTime = "2025-07-03T00:00:00Z"; + dbAsset.modifyTime = "2025-07-04T00:00:00Z"; + dbAsset.size = "1024"; + dbAsset.hash = "abc123"; + dbAsset.uri = uri; + dbAsset.path = "/path/to/file"; + + auto [asset, assetLen] = ExtensionUtil::Convert(dbAsset); + EXPECT_EQ(asset, nullptr); + EXPECT_EQ(assetLen, 0); +} + +/** +* @tc.name: Convert004 +* @tc.desc: Check whether the path and URI contain null characters. +* @tc.type: FUNC +*/ +HWTEST_F(ExtensionUtilTest, Convert004, TestSize.Level1) +{ + const char data1[] = "http://example.com/path\0to/file"; + std::string uri(data1, 32); + const char data2[] = "/path\0/to/file"; + std::string path(data2, 13); + DBAsset dbAsset; + dbAsset.version = 1; + dbAsset.status = DBAsset::STATUS_NORMAL; + dbAsset.expiresTime = 1234567890; + dbAsset.id = "12345"; + dbAsset.name = "test_asset"; + dbAsset.createTime = "2025-07-03T00:00:00Z"; + dbAsset.modifyTime = "2025-07-04T00:00:00Z"; + dbAsset.size = "1024"; + dbAsset.hash = "abc123"; + dbAsset.uri = uri; + dbAsset.path = path; + + auto [asset, assetLen] = ExtensionUtil::Convert(dbAsset); + EXPECT_EQ(asset, nullptr); + EXPECT_EQ(assetLen, 0); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index 75c4ae3266a401445ff582be5ccb7cb7554a59f1..fce1de0bab6c83693fb2b0aeb50aa28ca77e0da4 100644 --- a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -68,6 +68,7 @@ static constexpr const char *FT_ENABLE_CLOUD = "ENABLE_CLOUD"; static constexpr const char *FT_DISABLE_CLOUD = "DISABLE_CLOUD"; static constexpr const char *FT_SWITCH_ON = "SWITCH_ON"; static constexpr const char *FT_SWITCH_OFF = "SWITCH_OFF"; +static constexpr const char *FT_CLOUD_CLEAN = "CLOUD_CLEAN"; static constexpr const char *FT_QUERY_INFO = "QUERY_SYNC_INFO"; static constexpr const char *FT_USER_CHANGE = "USER_CHANGE"; static constexpr const char *FT_USER_UNLOCK = "USER_UNLOCK"; @@ -249,6 +250,7 @@ int32_t CloudServiceImpl::DoClean(const CloudInfo &cloudInfo, const std::map(user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + Report(FT_CLOUD_CLEAN, Fault::CSF_GS_CLOUD_CLEAN, meta.bundleName, "Clean:" + std::to_string(status) + + ", storeId=" + meta.GetStoreAlias() + ", action=" + std::to_string(action)); } else { ZLOGD("clean success, user:%{public}d, bundleName:%{public}s, storeId:%{public}s", static_cast(user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); @@ -325,16 +329,21 @@ int32_t CloudServiceImpl::Clean(const std::string &id, const std::map(cloudInfo.user)); + Report(FT_CLOUD_CLEAN, Fault::CSF_GS_CLOUD_CLEAN, "", + "get cloud info from meta failed=" + std::to_string(status)); return ERROR; } if (id != cloudInfo.id) { ZLOGE("different id, [server] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(cloudInfo.id).c_str(), Anonymous::Change(id).c_str()); + Report(FT_CLOUD_CLEAN, Fault::CSF_GS_CLOUD_CLEAN, "", + "different id, new:" + Anonymous::Change(id) + ", old:" + Anonymous::Change(cloudInfo.id)); return ERROR; } auto dbActions = ConvertAction(actions); if (dbActions.empty()) { ZLOGE("invalid actions. id:%{public}s", Anonymous::Change(cloudInfo.id).c_str()); + Report(FT_CLOUD_CLEAN, Fault::CSF_GS_CLOUD_CLEAN, "", "convert action failed"); return ERROR; } return DoClean(cloudInfo, dbActions); @@ -881,6 +890,8 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user, CloudSyncScene scene) actions[bundle] = GeneralStore::CleanMode::CLOUD_INFO; } DoClean(oldInfo, actions); + Report(GetDfxFaultType(scene), Fault::CSF_CLOUD_INFO, "", + "Clean: different id, new:" + Anonymous::Change(cloudInfo.id) + ", old:" + Anonymous::Change(oldInfo.id)); } return true; } diff --git a/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/services/distributeddataservice/service/rdb/rdb_general_store.cpp index 9455db59a84c8301295cc4a669a135481a548c24..9a3ba03cb830b15c6eca15b8c4fdf6e17f952dff 100644 --- a/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -943,13 +943,16 @@ int32_t RdbGeneralStore::SetDistributedTables(const std::vector &ta ZLOGE("create distributed table failed, table:%{public}s, err:%{public}d", Anonymous::Change(table).c_str(), dBStatus); Report(FT_OPEN_STORE, static_cast(Fault::CSF_GS_CREATE_DISTRIBUTED_TABLE), - "SetDistributedTables ret=" + std::to_string(static_cast(dBStatus))); + "SetDistributedTables: set table(" + Anonymous::Change(table) + ") =" + + std::to_string(static_cast(dBStatus))); return GeneralError::E_ERROR; } } if (type == DistributedTableType::DISTRIBUTED_CLOUD) { auto status = SetReference(references); if (status != GeneralError::E_OK) { + Report(FT_OPEN_STORE, static_cast(Fault::CSF_GS_CREATE_DISTRIBUTED_TABLE), + "SetDistributedTables: set reference=" + std::to_string(static_cast(status))); return GeneralError::E_ERROR; } }