已开启
fix(liveview): CheckNotificationRequest 增加空 content 判空校验防止崩溃 #5012
fix(liveview): CheckNotificationRequest 增加空 content 判空校验防止崩溃 #5012
已开启
stepend98创建于 7 天前
2 个文件变更+191-0
@@ -3212,8 +3212,19 @@ ErrCode NotificationRequest::CheckNotificationRequest(const sptr<NotificationReq
3212 return ERR_OK;3212 return ERR_OK;
3213 }3213 }
3214 3214 
3215+ if (notificationContent_ == nullptr) {
3216+ ANS_LOGE("notificationContent_ is nullptr, bundle name %{public}s, id %{public}d.",
3217+ GetCreatorBundleName().c_str(), GetNotificationId());
3218+ return ERR_ANS_INNER_INVALID_PARAM;
3219+ }
3220+ 
3215 using StatusType = NotificationLiveViewContent::LiveViewStatus;3221 using StatusType = NotificationLiveViewContent::LiveViewStatus;
3216 auto content = notificationContent_->GetNotificationContent();3222 auto content = notificationContent_->GetNotificationContent();
3223+ if (content == nullptr) {
3224+ ANS_LOGE("Invalid content, bundle name %{public}s, id %{public}d.",
3225+ GetCreatorBundleName().c_str(), GetNotificationId());
3226+ return ERR_ANS_INNER_INVALID_PARAM;
3227+ }
3217 auto liveView = std::static_pointer_cast<NotificationLiveViewContent>(content);3228 auto liveView = std::static_pointer_cast<NotificationLiveViewContent>(content);
3218 auto status = liveView->GetLiveViewStatus();3229 auto status = liveView->GetLiveViewStatus();
3219 if (oldRequest == nullptr) {3230 if (oldRequest == nullptr) {
@@ -2803,5 +2803,185 @@ HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NotObject_001
2803 EXPECT_EQ(result, false);2803 EXPECT_EQ(result, false);
2804 EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);2804 EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2805}2805}
2806+ 
2807+/**
2808+ * @tc.name: CheckNotificationRequest_NullNewContent_001
2809+ * @tc.desc: Test CheckNotificationRequest when new request is common live view but
2810+ * notificationContent_ is nullptr (IPC/JSON inconsistent state: type set, content absent).
2811+ * @tc.type: FUNC
2812+ */
2813+HWTEST_F(NotificationRequestTest, CheckNotificationRequest_NullNewContent_001, Level1)
2814+{
2815+ int32_t myNotificationId = 10;
2816+ NotificationRequest notificationRequest(myNotificationId);
2817+ notificationRequest.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2818+ notificationRequest.notificationContent_ = nullptr;
2819+ notificationRequest.notificationContentType_ = NotificationContent::Type::LIVE_VIEW;
2820+ EXPECT_TRUE(notificationRequest.IsCommonLiveView());
2821+ 
2822+ ErrCode result = notificationRequest.CheckNotificationRequest(nullptr);
2823+ EXPECT_EQ(result, ERR_ANS_INNER_INVALID_PARAM);
2824+}
2825+ 
2826+/**
2827+ * @tc.name: CheckNotificationRequest_NullNewContent_002
2828+ * @tc.desc: Test CheckNotificationRequest when new request is common live view with null
2829+ * notificationContent_ and oldRequest is a valid live view request.
2830+ * @tc.type: FUNC
2831+ */
2832+HWTEST_F(NotificationRequestTest, CheckNotificationRequest_NullNewContent_002, Level1)
2833+{
2834+ int32_t myNotificationId = 10;
2835+ NotificationRequest notificationRequest(myNotificationId);
2836+ notificationRequest.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2837+ notificationRequest.notificationContent_ = nullptr;
2838+ notificationRequest.notificationContentType_ = NotificationContent::Type::LIVE_VIEW;
2839+ 
2840+ sptr<NotificationRequest> oldRequest(new (std::nothrow) NotificationRequest());
2841+ oldRequest->SetNotificationId(myNotificationId);
2842+ oldRequest->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2843+ auto oldLiveContent = std::make_shared<NotificationLiveViewContent>();
2844+ oldLiveContent->SetLiveViewStatus(NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_CREATE);
2845+ auto oldContent = std::make_shared<NotificationContent>(oldLiveContent);
2846+ oldRequest->SetContent(oldContent);
2847+ 
2848+ ErrCode result = notificationRequest.CheckNotificationRequest(oldRequest);
2849+ EXPECT_EQ(result, ERR_ANS_INNER_INVALID_PARAM);
2850+}
2851+ 
2852+/**
2853+ * @tc.name: CheckNotificationRequest_NullNewInnerContent_001
2854+ * @tc.desc: Test CheckNotificationRequest when new request is common live view, notificationContent_
2855+ * is non-null but its inner content is nullptr.
2856+ * @tc.type: FUNC
2857+ */
2858+HWTEST_F(NotificationRequestTest, CheckNotificationRequest_NullNewInnerContent_001, Level1)
2859+{
2860+ int32_t myNotificationId = 10;
2861+ NotificationRequest notificationRequest(myNotificationId);
2862+ notificationRequest.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2863+ notificationRequest.notificationContent_ = std::make_shared<NotificationContent>();
2864+ notificationRequest.notificationContentType_ = NotificationContent::Type::LIVE_VIEW;
2865+ EXPECT_EQ(notificationRequest.GetContent()->GetNotificationContent(), nullptr);
2866+ 
2867+ ErrCode result = notificationRequest.CheckNotificationRequest(nullptr);
2868+ EXPECT_EQ(result, ERR_ANS_INNER_INVALID_PARAM);
2869+}
2870+ 
2871+/**
2872+ * @tc.name: CheckNotificationRequest_NullNewInnerContent_002
2873+ * @tc.desc: Test CheckNotificationRequest when new request inner content is nullptr and
2874+ * oldRequest is a valid live view request.
2875+ * @tc.type: FUNC
2876+ */
2877+HWTEST_F(NotificationRequestTest, CheckNotificationRequest_NullNewInnerContent_002, Level1)
2878+{
2879+ int32_t myNotificationId = 10;
2880+ NotificationRequest notificationRequest(myNotificationId);
2881+ notificationRequest.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2882+ notificationRequest.notificationContent_ = std::make_shared<NotificationContent>();
2883+ notificationRequest.notificationContentType_ = NotificationContent::Type::LIVE_VIEW;
2884+ 
2885+ sptr<NotificationRequest> oldRequest(new (std::nothrow) NotificationRequest());
2886+ oldRequest->SetNotificationId(myNotificationId);
2887+ oldRequest->SetSlotType(NotificationConstant::SlotType::LIVE_VIEW);
2888+ auto oldLiveContent = std::make_shared<NotificationLiveViewContent>();
2889+ oldLiveContent->SetLiveViewStatus(NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_CREATE);
2890+ auto oldContent = std::make_shared<NotificationContent>(oldLiveContent);
2891+ oldRequest->SetContent(oldContent);
2892+ 
2893+ ErrCode result = notificationRequest.CheckNotificationRequest(oldRequest);
2894+ EXPECT_EQ(result, ERR_ANS_INNER_INVALID_PARAM);
2895+}
2896+ 
2897+/**
2898+ * @tc.name: ConvertJsonToEnum_ValidContentType_001
2899+ * @tc.desc: Test ConvertJsonToEnum accepts valid notificationContentType values.
2900+ * @tc.type: FUNC
2901+ */
2902+HWTEST_F(NotificationRequestTest, ConvertJsonToEnum_ValidContentType_001, Level1)
2903+{
2904+ NotificationRequest notificationRequest(10);
2905+ nlohmann::json jsonObject = nlohmann::json{
2906+ {"notificationContentType", static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW)},
2907+ };
2908+ NotificationRequest::ConvertJsonToEnum(&notificationRequest, jsonObject);
2909+ EXPECT_EQ(notificationRequest.GetNotificationType(), NotificationContent::Type::LIVE_VIEW);
2910+}
2911+ 
2912+/**
2913+ * @tc.name: FromJson_ContentTypeSyncWithContent_001
2914+ * @tc.desc: Test FromJson syncs notificationContentType_ from the actual content object,
2915+ * preventing LIVE_VIEW type confusion when content is another type.
2916+ * @tc.type: FUNC
2917+ */
2918+HWTEST_F(NotificationRequestTest, FromJson_ContentTypeSyncWithContent_001, Level1)
2919+{
2920+ nlohmann::json jsonObject = nlohmann::json{
2921+ {"slotType", static_cast<int32_t>(NotificationConstant::SlotType::LIVE_VIEW)},
2922+ {"notificationContentType", static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW)},
2923+ {"content", {
2924+ {"contentType", static_cast<int32_t>(NotificationContent::Type::BASIC_TEXT)},
2925+ {"content", {{"text", "test text"}, {"title", "test title"}}}
2926+ }},
2927+ };
2928+ 
2929+ auto *request = NotificationRequest::FromJson(jsonObject);
2930+ ASSERT_NE(request, nullptr);
2931+ EXPECT_NE(request->GetContent(), nullptr);
2932+ EXPECT_EQ(request->GetContent()->GetContentType(), NotificationContent::Type::BASIC_TEXT);
2933+ EXPECT_EQ(request->GetNotificationType(), NotificationContent::Type::BASIC_TEXT);
2934+ EXPECT_FALSE(request->IsCommonLiveView());
2935+ delete request;
2936+}
2937+ 
2938+/**
2939+ * @tc.name: FromJson_LiveViewContentConsistent_001
2940+ * @tc.desc: Test FromJson keeps LIVE_VIEW type when content is a real live view content
2941+ * and CheckNotificationRequest works on the parsed request.
2942+ * @tc.type: FUNC
2943+ */
2944+HWTEST_F(NotificationRequestTest, FromJson_LiveViewContentConsistent_001, Level1)
2945+{
2946+ nlohmann::json jsonObject = nlohmann::json{
2947+ {"slotType", static_cast<int32_t>(NotificationConstant::SlotType::LIVE_VIEW)},
2948+ {"notificationContentType", static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW)},
2949+ {"content", {
2950+ {"contentType", static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW)},
2951+ {"content", {{"text", "test text"}, {"title", "test title"},
2952+ {"status", static_cast<int32_t>(
2953+ NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_CREATE)}}}
2954+ }},
2955+ };
2956+ 
2957+ auto *request = NotificationRequest::FromJson(jsonObject);
2958+ ASSERT_NE(request, nullptr);
2959+ EXPECT_EQ(request->GetNotificationType(), NotificationContent::Type::LIVE_VIEW);
2960+ EXPECT_TRUE(request->IsCommonLiveView());
2961+ EXPECT_EQ(request->CheckNotificationRequest(nullptr), ERR_OK);
2962+ delete request;
2963+}
2964+ 
2965+/**
2966+ * @tc.name: FromJson_LiveViewWithoutContent_001
2967+ * @tc.desc: Test CheckNotificationRequest on a request parsed from JSON which declares
2968+ * LIVE_VIEW type but carries no content object (no crash, invalid param).
2969+ * @tc.type: FUNC
2970+ */
2971+HWTEST_F(NotificationRequestTest, FromJson_LiveViewWithoutContent_001, Level1)
2972+{
2973+ nlohmann::json jsonObject = nlohmann::json{
2974+ {"slotType", static_cast<int32_t>(NotificationConstant::SlotType::LIVE_VIEW)},
2975+ {"notificationContentType", static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW)},
2976+ {"content", nullptr},
2977+ };
2978+ 
2979+ auto *request = NotificationRequest::FromJson(jsonObject);
2980+ ASSERT_NE(request, nullptr);
2981+ EXPECT_EQ(request->GetContent(), nullptr);
2982+ EXPECT_TRUE(request->IsCommonLiveView());
2983+ EXPECT_EQ(request->CheckNotificationRequest(nullptr), ERR_ANS_INNER_INVALID_PARAM);
2984+ delete request;
2985+}
2806} // namespace Notification2986} // namespace Notification
2807} // namespace OHOS2987} // namespace OHOS