From feeca881184303f555dfb4f8cd9974338246d87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9C=E9=99=B6=E9=87=91=E6=B2=9B=E2=80=9D?= Date: Mon, 14 Jul 2025 15:00:13 +0800 Subject: [PATCH] bugfix_watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: “陶金沛” --- .../mod_fs/class_watcher/fs_file_watcher.cpp | 12 ++++ .../src/mod_fs/properties/ani/access_ani.cpp | 6 +- .../js/src/mod_fs/properties/copy_core.cpp | 13 +++++ .../fs_file_watcher_mock_test.cpp | 49 ++++++++++++++++ .../mod_fs/properties/copy_core_mock_test.cpp | 56 +++++++++++++++++++ 5 files changed, 133 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp index 9f77d49df..e411c3e6a 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp @@ -202,6 +202,18 @@ void FsFileWatcher::ReadNotifyEvent() while (index < len) { event = reinterpret_cast(buf + index); + if ((len - index) < sizeof(struct inotify_event)) { + HILOGE("out of bounds access, len:%{public}d, index: %{public}d, inotify: %{public}zu", + len, index, sizeof(struct inotify_event)); + break; + } + if (event->len > (static_cast(len - index - sizeof(struct inotify_event)))) { + HILOGE("out of bounds access, index: %{public}d, inotify: %{public}zu, " + "event :%{public}u, len: %{public}d", + index, sizeof(struct inotify_event), + event->len, len); + break; + } NotifyEvent(event); index += sizeof(struct inotify_event) + static_cast(event->len); } diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp index 329e11623..41052ff71 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/access_ani.cpp @@ -102,10 +102,10 @@ ani_boolean AccessAni::AccessSync3( auto flagType = OptToAccessFlagType(flagOpt); FsResult fsRet = FsResult::Error(UNKNOWN_ERR); - if (flagOpt == std::nullopt) { - fsRet = AccessCore::DoAccess(pathStr, modeType); - } else { + if (modeType != std::nullopt && flagType != std::nullopt) { fsRet = AccessCore::DoAccess(pathStr, modeType.value(), flagType.value()); + } else { + fsRet = AccessCore::DoAccess(pathStr, modeType); } if (!fsRet.IsSuccess()) { diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp index 45403ca6d..ed94402f2 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -666,6 +666,19 @@ void CopyCore::ReadNotifyEvent(std::shared_ptr infos) } while (infos->run && index < len) { event = reinterpret_cast(buf + index); + if ((len - index) < sizeof(struct inotify_event)) { + HILOGE("out of bounds access, len:%{public}d, index: %{public}lld, inotify: %{public}zu", + len, index, sizeof(struct inotify_event)); + break; + } + if (event->len > (static_cast(len - index - sizeof(struct inotify_event)))) { + HILOGE("out of bounds access, index: %{public}lld, inotify: %{public}zu, " + "event :%{public}u, len: %{public}d", + index, sizeof(struct inotify_event), + event->len, len); + break; + } + auto [needContinue, errCode, needSend] = HandleProgress(event, infos, callback); if (!needContinue) { infos->exceptionCode = errCode; diff --git a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp index fe585ef71..33fd4b466 100644 --- a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp @@ -1058,6 +1058,55 @@ HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_003, testi GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_003"; } +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_004 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when len < sizeof(struct inotify_event). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_004"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + int32_t len = static_cast(sizeof(struct inotify_event)) - 1; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_004"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_005 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when event->len exceeds the remaining buffer size. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_005"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + char buffer[BUF_SIZE]; + struct inotify_event* event = reinterpret_cast(buffer); + event->len = 10; + int32_t len = sizeof(struct inotify_event) + 5; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_005"; +} + /** * @tc.name: FsFileWatcherMockTest_NotifyEvent_001 * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for SUCCESS when valid event without filename. diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp index 6e832264a..d7fe0bc18 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -48,6 +48,7 @@ public: private: static constexpr mode_t permission0755 = 0755; static constexpr mode_t permission0644 = 0644; + static constexpr int32_t bufSize = 1024; }; const string CopyCoreMockTest::testDir = "/data/test"; @@ -403,6 +404,61 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_003, testing::ext::T GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_003"; } +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_004 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when len < sizeof(struct inotify_event). + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_004"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + int len = static_cast(sizeof(struct inotify_event)) - 1; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_004"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_005 + * @tc.desc: Test function of ReadNotifyEvent interface for SUCCESS when event->len exceeds the remaining buffer size. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_005"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + char buffer[bufSize]; + struct inotify_event* event = reinterpret_cast(buffer); + event->len = 10; + int len = sizeof(struct inotify_event) + 5; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_005"; +} + /** * @tc.name: CopyCoreMockTest_ReadNotifyEventLocked_001 * @tc.desc: Test ReadNotifyEventLocked when closed is false. -- Gitee