已开启
fix(liveview): CheckNotificationRequest 增加空 content 判空校验防止崩溃 #5012
stepend98创建于 7 天前
fix(liveview): CheckNotificationRequest 增加空 content 判空校验防止崩溃 #5012
已开启
共 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(¬ificationRequest, 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 Notification | 2986 | } // namespace Notification |
| 2807 | } // namespace OHOS | 2987 | } // namespace OHOS |