158 个文件变更+8223-683
@@ -25,6 +25,27 @@ What do you want to test?
25 25 
26## Core Workflow26## Core Workflow
27 27 
28+### Step 0: Hard Constraint — Test-Only Changes (强制约束:仅修改测试代码)
29+ 
30+When writing TDD, you may **ONLY modify test code**. Production code must not be touched:
31+ 
32+**Allowed to modify:**
33+- Test files (`*_test.cpp`) under any `test/` directory
34+- Test mock files (`mock_*.cpp` / `mock_*.h` under test directories, including `mock/include/`)
35+- Test `BUILD.gn` (adding test sources, mocks, or test-target-only config)
36+- Test fixtures/helpers located under test directories
37+ 
38+**Forbidden to modify:**
39+- Production source files (`services/*/src`, `frameworks/*/src`, `interfaces/`, etc.)
40+- Production headers (`interfaces/inner_api/`, `services/*/include/`, `frameworks/*/include/`, etc.)
41+- Production `BUILD.gn` / `.gni` files
42+- IDL files and any generated proxy/stub code
43+ 
44+**Rules:**
45+- If a branch cannot be covered without changing production code, do NOT change it. Report the limitation instead (e.g., "branch X requires a production-code refactor or a mock of dependency Y").
46+- If existing tests fail due to intentional production-code behavior changes, fix the **tests** (update expectations, fix mock setup, reset mock state pollution) — never the production code.
47+- Verify before finishing: `git diff --stat` must show changes only under test paths (`test/`, `mock/`).
48+ 
28### Step 1: Identify Test Scope49### Step 1: Identify Test Scope
29 50 
30Determine testing scope based on user request:51Determine testing scope based on user request:
@@ -124,7 +145,28 @@ Add new test file to appropriate BUILD.gn:
124 145 
125See [BUILD_CONFIG.md](references/BUILD_CONFIG.md) for BUILD.gn configuration templates.146See [BUILD_CONFIG.md](references/BUILD_CONFIG.md) for BUILD.gn configuration templates.
126 147 
127-### Step 6: Build and Verify148+### Step 6: Post-Generation Checks (新增 TDD 后必检)
149+ 
150+**Scope:** These checks apply ONLY to **newly added tests**. Never modify or delete existing test items because of these checks.
151+ 
152+After generating each new test (TDD), run the following mandatory checks on the new tests:
153+ 
154+1. **Non-tautological assertion:** Every new test MUST contain at least one assertion that can actually fail (non-永真断言).
155+ - Valid: `EXPECT_EQ(result, expectedValue)`, `EXPECT_NE(ptr, nullptr)`, `EXPECT_FALSE(result)`
156+ - Invalid (永真): `EXPECT_EQ(1, 1)`, `EXPECT_TRUE(true)`, `EXPECT_NE(nullptr, nullptr)`
157+ - If a new test contains only tautological assertions, rewrite it with a real verifiable assertion; if none is possible, do not add the test.
158+ 
159+2. **Minimum test body length:** Every new test body must be **at least 3 lines**. If fewer than 3 lines, do not add the test.
160+ 
161+3. **Line length limit:** Every line of the new tests must be **at most 120 characters**. If a line exceeds 120 characters, wrap it, placing the operator at the **end** of the line:
162+ ```cpp
163+ EXPECT_EQ(bundleManagerHelper.GetDistributedNotificationEnabled(bundleName, userId),
164+ false);
165+ ```
166+ 
167+4. **Preserve existing tests:** Do NOT delete or rewrite existing test items, even if they violate checks 1–3. These checks govern only newly generated tests; existing tests may only be changed when explicitly requested (e.g., fixing a broken expectation caused by intentional production-code behavior change).
168+ 
169+### Step 7: Build and Verify
128 170 
1291. **Build test:**1711. **Build test:**
130 ```bash172 ```bash
@@ -221,7 +263,12 @@ HWTEST_F(ClassNameTest, MethodName_00001, Function | SmallTest | Level1)
221 263 
222Before completing test generation, verify:264Before completing test generation, verify:
223 265 
266+- [ ] `git diff --stat` shows changes only under test paths (test files, mocks, test BUILD.gn) — no production code touched (Step 0)
224- [ ] Every test has at least one assertion (EXPECT/ASSERT)267- [ ] Every test has at least one assertion (EXPECT/ASSERT)
268+- [ ] Every new test has at least one non-tautological assertion (can actually fail)
269+- [ ] Every new test body is at least 3 lines (do not add if fewer)
270+- [ ] Every line of the new tests is at most 120 characters; wrapped lines place operators at end of line
271+- [ ] No existing test items deleted or rewritten (Step 6.4)
225- [ ] All tests follow naming convention: `FunctionName_ScenarioNumber`272- [ ] All tests follow naming convention: `FunctionName_ScenarioNumber`
226- [ ] Test documentation includes @tc.name, @tc.desc, @tc.type, @tc.require273- [ ] Test documentation includes @tc.name, @tc.desc, @tc.type, @tc.require
227- [ ] Appropriate use_exceptions in BUILD.gn if using EXPECT_THROW/EXPECT_NO_THROW274- [ ] Appropriate use_exceptions in BUILD.gn if using EXPECT_THROW/EXPECT_NO_THROW
@@ -135,11 +135,40 @@ BadgeNumberCallbackData *BadgeNumberCallbackData::Unmarshalling(Parcel &parcel)
135 135 
136bool BadgeNumberCallbackData::ReadFromParcel(Parcel &parcel)136bool BadgeNumberCallbackData::ReadFromParcel(Parcel &parcel)
137{137{
138- bundle_ = Str16ToStr8(parcel.ReadString16());138+ std::u16string bundle16;
139- appInstanceKey_ = parcel.ReadString();139+ if (!parcel.ReadString16(bundle16)) {
140- uid_ = parcel.ReadInt32();140+ ANS_LOGE("ReadString16 failed");
141- badgeNumber_ = parcel.ReadInt32();141+ return false;
142- instanceKey_ = parcel.ReadInt32();142+ }
143+ bundle_ = Str16ToStr8(bundle16);
144+ 
145+ std::string appInstanceKey;
146+ if (!parcel.ReadString(appInstanceKey)) {
147+ ANS_LOGE("ReadString failed");
148+ return false;
149+ }
150+ appInstanceKey_ = appInstanceKey;
151+ 
152+ int32_t uid = 0;
153+ if (!parcel.ReadInt32(uid)) {
154+ ANS_LOGE("ReadInt32 failed");
155+ return false;
156+ }
157+ uid_ = uid;
158+ 
159+ int32_t badgeNumber = 0;
160+ if (!parcel.ReadInt32(badgeNumber)) {
161+ ANS_LOGE("ReadInt32 failed");
162+ return false;
163+ }
164+ badgeNumber_ = badgeNumber;
165+ 
166+ int32_t instanceKey = 0;
167+ if (!parcel.ReadInt32(instanceKey)) {
168+ ANS_LOGE("ReadInt32 failed");
169+ return false;
170+ }
171+ instanceKey_ = instanceKey;
143 172 
144 return true;173 return true;
145}174}
@@ -216,11 +216,39 @@ bool MessageUser::Marshalling(Parcel &parcel) const
216 216 
217bool MessageUser::ReadFromParcel(Parcel &parcel)217bool MessageUser::ReadFromParcel(Parcel &parcel)
218{218{
219- key_ = parcel.ReadString();219+ std::string key;
220- name_ = parcel.ReadString();220+ if (!parcel.ReadString(key)) {
221- isMachine_ = parcel.ReadBool();221+ ANS_LOGE("ReadString failed");
222- isUserImportant_ = parcel.ReadBool();222+ return false;
223+ }
224+ key_ = key;
223 225 
226+ std::string name;
227+ if (!parcel.ReadString(name)) {
228+ ANS_LOGE("ReadString failed");
229+ return false;
230+ }
231+ name_ = name;
232+ 
233+ bool isMachine = false;
234+ if (!parcel.ReadBool(isMachine)) {
235+ ANS_LOGE("ReadBool failed");
236+ return false;
237+ }
238+ isMachine_ = isMachine;
239+ 
240+ bool isUserImportant = false;
241+ if (!parcel.ReadBool(isUserImportant)) {
242+ ANS_LOGE("ReadBool failed");
243+ return false;
244+ }
245+ isUserImportant_ = isUserImportant;
246+ 
247+ return ReadOptionalFromParcel(parcel);
248+}
249+ 
250+bool MessageUser::ReadOptionalFromParcel(Parcel &parcel)
251+{
224 int32_t empty = VALUE_NULL;252 int32_t empty = VALUE_NULL;
225 if (!parcel.ReadInt32(empty)) {253 if (!parcel.ReadInt32(empty)) {
226 ANS_LOGE("Failed to read VALUE");254 ANS_LOGE("Failed to read VALUE");
@@ -228,10 +256,19 @@ bool MessageUser::ReadFromParcel(Parcel &parcel)
228 }256 }
229 257 
230 if (empty == VALUE_OBJECT) {258 if (empty == VALUE_OBJECT) {
231- uri_ = Uri((parcel.ReadString()));259+ std::string uriStr;
260+ if (!parcel.ReadString(uriStr)) {
261+ ANS_LOGE("ReadString failed");
262+ return false;
263+ }
264+ uri_ = Uri(uriStr);
232 }265 }
233 266 
234- bool valid = parcel.ReadBool();267+ bool valid = false;
268+ if (!parcel.ReadBool(valid)) {
269+ ANS_LOGE("ReadBool failed");
270+ return false;
271+ }
235 if (valid) {272 if (valid) {
236 pixelMap_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());273 pixelMap_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());
237 if (!pixelMap_) {274 if (!pixelMap_) {
@@ -295,8 +295,9 @@ bool Notification::MarshallingString(Parcel &parcel) const
295 return false;295 return false;
296 }296 }
297 297 
298- if (enableSound_ && sound_ != nullptr) {298+ if (enableSound_) {
299- if (!parcel.WriteString(sound_->ToString())) {299+ std::string soundStr = (sound_ != nullptr) ? sound_->ToString() : "";
300+ if (!parcel.WriteString(soundStr)) {
300 ANS_LOGE("Can't write sound");301 ANS_LOGE("Can't write sound");
301 return false;302 return false;
302 }303 }
@@ -312,6 +313,25 @@ bool Notification::MarshallingString(Parcel &parcel) const
312 313 
313bool Notification::MarshallingInt32(Parcel &parcel) const314bool Notification::MarshallingInt32(Parcel &parcel) const
314{315{
316+ int32_t visibleness = static_cast<int32_t>(lockscreenVisibleness_);
317+ if (visibleness < static_cast<int32_t>(NotificationConstant::VisiblenessType::NO_OVERRIDE) ||
318+ visibleness >= static_cast<int32_t>(NotificationConstant::VisiblenessType::ILLEGAL_TYPE)) {
319+ ANS_LOGE("Invalid visibleness: %{public}d", visibleness);
320+ return false;
321+ }
322+ int32_t remindType = static_cast<int32_t>(remindType_);
323+ if (remindType < static_cast<int32_t>(NotificationConstant::RemindType::NONE) ||
324+ remindType > static_cast<int32_t>(NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND)) {
325+ ANS_LOGE("Invalid remind type: %{public}d", remindType);
326+ return false;
327+ }
328+ int32_t sourceType = static_cast<int32_t>(sourceType_);
329+ if (sourceType < static_cast<int32_t>(NotificationConstant::SourceType::TYPE_NORMAL) ||
330+ sourceType > static_cast<int32_t>(NotificationConstant::SourceType::TYPE_TIMER)) {
331+ ANS_LOGE("Invalid source type: %{public}d", sourceType);
332+ return false;
333+ }
334+ 
315 if (!parcel.WriteInt32(ledLightColor_)) {335 if (!parcel.WriteInt32(ledLightColor_)) {
316 ANS_LOGE("Can't write ledLightColor");336 ANS_LOGE("Can't write ledLightColor");
317 return false;337 return false;
@@ -427,64 +447,127 @@ bool Notification::Marshalling(Parcel &parcel) const
427 return true;447 return true;
428}448}
429 449 
430-void Notification::ReadFromParcelBool(Parcel &parcel)450+bool Notification::ReadFromParcelBool(Parcel &parcel)
431{451{
432- // Read enableLight_452+ if (!parcel.ReadBool(enableLight_)) {
433- enableLight_ = parcel.ReadBool();453+ ANS_LOGE("ReadBool failed");
434- 454+ return false;
435- // Read enableSound_455+ }
436- enableSound_ = parcel.ReadBool();456+ if (!parcel.ReadBool(enableSound_)) {
437- 457+ ANS_LOGE("ReadBool failed");
438- // Read enableVibration_458+ return false;
439- enableVibration_ = parcel.ReadBool();459+ }
440- 460+ if (!parcel.ReadBool(enableVibration_)) {
441- // Read isRemoveAllowed_461+ ANS_LOGE("ReadBool failed");
442- isRemoveAllowed_ = parcel.ReadBool();462+ return false;
463+ }
464+ if (!parcel.ReadBool(isRemoveAllowed_)) {
465+ ANS_LOGE("ReadBool failed");
466+ return false;
467+ }
468+ return true;
443}469}
444 470 
445-void Notification::ReadFromParcelString(Parcel &parcel)471+bool Notification::ReadFromParcelString(Parcel &parcel)
446{472{
447- // Read key_473+ std::string key;
448- key_ = parcel.ReadString();474+ if (!parcel.ReadString(key)) {
475+ ANS_LOGE("ReadString failed");
476+ return false;
477+ }
478+ key_ = key;
449 479 
450- // Read sound_
451 if (enableSound_) {480 if (enableSound_) {
452- sound_ = std::make_shared<Uri>(parcel.ReadString());481+ std::string soundStr;
482+ if (!parcel.ReadString(soundStr)) {
483+ ANS_LOGE("ReadString failed");
484+ return false;
485+ }
486+ sound_ = std::make_shared<Uri>(soundStr);
453 }487 }
454 488 
455- // Read deviceId_489+ std::string deviceId;
456- deviceId_ = parcel.ReadString();490+ if (!parcel.ReadString(deviceId)) {
491+ ANS_LOGE("ReadString failed");
492+ return false;
493+ }
494+ deviceId_ = deviceId;
495+ return true;
457}496}
458 497 
459-void Notification::ReadFromParcelInt32(Parcel &parcel)498+bool Notification::ReadFromParcelInt32(Parcel &parcel)
460{499{
461- // Read ledLightColor_500+ if (!parcel.ReadInt32(ledLightColor_)) {
462- ledLightColor_ = parcel.ReadInt32();501+ ANS_LOGE("ReadInt32 failed");
502+ return false;
503+ }
463 504 
464- // Read lockscreenVisibleness_505+ int32_t visibleness = 0;
465- lockscreenVisibleness_ = static_cast<NotificationConstant::VisiblenessType>(parcel.ReadInt32());506+ if (!parcel.ReadInt32(visibleness)) {
507+ ANS_LOGE("ReadInt32 failed");
508+ return false;
509+ }
510+ if (visibleness < static_cast<int32_t>(NotificationConstant::VisiblenessType::NO_OVERRIDE) ||
511+ visibleness >= static_cast<int32_t>(NotificationConstant::VisiblenessType::ILLEGAL_TYPE)) {
512+ ANS_LOGE("Invalid visibleness: %{public}d", visibleness);
513+ return false;
514+ }
515+ lockscreenVisibleness_ = static_cast<NotificationConstant::VisiblenessType>(visibleness);
466 516 
467- // Read remindType_517+ int32_t remindType = 0;
468- remindType_ = static_cast<NotificationConstant::RemindType>(parcel.ReadInt32());518+ if (!parcel.ReadInt32(remindType)) {
519+ ANS_LOGE("ReadInt32 failed");
520+ return false;
521+ }
522+ if (remindType < static_cast<int32_t>(NotificationConstant::RemindType::NONE) ||
523+ remindType > static_cast<int32_t>(NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND)) {
524+ ANS_LOGE("Invalid remind type: %{public}d", remindType);
525+ return false;
526+ }
527+ remindType_ = static_cast<NotificationConstant::RemindType>(remindType);
469 528 
470- // Read sourceType_529+ int32_t sourceType = 0;
471- sourceType_ = static_cast<NotificationConstant::SourceType>(parcel.ReadInt32());530+ if (!parcel.ReadInt32(sourceType)) {
531+ ANS_LOGE("ReadInt32 failed");
532+ return false;
533+ }
534+ if (sourceType < static_cast<int32_t>(NotificationConstant::SourceType::TYPE_NORMAL) ||
535+ sourceType > static_cast<int32_t>(NotificationConstant::SourceType::TYPE_TIMER)) {
536+ ANS_LOGE("Invalid source type: %{public}d", sourceType);
537+ return false;
538+ }
539+ sourceType_ = static_cast<NotificationConstant::SourceType>(sourceType);
540+ return true;
472}541}
473 542 
474-void Notification::ReadFromParcelInt64(Parcel &parcel)543+bool Notification::ReadFromParcelInt64(Parcel &parcel)
475{544{
476- // Read postTime_545+ if (!parcel.ReadInt64(postTime_)) {
477- postTime_ = parcel.ReadInt64();546+ ANS_LOGE("ReadInt64 failed");
478- 547+ return false;
479- // Read vibrationStyle_548+ }
480- parcel.ReadInt64Vector(&vibrationStyle_);549+ if (!parcel.ReadInt64Vector(&vibrationStyle_)) {
550+ ANS_LOGE("ReadInt64Vector failed");
551+ return false;
552+ }
553+ return true;
481}554}
482 555 
483-void Notification::ReadFromParcelUint64(Parcel &parcel)556+bool Notification::ReadFromParcelUint64(Parcel &parcel)
484{557{
485- updateTimerId_ = parcel.ReadUint64();558+ if (!parcel.ReadUint64(updateTimerId_)) {
486- finishTimerId_ = parcel.ReadUint64();559+ ANS_LOGE("ReadUint64 failed");
487- archiveTimerId_ = parcel.ReadUint64();560+ return false;
561+ }
562+ if (!parcel.ReadUint64(finishTimerId_)) {
563+ ANS_LOGE("ReadUint64 failed");
564+ return false;
565+ }
566+ if (!parcel.ReadUint64(archiveTimerId_)) {
567+ ANS_LOGE("ReadUint64 failed");
568+ return false;
569+ }
570+ return true;
488}571}
489 572 
490bool Notification::ReadFromParcelParcelable(Parcel &parcel)573bool Notification::ReadFromParcelParcelable(Parcel &parcel)
@@ -496,7 +579,11 @@ bool Notification::ReadFromParcelParcelable(Parcel &parcel)
496 }579 }
497 580 
498 // Read voiceContent_581 // Read voiceContent_
499- bool hasVoiceContent = parcel.ReadBool();582+ bool hasVoiceContent = false;
583+ if (!parcel.ReadBool(hasVoiceContent)) {
584+ ANS_LOGE("ReadBool failed");
585+ return false;
586+ }
500 if (hasVoiceContent) {587 if (hasVoiceContent) {
501 voiceContent_ = std::shared_ptr<NotificationVoiceContent>(parcel.ReadParcelable<NotificationVoiceContent>());588 voiceContent_ = std::shared_ptr<NotificationVoiceContent>(parcel.ReadParcelable<NotificationVoiceContent>());
502 if (voiceContent_ == nullptr) {589 if (voiceContent_ == nullptr) {
@@ -505,7 +592,11 @@ bool Notification::ReadFromParcelParcelable(Parcel &parcel)
505 }592 }
506 }593 }
507 594 
508- bool hasNotificationClassification = parcel.ReadBool();595+ bool hasNotificationClassification = false;
596+ if (!parcel.ReadBool(hasNotificationClassification)) {
597+ ANS_LOGE("ReadBool failed");
598+ return false;
599+ }
509 if (hasNotificationClassification) {600 if (hasNotificationClassification) {
510 notificationClassification_ = parcel.ReadStrongParcelable<NotificationClassification>();601 notificationClassification_ = parcel.ReadStrongParcelable<NotificationClassification>();
511 if (notificationClassification_ == nullptr) {602 if (notificationClassification_ == nullptr) {
@@ -518,11 +609,26 @@ bool Notification::ReadFromParcelParcelable(Parcel &parcel)
518 609 
519bool Notification::ReadFromParcel(Parcel &parcel)610bool Notification::ReadFromParcel(Parcel &parcel)
520{611{
521- ReadFromParcelBool(parcel);612+ if (!ReadFromParcelBool(parcel)) {
522- ReadFromParcelString(parcel);613+ ANS_LOGE("ReadFromParcelBool from parcel error");
523- ReadFromParcelInt32(parcel);614+ return false;
524- ReadFromParcelInt64(parcel);615+ }
525- ReadFromParcelUint64(parcel);616+ if (!ReadFromParcelString(parcel)) {
617+ ANS_LOGE("ReadFromParcelString from parcel error");
618+ return false;
619+ }
620+ if (!ReadFromParcelInt32(parcel)) {
621+ ANS_LOGE("ReadFromParcelInt32 from parcel error");
622+ return false;
623+ }
624+ if (!ReadFromParcelInt64(parcel)) {
625+ ANS_LOGE("ReadFromParcelInt64 from parcel error");
626+ return false;
627+ }
628+ if (!ReadFromParcelUint64(parcel)) {
629+ ANS_LOGE("ReadFromParcelUint64 from parcel error");
630+ return false;
631+ }
526 if (!ReadFromParcelParcelable(parcel)) {632 if (!ReadFromParcelParcelable(parcel)) {
527 ANS_LOGE("ReadFromParcelParcelable from parcel error");633 ANS_LOGE("ReadFromParcelParcelable from parcel error");
528 return false;634 return false;
@@ -564,6 +670,12 @@ void Notification::SetLedLightColor(const int32_t &color)
564 670 
565void Notification::SetLockScreenVisbleness(const NotificationConstant::VisiblenessType &visbleness)671void Notification::SetLockScreenVisbleness(const NotificationConstant::VisiblenessType &visbleness)
566{672{
673+ int32_t type = static_cast<int32_t>(visbleness);
674+ if (type < static_cast<int32_t>(NotificationConstant::VisiblenessType::NO_OVERRIDE) ||
675+ type >= static_cast<int32_t>(NotificationConstant::VisiblenessType::ILLEGAL_TYPE)) {
676+ ANS_LOGE("Invalid visibleness: %{public}d", type);
677+ return;
678+ }
567 lockscreenVisibleness_ = visbleness;679 lockscreenVisibleness_ = visbleness;
568}680}
569 681 
@@ -594,6 +706,12 @@ void Notification::SetRemoveAllowed(bool removeAllowed)
594 706 
595void Notification::SetSourceType(NotificationConstant::SourceType sourceType)707void Notification::SetSourceType(NotificationConstant::SourceType sourceType)
596{708{
709+ int32_t type = static_cast<int32_t>(sourceType);
710+ if (type < static_cast<int32_t>(NotificationConstant::SourceType::TYPE_NORMAL) ||
711+ type > static_cast<int32_t>(NotificationConstant::SourceType::TYPE_TIMER)) {
712+ ANS_LOGE("Invalid source type: %{public}d", type);
713+ return;
714+ }
597 sourceType_ = sourceType;715 sourceType_ = sourceType;
598}716}
599 717 
@@ -221,49 +221,49 @@ NotificationContent *NotificationContent::Unmarshalling(Parcel &parcel)
221 return pContent;221 return pContent;
222}222}
223 223 
224-bool NotificationContent::ReadFromParcel(Parcel &parcel)224+namespace {
225+template<typename T>
226+std::shared_ptr<NotificationBasicContent> ReadContentAs(Parcel &parcel)
225{227{
226- contentType_ = static_cast<NotificationContent::Type>(parcel.ReadInt32());228+ return std::static_pointer_cast<NotificationBasicContent>(
227- 229+ std::shared_ptr<T>(parcel.ReadParcelable<T>()));
228- if (!parcel.ReadBool()) {230+}
229- return true;231+}
230- }
231 232 
233+bool NotificationContent::ReadContentFromParcel(Parcel &parcel)
234+{
232 switch (contentType_) {235 switch (contentType_) {
233 case NotificationContent::Type::BASIC_TEXT:236 case NotificationContent::Type::BASIC_TEXT:
234- content_ = std::static_pointer_cast<NotificationBasicContent>(237+ content_ = ReadContentAs<NotificationNormalContent>(parcel);
235- std::shared_ptr<NotificationNormalContent>(parcel.ReadParcelable<NotificationNormalContent>()));
236 break;238 break;
237 case NotificationContent::Type::CONVERSATION:239 case NotificationContent::Type::CONVERSATION:
238- content_ =240+ content_ = ReadContentAs<NotificationConversationalContent>(parcel);
239- std::static_pointer_cast<NotificationBasicContent>(std::shared_ptr<NotificationConversationalContent>(
240- parcel.ReadParcelable<NotificationConversationalContent>()));
241 break;241 break;
242 case NotificationContent::Type::LONG_TEXT:242 case NotificationContent::Type::LONG_TEXT:
243- content_ = std::static_pointer_cast<NotificationBasicContent>(243+ content_ = ReadContentAs<NotificationLongTextContent>(parcel);
244- std::shared_ptr<NotificationLongTextContent>(parcel.ReadParcelable<NotificationLongTextContent>()));
245 break;244 break;
246 case NotificationContent::Type::MEDIA:245 case NotificationContent::Type::MEDIA:
247- content_ = std::static_pointer_cast<NotificationBasicContent>(246+ content_ = ReadContentAs<NotificationMediaContent>(parcel);
248- std::shared_ptr<NotificationMediaContent>(parcel.ReadParcelable<NotificationMediaContent>()));
249 break;247 break;
250 case NotificationContent::Type::MULTILINE:248 case NotificationContent::Type::MULTILINE:
251- content_ = std::static_pointer_cast<NotificationBasicContent>(249+ content_ = ReadContentAs<NotificationMultiLineContent>(parcel);
252- std::shared_ptr<NotificationMultiLineContent>(parcel.ReadParcelable<NotificationMultiLineContent>()));
253 break;250 break;
254 case NotificationContent::Type::PICTURE:251 case NotificationContent::Type::PICTURE:
255- content_ = std::static_pointer_cast<NotificationBasicContent>(252+ content_ = ReadContentAs<NotificationPictureContent>(parcel);
256- std::shared_ptr<NotificationPictureContent>(parcel.ReadParcelable<NotificationPictureContent>()));
257 break;253 break;
258 case NotificationContent::Type::LOCAL_LIVE_VIEW:254 case NotificationContent::Type::LOCAL_LIVE_VIEW:
259- content_ = std::static_pointer_cast<NotificationBasicContent>(255+ content_ = ReadContentAs<NotificationLocalLiveViewContent>(parcel);
260- std::shared_ptr<NotificationLocalLiveViewContent>(
261- parcel.ReadParcelable<NotificationLocalLiveViewContent>()));
262 break;256 break;
263- case NotificationContent::Type::LIVE_VIEW:257+ case NotificationContent::Type::LIVE_VIEW: {
264- content_ = std::static_pointer_cast<NotificationBasicContent>(258+ auto liveView = std::shared_ptr<NotificationLiveViewContent>(
265- std::shared_ptr<NotificationLiveViewContent>(parcel.ReadParcelable<NotificationLiveViewContent>()));259+ parcel.ReadParcelable<NotificationLiveViewContent>());
260+ if (liveView == nullptr) {
261+ ANS_LOGE("null content");
262+ return false;
263+ }
264+ content_ = std::static_pointer_cast<NotificationBasicContent>(liveView);
266 break;265 break;
266+ }
267 default:267 default:
268 ANS_LOGE("Invalid contentType");268 ANS_LOGE("Invalid contentType");
269 return false;269 return false;
@@ -272,10 +272,20 @@ bool NotificationContent::ReadFromParcel(Parcel &parcel)
272 ANS_LOGE("Failed to read content");272 ANS_LOGE("Failed to read content");
273 return false;273 return false;
274 }274 }
275- 
276 return true;275 return true;
277}276}
278 277 
278+bool NotificationContent::ReadFromParcel(Parcel &parcel)
279+{
280+ contentType_ = static_cast<NotificationContent::Type>(parcel.ReadInt32());
281+ 
282+ if (!parcel.ReadBool()) {
283+ return true;
284+ }
285+ 
286+ return ReadContentFromParcel(parcel);
287+}
288+ 
279bool NotificationContent::ConvertJsonToContent(NotificationContent *target, const nlohmann::json &jsonObject)289bool NotificationContent::ConvertJsonToContent(NotificationContent *target, const nlohmann::json &jsonObject)
280{290{
281 if (target == nullptr) {291 if (target == nullptr) {
@@ -14,6 +14,8 @@
14 */14 */
15#include "notification_disable.h"15#include "notification_disable.h"
16 16 
17+#include <cinttypes>
18+ 
17#include "ans_const_define.h"19#include "ans_const_define.h"
18#include "ans_log_wrapper.h"20#include "ans_log_wrapper.h"
19#include "nlohmann/json.hpp"21#include "nlohmann/json.hpp"
@@ -87,8 +89,18 @@ bool NotificationDisable::Marshalling(Parcel &parcel) const
87 89 
88bool NotificationDisable::ReadFromParcel(Parcel &parcel)90bool NotificationDisable::ReadFromParcel(Parcel &parcel)
89{91{
90- disabled_ = parcel.ReadBool();92+ bool disabled = false;
91- auto size = parcel.ReadUint32();93+ if (!parcel.ReadBool(disabled)) {
94+ ANS_LOGE("ReadBool failed");
95+ return false;
96+ }
97+ disabled_ = disabled;
98+ 
99+ uint32_t size = 0;
100+ if (!parcel.ReadUint32(size)) {
101+ ANS_LOGE("ReadUint32 failed");
102+ return false;
103+ }
92 if (size > MAX_NOTIFICATION_DISABLE_NUM) {104 if (size > MAX_NOTIFICATION_DISABLE_NUM) {
93 ANS_LOGE("Size exceeds the range");105 ANS_LOGE("Size exceeds the range");
94 return false;106 return false;
@@ -100,7 +112,13 @@ bool NotificationDisable::ReadFromParcel(Parcel &parcel)
100 return false;112 return false;
101 }113 }
102 }114 }
103- userId_ = parcel.ReadInt32();115+ 
116+ int32_t userId = 0;
117+ if (!parcel.ReadInt32(userId)) {
118+ ANS_LOGE("ReadInt32 failed");
119+ return false;
120+ }
121+ userId_ = userId;
104 return true;122 return true;
105}123}
106 124 
@@ -144,6 +162,10 @@ void NotificationDisable::FromJson(const std::string &jsonObj)
144 }162 }
145 if (jsonObject.find(BUNDLELIST) != jsonEnd && jsonObject.at(BUNDLELIST).is_array()) {163 if (jsonObject.find(BUNDLELIST) != jsonEnd && jsonObject.at(BUNDLELIST).is_array()) {
146 auto bundleListJson = jsonObject.at(BUNDLELIST);164 auto bundleListJson = jsonObject.at(BUNDLELIST);
165+ if (bundleListJson.size() > MAX_NOTIFICATION_DISABLE_NUM) {
166+ ANS_LOGE("bundleList size exceeds limit: %{public}zu", bundleListJson.size());
167+ return;
168+ }
147 for (const auto &bundle : bundleListJson) {169 for (const auto &bundle : bundleListJson) {
148 if (bundle.is_string()) {170 if (bundle.is_string()) {
149 bundleList_.push_back(bundle.get<std::string>());171 bundleList_.push_back(bundle.get<std::string>());
@@ -151,7 +173,12 @@ void NotificationDisable::FromJson(const std::string &jsonObj)
151 }173 }
152 }174 }
153 if (jsonObject.find(USERID) != jsonEnd && jsonObject.at(USERID).is_number_integer()) {175 if (jsonObject.find(USERID) != jsonEnd && jsonObject.at(USERID).is_number_integer()) {
154- userId_ = jsonObject.at(USERID).get<int32_t>();176+ int64_t val = jsonObject.at(USERID).get<int64_t>();
177+ if (val < INT32_MIN || val > INT32_MAX) {
178+ ANS_LOGE("userId out of range: %{public}" PRId64, val);
179+ } else {
180+ userId_ = static_cast<int32_t>(val);
181+ }
155 }182 }
156}183}
157}184}
@@ -63,6 +63,11 @@ std::vector<NotificationBundleOption> NotificationDoNotDisturbProfile::GetProfil
63 63 
64bool NotificationDoNotDisturbProfile::Marshalling(Parcel &parcel) const64bool NotificationDoNotDisturbProfile::Marshalling(Parcel &parcel) const
65{65{
66+ auto size = trustList_.size();
67+ if (size > MAX_PARCELABLE_VECTOR_NUM) {
68+ ANS_LOGE("Size exceeds the range.");
69+ return false;
70+ }
66 if (!parcel.WriteInt64(id_)) {71 if (!parcel.WriteInt64(id_)) {
67 ANS_LOGE("Failed to write do not disturb id.");72 ANS_LOGE("Failed to write do not disturb id.");
68 return false;73 return false;
@@ -71,11 +76,6 @@ bool NotificationDoNotDisturbProfile::Marshalling(Parcel &parcel) const
71 ANS_LOGE("Failed to write do not disturb name.");76 ANS_LOGE("Failed to write do not disturb name.");
72 return false;77 return false;
73 }78 }
74- auto size = trustList_.size();
75- if (size > MAX_PARCELABLE_VECTOR_NUM) {
76- ANS_LOGE("Size exceeds the range.");
77- return false;
78- }
79 if (!parcel.WriteInt32(size)) {79 if (!parcel.WriteInt32(size)) {
80 ANS_LOGE("Failed to write do not disturb trust list size.");80 ANS_LOGE("Failed to write do not disturb trust list size.");
81 return false;81 return false;
@@ -101,9 +101,21 @@ NotificationDoNotDisturbProfile *NotificationDoNotDisturbProfile::Unmarshalling(
101 101 
102bool NotificationDoNotDisturbProfile::ReadFromParcel(Parcel &parcel)102bool NotificationDoNotDisturbProfile::ReadFromParcel(Parcel &parcel)
103{103{
104- id_ = parcel.ReadInt64();104+ if (!parcel.ReadInt64(id_)) {
105- name_ = parcel.ReadString();105+ ANS_LOGE("ReadInt64 failed");
106- auto size = parcel.ReadUint32();106+ return false;
107+ }
108+ std::string name;
109+ if (!parcel.ReadString(name)) {
110+ ANS_LOGE("ReadString failed");
111+ return false;
112+ }
113+ name_ = name;
114+ uint32_t size = 0;
115+ if (!parcel.ReadUint32(size)) {
116+ ANS_LOGE("ReadUint32 failed");
117+ return false;
118+ }
107 if (size > MAX_PARCELABLE_VECTOR_NUM) {119 if (size > MAX_PARCELABLE_VECTOR_NUM) {
108 ANS_LOGE("Size exceeds the range.");120 ANS_LOGE("Size exceeds the range.");
109 return false;121 return false;
@@ -249,7 +249,10 @@ bool NotificationIconButton::ReadFromParcel(Parcel &parcel)
249 }249 }
250 250 
251 bool valid {false};251 bool valid {false};
252- valid = parcel.ReadBool();252+ if (!parcel.ReadBool(valid)) {
253+ ANS_LOGE("ReadBool failed");
254+ return false;
255+ }
253 if (valid) {256 if (valid) {
254 iconImage_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());257 iconImage_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());
255 if (!iconImage_) {258 if (!iconImage_) {
@@ -258,7 +261,10 @@ bool NotificationIconButton::ReadFromParcel(Parcel &parcel)
258 }261 }
259 }262 }
260 263 
261- valid = parcel.ReadBool();264+ if (!parcel.ReadBool(valid)) {
265+ ANS_LOGE("ReadBool failed");
266+ return false;
267+ }
262 if (valid) {268 if (valid) {
263 if (!ReadResourceFromParcel(parcel, iconResource_)) {269 if (!ReadResourceFromParcel(parcel, iconResource_)) {
264 ANS_LOGE("Failed to read button icon resource.");270 ANS_LOGE("Failed to read button icon resource.");
@@ -377,6 +377,46 @@ bool NotificationLiveViewContent::ReadFromParcel(Parcel &parcel)
377 377 
378 isOnlyLocalUpdate_ = parcel.ReadBool();378 isOnlyLocalUpdate_ = parcel.ReadBool();
379 379 
380+ if (!ReadPictureMapFromParcel(parcel)) {
381+ return false;
382+ }
383+ 
384+ valid = parcel.ReadBool();
385+ if (valid) {
386+ extensionWantAgent_ = std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>(
387+ parcel.ReadParcelable<AbilityRuntime::WantAgent::WantAgent>());
388+ if (!extensionWantAgent_) {
389+ ANS_LOGE("null wantAgent");
390+ return false;
391+ }
392+ }
393+ if (!ReadTrailingFieldsFromParcel(parcel)) {
394+ return false;
395+ }
396+ return true;
397+}
398+ 
399+bool NotificationLiveViewContent::ReadTrailingFieldsFromParcel(Parcel &parcel)
400+{
401+ uint32_t removeState = 0;
402+ if (!parcel.ReadUint32(removeState)) {
403+ ANS_LOGE("Failed to read removeOnProcessExitState");
404+ return false;
405+ }
406+ if (removeState > static_cast<uint32_t>(LiveViewRemoveStatus::LIVE_VIEW_NO_REMOVE)) {
407+ ANS_LOGE("Invalid removeOnProcessExitState value: %{public}u", removeState);
408+ return false;
409+ }
410+ removeOnProcessExitState_ = static_cast<NotificationLiveViewContent::LiveViewRemoveStatus>(removeState);
411+ if (!parcel.ReadInt32(createPid_)) {
412+ ANS_LOGE("Failed to read createPid");
413+ return false;
414+ }
415+ return true;
416+}
417+ 
418+bool NotificationLiveViewContent::ReadPictureMapFromParcel(Parcel &parcel)
419+{
380 uint64_t len = parcel.ReadUint64();420 uint64_t len = parcel.ReadUint64();
381 if (len > MAX_PARCELABLE_VECTOR_NUM) {421 if (len > MAX_PARCELABLE_VECTOR_NUM) {
382 ANS_LOGE("Size exceeds the range.");422 ANS_LOGE("Size exceeds the range.");
@@ -391,18 +431,6 @@ bool NotificationLiveViewContent::ReadFromParcel(Parcel &parcel)
391 }431 }
392 pictureMap_[key] = pixelMapVec;432 pictureMap_[key] = pixelMapVec;
393 }433 }
394- 
395- valid = parcel.ReadBool();
396- if (valid) {
397- extensionWantAgent_ = std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>(
398- parcel.ReadParcelable<AbilityRuntime::WantAgent::WantAgent>());
399- if (!extensionWantAgent_) {
400- ANS_LOGE("null wantAgent");
401- return false;
402- }
403- }
404- removeOnProcessExitState_ = static_cast<NotificationLiveViewContent::LiveViewRemoveStatus>(parcel.ReadUint32());
405- createPid_ = parcel.ReadInt32();
406 return true;434 return true;
407}435}
408 436 
@@ -76,7 +76,7 @@ ResourceVectorPtr NotificationLocalLiveViewButton::GetAllButtonIconResource() co
76void NotificationLocalLiveViewButton::addSingleButtonIconResource(76void NotificationLocalLiveViewButton::addSingleButtonIconResource(
77 std::shared_ptr<ResourceManager::Resource> &iconResource)77 std::shared_ptr<ResourceManager::Resource> &iconResource)
78{78{
79- if (buttonIcons_.size() >= BUTTON_MAX_SIZE) {79+ if (buttonIconsResource_.size() >= BUTTON_MAX_SIZE) {
80 ANS_LOGW("already added 3 buttonIcon");80 ANS_LOGW("already added 3 buttonIcon");
81 return;81 return;
82 }82 }
@@ -244,6 +244,10 @@ bool NotificationMultiLineContent::ReadFromParcel(Parcel &parcel)
244 for (std::uint8_t i = 0; i < lineWantAgentsLength; i++) {244 for (std::uint8_t i = 0; i < lineWantAgentsLength; i++) {
245 auto wantAgent = std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>(245 auto wantAgent = std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>(
246 parcel.ReadParcelable<AbilityRuntime::WantAgent::WantAgent>());246 parcel.ReadParcelable<AbilityRuntime::WantAgent::WantAgent>());
247+ if (wantAgent == nullptr) {
248+ ANS_LOGE("Failed to read wantAgent, index is %{public}u", i);
249+ return false;
250+ }
247 lineWantAgents_.push_back(wantAgent);251 lineWantAgents_.push_back(wantAgent);
248 }252 }
249 253 
@@ -540,6 +540,11 @@ void NotificationRequest::SetShowStopwatch(bool isShow)
540 540 
541void NotificationRequest::SetSlotType(NotificationConstant::SlotType slotType)541void NotificationRequest::SetSlotType(NotificationConstant::SlotType slotType)
542{542{
543+ if (static_cast<int32_t>(slotType) < 0 ||
544+ static_cast<int32_t>(slotType) >= static_cast<int32_t>(NotificationConstant::SlotType::ILLEGAL_TYPE)) {
545+ ANS_LOGE("Invalid SlotType: %{public}d", static_cast<int32_t>(slotType));
546+ return;
547+ }
543 slotType_ = slotType;548 slotType_ = slotType;
544}549}
545 550 
@@ -647,8 +652,12 @@ void NotificationRequest::SetNotificationUserInputHistory(const std::vector<std:
647 return;652 return;
648 }653 }
649 654 
650- auto vsize = std::min(NotificationRequest::MAX_USER_INPUT_HISTORY, text.size());655+ if (text.size() > NotificationRequest::MAX_USER_INPUT_HISTORY) {
651- userInputHistory_.assign(text.begin(), text.begin() + vsize);656+ ANS_LOGE("userInputHistory size exceeds limit: %{public}zu", text.size());
657+ return;
658+ }
659+ 
660+ userInputHistory_.assign(text.begin(), text.end());
652}661}
653 662 
654std::vector<std::string> NotificationRequest::GetNotificationUserInputHistory() const663std::vector<std::string> NotificationRequest::GetNotificationUserInputHistory() const
@@ -738,6 +747,10 @@ void NotificationRequest::SetDevicesSupportDisplay(const std::vector<std::string
738 747 
739void NotificationRequest::SetDevicesSupportOperate(const std::vector<std::string> &devices)748void NotificationRequest::SetDevicesSupportOperate(const std::vector<std::string> &devices)
740{749{
750+ if (devices.size() > static_cast<size_t>(MAX_PARCELABLE_VECTOR_NUM)) {
751+ ANS_LOGE("devices size exceeds limit: %{public}zu", devices.size());
752+ return;
753+ }
741 distributedOptions_.SetDevicesSupportOperate(devices);754 distributedOptions_.SetDevicesSupportOperate(devices);
742}755}
743 756 
@@ -753,6 +766,10 @@ void NotificationRequest::SetCreatorUserId(int32_t userId)
753 766 
754int32_t NotificationRequest::GetCreatorUserId() const767int32_t NotificationRequest::GetCreatorUserId() const
755{768{
769+ if (creatorUserId_ < 0) {
770+ ANS_LOGE("Invalid creatorUserId: %{public}d", creatorUserId_);
771+ return SUBSCRIBE_USER_INIT;
772+ }
756 return creatorUserId_;773 return creatorUserId_;
757}774}
758 775 
@@ -960,12 +977,15 @@ NotificationRequest *NotificationRequest::CollaborationFromJson(const std::strin
960 return nullptr;977 return nullptr;
961 }978 }
962 979 
963- const auto &jsonEnd = jsonObject.cend();980+ if (jsonObject.contains("extraInfo") && jsonObject.at("extraInfo").is_string()) {
964- if (jsonObject.find("extraInfo") != jsonEnd && jsonObject.at("extraInfo").is_string()) {
965 auto extraInfoStr = jsonObject.at("extraInfo").get<std::string>();981 auto extraInfoStr = jsonObject.at("extraInfo").get<std::string>();
966 if (!extraInfoStr.empty()) {982 if (!extraInfoStr.empty()) {
967- AAFwk::WantParams params = NotificationWantParamsHelper::ParseWantParams(extraInfoStr);983+ if (!nlohmann::json::accept(extraInfoStr)) {
968- pRequest->additionalParams_ = std::make_shared<AAFwk::WantParams>(params);984+ ANS_LOGE("extraInfo is not valid JSON, skip ParseWantParams");
985+ } else {
986+ AAFwk::WantParams params = NotificationWantParamsHelper::ParseWantParams(extraInfoStr);
987+ pRequest->additionalParams_ = std::make_shared<AAFwk::WantParams>(params);
988+ }
969 }989 }
970 }990 }
971 991 
@@ -1020,7 +1040,7 @@ bool NotificationRequest::ConvertJsonToTemplate(
1020 if (templateOptionObj.find("templateData") != templateOptionObj.cend() &&1040 if (templateOptionObj.find("templateData") != templateOptionObj.cend() &&
1021 templateOptionObj.at("templateData").is_string()) {1041 templateOptionObj.at("templateData").is_string()) {
1022 std::string data = templateOptionObj.at("templateData").get<std::string>();1042 std::string data = templateOptionObj.at("templateData").get<std::string>();
1023- if (!data.empty()) {1043+ if (!data.empty() && data.size() <= MAX_PARCELABLE_VECTOR_NUM) {
1024 AAFwk::WantParams params = NotificationWantParamsHelper::ParseWantParams(data);1044 AAFwk::WantParams params = NotificationWantParamsHelper::ParseWantParams(data);
1025 templatePtr->SetTemplateData(std::make_shared<AAFwk::WantParams>(params));1045 templatePtr->SetTemplateData(std::make_shared<AAFwk::WantParams>(params));
1026 }1046 }
@@ -2128,6 +2148,10 @@ bool NotificationRequest::ReadFromParcel(Parcel &parcel)
2128 ANS_LOGE("Failed to read userInputHistory");2148 ANS_LOGE("Failed to read userInputHistory");
2129 return false;2149 return false;
2130 }2150 }
2151+ if (userInputHistory_.size() > NotificationRequest::MAX_USER_INPUT_HISTORY) {
2152+ ANS_LOGE("userInputHistory size exceeds limit: %{public}zu", userInputHistory_.size());
2153+ return false;
2154+ }
2131 2155 
2132 auto pOpt = parcel.ReadParcelable<NotificationDistributedOptions>();2156 auto pOpt = parcel.ReadParcelable<NotificationDistributedOptions>();
2133 if (pOpt == nullptr) {2157 if (pOpt == nullptr) {
@@ -2575,6 +2599,23 @@ bool NotificationRequest::ConvertGroupInfoToJson(nlohmann::json &jsonObject) con
2575 return true;2599 return true;
2576}2600}
2577 2601 
2602+namespace {
2603+template<typename T>
2604+void ReadIntFromJson(const nlohmann::json &jsonObject, const std::string &key,
2605+ int64_t minVal, int64_t maxVal, T &out)
2606+{
2607+ if (jsonObject.find(key) == jsonObject.cend() || !jsonObject.at(key).is_number_integer()) {
2608+ return;
2609+ }
2610+ int64_t val = jsonObject.at(key).get<int64_t>();
2611+ if (val >= minVal && val <= maxVal) {
2612+ out = static_cast<T>(val);
2613+ } else {
2614+ ANS_LOGE("%{public}s out of range: %{public}" PRId64, key.c_str(), val);
2615+ }
2616+}
2617+}
2618+ 
2578void NotificationRequest::ConvertJsonToNumExt(2619void NotificationRequest::ConvertJsonToNumExt(
2579 NotificationRequest *target, const nlohmann::json &jsonObject)2620 NotificationRequest *target, const nlohmann::json &jsonObject)
2580{2621{
@@ -2582,38 +2623,14 @@ void NotificationRequest::ConvertJsonToNumExt(
2582 ANS_LOGE("target is nullptr");2623 ANS_LOGE("target is nullptr");
2583 return;2624 return;
2584 }2625 }
2585-
2586- const auto &jsonEnd = jsonObject.cend();
2587 2626 
2588- if (jsonObject.find("updateDeadLine") != jsonEnd && jsonObject.at("updateDeadLine").is_number_integer()) {2627+ ReadIntFromJson(jsonObject, "updateDeadLine", INT64_MIN, INT64_MAX, target->updateDeadLine_);
2589- target->updateDeadLine_ = jsonObject.at("updateDeadLine").get<int64_t>();2628+ ReadIntFromJson(jsonObject, "finishDeadLine", INT64_MIN, INT64_MAX, target->finishDeadLine_);
2590- }2629+ ReadIntFromJson(jsonObject, "triggerDeadLine", INT64_MIN, INT64_MAX, target->triggerDeadLine_);
2591- 2630+ ReadIntFromJson(jsonObject, "ownerUserId", INT32_MIN, INT32_MAX, target->ownerUserId_);
2592- if (jsonObject.find("finishDeadLine") != jsonEnd && jsonObject.at("finishDeadLine").is_number_integer()) {2631+ ReadIntFromJson(jsonObject, "ownerUid", INT32_MIN, INT32_MAX, target->ownerUid_);
2593- target->finishDeadLine_ = jsonObject.at("finishDeadLine").get<int64_t>();2632+ ReadIntFromJson(jsonObject, "notificationControlFlags", 0, UINT32_MAX, target->notificationControlFlags_);
2594- }2633+ ReadIntFromJson(jsonObject, "snoozeDelayTime", INT64_MIN, INT64_MAX, target->snoozeDelayTime_);
2595- 
2596- if (jsonObject.find("triggerDeadLine") != jsonEnd && jsonObject.at("triggerDeadLine").is_number_integer()) {
2597- target->triggerDeadLine_ = jsonObject.at("triggerDeadLine").get<int64_t>();
2598- }
2599- 
2600- if (jsonObject.find("ownerUserId") != jsonEnd && jsonObject.at("ownerUserId").is_number_integer()) {
2601- target->ownerUserId_ = jsonObject.at("ownerUserId").get<int32_t>();
2602- }
2603- 
2604- if (jsonObject.find("ownerUid") != jsonEnd && jsonObject.at("ownerUid").is_number_integer()) {
2605- target->ownerUid_ = jsonObject.at("ownerUid").get<int32_t>();
2606- }
2607- 
2608- if (jsonObject.find("notificationControlFlags") != jsonEnd &&
2609- jsonObject.at("notificationControlFlags").is_number_integer()) {
2610- target->notificationControlFlags_ = jsonObject.at("notificationControlFlags").get<uint32_t>();
2611- }
2612- 
2613- if (jsonObject.find("snoozeDelayTime") != jsonEnd &&
2614- jsonObject.at("snoozeDelayTime").is_number_integer()) {
2615- target->snoozeDelayTime_ = jsonObject.at("snoozeDelayTime").get<int64_t>();
2616- }
2617}2634}
2618 2635 
2619void NotificationRequest::ConvertJsonToNum(NotificationRequest *target, const nlohmann::json &jsonObject)2636void NotificationRequest::ConvertJsonToNum(NotificationRequest *target, const nlohmann::json &jsonObject)
@@ -2753,7 +2770,11 @@ void NotificationRequest::ConvertJsonToEnum(NotificationRequest *target, const n
2753 2770 
2754 if (jsonObject.find("slotType") != jsonEnd && jsonObject.at("slotType").is_number_integer()) {2771 if (jsonObject.find("slotType") != jsonEnd && jsonObject.at("slotType").is_number_integer()) {
2755 auto slotTypeValue = jsonObject.at("slotType").get<int32_t>();2772 auto slotTypeValue = jsonObject.at("slotType").get<int32_t>();
2756- target->slotType_ = static_cast<NotificationConstant::SlotType>(slotTypeValue);2773+ if (slotTypeValue < 0 || slotTypeValue >= static_cast<int32_t>(NotificationConstant::SlotType::ILLEGAL_TYPE)) {
2774+ ANS_LOGE("invalid slotType: %{public}d", slotTypeValue);
2775+ } else {
2776+ target->slotType_ = static_cast<NotificationConstant::SlotType>(slotTypeValue);
2777+ }
2757 }2778 }
2758 2779 
2759 if (jsonObject.find("badgeIconStyle") != jsonEnd && jsonObject.at("badgeIconStyle").is_number_integer()) {2780 if (jsonObject.find("badgeIconStyle") != jsonEnd && jsonObject.at("badgeIconStyle").is_number_integer()) {
@@ -2935,6 +2956,10 @@ bool NotificationRequest::ConvertJsonToNotificationActionButton(
2935 2956 
2936 if (jsonObject.find("actionButtons") != jsonEnd) {2957 if (jsonObject.find("actionButtons") != jsonEnd) {
2937 auto buttonArr = jsonObject.at("actionButtons");2958 auto buttonArr = jsonObject.at("actionButtons");
2959+ if (!buttonArr.is_array()) {
2960+ ANS_LOGE("actionButtons is not an array");
2961+ return false;
2962+ }
2938 for (auto &btnObj : buttonArr) {2963 for (auto &btnObj : buttonArr) {
2939 auto pBtn = NotificationActionButton::ConvertNotificationActionButton(targetUid, btnObj);2964 auto pBtn = NotificationActionButton::ConvertNotificationActionButton(targetUid, btnObj);
2940 if (pBtn == nullptr) {2965 if (pBtn == nullptr) {
@@ -3063,19 +3088,40 @@ bool NotificationRequest::ConvertJsonToNotificationTrigger(
3063 }3088 }
3064 3089 
3065 const auto &jsonEnd = jsonObject.cend();3090 const auto &jsonEnd = jsonObject.cend();
3091+ if (jsonObject.find("notificationTrigger") == jsonEnd) {
3092+ return true;
3093+ }
3066 3094 
3067- if (jsonObject.find("notificationTrigger") != jsonEnd) {3095+ auto triggerObj = jsonObject.at("notificationTrigger");
3068- auto triggerObj = jsonObject.at("notificationTrigger");3096+ if (triggerObj.is_null()) {
3069- if (!triggerObj.is_null()) {3097+ return true;
3070- auto *pNotificationTrigger = NotificationJsonConverter::ConvertFromJson<NotificationTrigger>(triggerObj);3098+ }
3071- if (pNotificationTrigger == nullptr) {
3072- ANS_LOGE("null pNotificationTrigger");
3073- return false;
3074- }
3075 3099 
3076- target->notificationTrigger_ = std::shared_ptr<NotificationTrigger>(pNotificationTrigger);3100+ if (triggerObj.contains("triggerType") && triggerObj.at("triggerType").is_number_integer()) {
3101+ auto triggerType = triggerObj.at("triggerType").get<int32_t>();
3102+ if (triggerType < static_cast<int32_t>(NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE) ||
3103+ triggerType > static_cast<int32_t>(NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE)) {
3104+ ANS_LOGE("invalid triggerType: %{public}d", triggerType);
3105+ return false;
3077 }3106 }
3078 }3107 }
3108+ if (triggerObj.contains("triggerConfigPath") &&
3109+ triggerObj.at("triggerConfigPath").is_number_integer()) {
3110+ auto configPath = triggerObj.at("triggerConfigPath").get<int32_t>();
3111+ if (configPath < static_cast<int32_t>(NotificationConstant::ConfigPath::CONFIG_PATH_DEVICE_CONFIG) ||
3112+ configPath > static_cast<int32_t>(NotificationConstant::ConfigPath::CONFIG_PATH_CLOUD_CONFIG)) {
3113+ ANS_LOGE("invalid triggerConfigPath: %{public}d", configPath);
3114+ return false;
3115+ }
3116+ }
3117+ 
3118+ auto *pNotificationTrigger = NotificationJsonConverter::ConvertFromJson<NotificationTrigger>(triggerObj);
3119+ if (pNotificationTrigger == nullptr) {
3120+ ANS_LOGE("null pNotificationTrigger");
3121+ return false;
3122+ }
3123+ 
3124+ target->notificationTrigger_ = std::shared_ptr<NotificationTrigger>(pNotificationTrigger);
3079 3125 
3080 return true;3126 return true;
3081}3127}
@@ -14,6 +14,7 @@
14 */14 */
15 15 
16#include "notification_ringtone_info.h"16#include "notification_ringtone_info.h"
17+#include "ans_const_define.h"
17#include "ans_log_wrapper.h"18#include "ans_log_wrapper.h"
18#include "nlohmann/json.hpp"19#include "nlohmann/json.hpp"
19 20 
@@ -81,6 +82,18 @@ std::string NotificationRingtoneInfo::GetRingtoneUri() const
81 82 
82bool NotificationRingtoneInfo::Marshalling(Parcel &parcel) const83bool NotificationRingtoneInfo::Marshalling(Parcel &parcel) const
83{84{
85+ if (ringtoneTitle_.length() > STR_MAX_SIZE) {
86+ ANS_LOGE("ringtoneTitle_ length exceeds limit");
87+ return false;
88+ }
89+ if (ringtoneFileName_.length() > STR_MAX_SIZE) {
90+ ANS_LOGE("ringtoneFileName_ length exceeds limit");
91+ return false;
92+ }
93+ if (ringtoneUri_.length() > STR_MAX_SIZE) {
94+ ANS_LOGE("ringtoneUri_ length exceeds limit");
95+ return false;
96+ }
84 if (!parcel.WriteInt32(static_cast<int32_t>(ringtoneType_))) {97 if (!parcel.WriteInt32(static_cast<int32_t>(ringtoneType_))) {
85 ANS_LOGE("Failed to write ringtone type");98 ANS_LOGE("Failed to write ringtone type");
86 return false;99 return false;
@@ -116,10 +129,38 @@ NotificationRingtoneInfo *NotificationRingtoneInfo::Unmarshalling(Parcel &parcel
116 129 
117bool NotificationRingtoneInfo::ReadFromParcel(Parcel &parcel)130bool NotificationRingtoneInfo::ReadFromParcel(Parcel &parcel)
118{131{
119- ringtoneType_ = static_cast<NotificationConstant::RingtoneType>(parcel.ReadInt32());132+ int32_t ringtoneType = 0;
120- ringtoneTitle_ = parcel.ReadString();133+ if (!parcel.ReadInt32(ringtoneType)) {
121- ringtoneFileName_ = parcel.ReadString();134+ ANS_LOGE("ReadInt32 failed");
122- ringtoneUri_ = parcel.ReadString();135+ return false;
136+ }
137+ if (ringtoneType < static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_SYSTEM) ||
138+ ringtoneType >= static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_BUTT)) {
139+ ANS_LOGE("Invalid ringtone type: %{public}d", ringtoneType);
140+ return false;
141+ }
142+ ringtoneType_ = static_cast<NotificationConstant::RingtoneType>(ringtoneType);
143+ 
144+ std::string ringtoneTitle;
145+ if (!parcel.ReadString(ringtoneTitle)) {
146+ ANS_LOGE("ReadString failed");
147+ return false;
148+ }
149+ ringtoneTitle_ = ringtoneTitle;
150+ 
151+ std::string ringtoneFileName;
152+ if (!parcel.ReadString(ringtoneFileName)) {
153+ ANS_LOGE("ReadString failed");
154+ return false;
155+ }
156+ ringtoneFileName_ = ringtoneFileName;
157+ 
158+ std::string ringtoneUri;
159+ if (!parcel.ReadString(ringtoneUri)) {
160+ ANS_LOGE("ReadString failed");
161+ return false;
162+ }
163+ ringtoneUri_ = ringtoneUri;
123 return true;164 return true;
124}165}
125 166 
@@ -145,8 +186,13 @@ void NotificationRingtoneInfo::FromJson(const std::string &jsonObj)
145 return;186 return;
146 }187 }
147 if (jsonObject.contains(RINGTONE_INFO_RINGTONE_TYPE) && jsonObject[RINGTONE_INFO_RINGTONE_TYPE].is_number()) {188 if (jsonObject.contains(RINGTONE_INFO_RINGTONE_TYPE) && jsonObject[RINGTONE_INFO_RINGTONE_TYPE].is_number()) {
148- ringtoneType_ =189+ int32_t ringtoneType = jsonObject.at(RINGTONE_INFO_RINGTONE_TYPE).get<int32_t>();
149- static_cast<NotificationConstant::RingtoneType>(jsonObject.at(RINGTONE_INFO_RINGTONE_TYPE).get<int32_t>());190+ if (ringtoneType < static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_SYSTEM) ||
191+ ringtoneType >= static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_BUTT)) {
192+ ANS_LOGE("Invalid ringtone type: %{public}d", ringtoneType);
193+ } else {
194+ ringtoneType_ = static_cast<NotificationConstant::RingtoneType>(ringtoneType);
195+ }
150 }196 }
151 if (jsonObject.contains(RINGTONE_INFO_RINGTONE_TITLE) && jsonObject[RINGTONE_INFO_RINGTONE_TITLE].is_string()) {197 if (jsonObject.contains(RINGTONE_INFO_RINGTONE_TITLE) && jsonObject[RINGTONE_INFO_RINGTONE_TITLE].is_string()) {
152 ringtoneTitle_ = jsonObject.at(RINGTONE_INFO_RINGTONE_TITLE).get<std::string>();198 ringtoneTitle_ = jsonObject.at(RINGTONE_INFO_RINGTONE_TITLE).get<std::string>();
@@ -146,8 +146,19 @@ bool NotificationStatistics::ReadFromParcel(Parcel &parcel)
146 delete pBundle;146 delete pBundle;
147 pBundle = nullptr;147 pBundle = nullptr;
148 148 
149- lastTime_ = parcel.ReadInt64();149+ int64_t lastTime = 0;
150- recentCount_ = parcel.ReadInt32();150+ if (!parcel.ReadInt64(lastTime)) {
151+ ANS_LOGE("ReadInt64 failed");
152+ return false;
153+ }
154+ lastTime_ = lastTime;
155+ 
156+ int32_t recentCount = 0;
157+ if (!parcel.ReadInt32(recentCount)) {
158+ ANS_LOGE("ReadInt32 failed");
159+ return false;
160+ }
161+ recentCount_ = recentCount;
151 162 
152 return true;163 return true;
153}164}
@@ -23,10 +23,10 @@
23#include "refbase.h"23#include "refbase.h"
24#include "voice_content_option.h"24#include "voice_content_option.h"
25#include "picture_option.h"25#include "picture_option.h"
26+#include "ans_const_define.h"
26 27 
27namespace OHOS {28namespace OHOS {
28namespace Notification {29namespace Notification {
29-constexpr uint32_t MAX_SLOT_SIZE = 1000;
30NotificationSubscribeInfo::NotificationSubscribeInfo()30NotificationSubscribeInfo::NotificationSubscribeInfo()
31{}31{}
32 32 
@@ -226,7 +226,11 @@ uint32_t NotificationSubscribeInfo::GetSubscribedFlags() const
226 226 
227bool NotificationSubscribeInfo::ReadVoiceContentOptionFromParcel(Parcel &parcel)227bool NotificationSubscribeInfo::ReadVoiceContentOptionFromParcel(Parcel &parcel)
228{228{
229- bool hasVoiceContentOption = parcel.ReadBool();229+ bool hasVoiceContentOption = false;
230+ if (!parcel.ReadBool(hasVoiceContentOption)) {
231+ ANS_LOGE("ReadBool failed");
232+ return false;
233+ }
230 if (hasVoiceContentOption) {234 if (hasVoiceContentOption) {
231 voiceContentOption_ = VoiceContentOption::Unmarshalling(parcel);235 voiceContentOption_ = VoiceContentOption::Unmarshalling(parcel);
232 if (voiceContentOption_ == nullptr) {236 if (voiceContentOption_ == nullptr) {
@@ -239,7 +243,11 @@ bool NotificationSubscribeInfo::ReadVoiceContentOptionFromParcel(Parcel &parcel)
239 243 
240bool NotificationSubscribeInfo::ReadPictureOptionFromParcel(Parcel &parcel)244bool NotificationSubscribeInfo::ReadPictureOptionFromParcel(Parcel &parcel)
241{245{
242- bool hasPictureOption = parcel.ReadBool();246+ bool hasPictureOption = false;
247+ if (!parcel.ReadBool(hasPictureOption)) {
248+ ANS_LOGE("ReadBool failed");
249+ return false;
250+ }
243 if (hasPictureOption) {251 if (hasPictureOption) {
244 pictureOption_ = PictureOption::Unmarshalling(parcel);252 pictureOption_ = PictureOption::Unmarshalling(parcel);
245 if (pictureOption_ == nullptr) {253 if (pictureOption_ == nullptr) {
@@ -250,20 +258,8 @@ bool NotificationSubscribeInfo::ReadPictureOptionFromParcel(Parcel &parcel)
250 return true;258 return true;
251}259}
252 260 
253-bool NotificationSubscribeInfo::ReadFromParcel(Parcel &parcel)261+bool NotificationSubscribeInfo::ReadSlotTypesFromParcel(Parcel &parcel)
254{262{
255- if (!parcel.ReadStringVector(&appNames_)) {
256- ANS_LOGE("Can't read appNames_");
257- return false;
258- }
259- if (!parcel.ReadString(deviceType_)) {
260- ANS_LOGE("Can't read deviceType_");
261- return false;
262- }
263- if (!parcel.ReadInt32(userId_)) {
264- ANS_LOGE("Can't read userId_");
265- return false;
266- }
267 uint32_t size = 0;263 uint32_t size = 0;
268 if (!parcel.ReadUint32(size)) {264 if (!parcel.ReadUint32(size)) {
269 ANS_LOGE("Can't read size");265 ANS_LOGE("Can't read size");
@@ -279,8 +275,37 @@ bool NotificationSubscribeInfo::ReadFromParcel(Parcel &parcel)
279 ANS_LOGE("Can't read slotType");275 ANS_LOGE("Can't read slotType");
280 return false;276 return false;
281 }277 }
278+ if (slotType < static_cast<int32_t>(NotificationConstant::SlotType::SOCIAL_COMMUNICATION) ||
279+ slotType >= static_cast<int32_t>(NotificationConstant::SlotType::ILLEGAL_TYPE)) {
280+ ANS_LOGE("Invalid slot type: %{public}d", slotType);
281+ return false;
282+ }
282 slotTypes_.emplace_back(static_cast<NotificationConstant::SlotType>(slotType));283 slotTypes_.emplace_back(static_cast<NotificationConstant::SlotType>(slotType));
283 }284 }
285+ return true;
286+}
287+ 
288+bool NotificationSubscribeInfo::ReadFromParcel(Parcel &parcel)
289+{
290+ if (!parcel.ReadStringVector(&appNames_)) {
291+ ANS_LOGE("Can't read appNames_");
292+ return false;
293+ }
294+ if (appNames_.size() > MAX_BUNDLE_LIST_SIZE) {
295+ ANS_LOGE("appNames_ size exceeds limit: %{public}zu", appNames_.size());
296+ return false;
297+ }
298+ if (!parcel.ReadString(deviceType_)) {
299+ ANS_LOGE("Can't read deviceType_");
300+ return false;
301+ }
302+ if (!parcel.ReadInt32(userId_)) {
303+ ANS_LOGE("Can't read userId_");
304+ return false;
305+ }
306+ if (!ReadSlotTypesFromParcel(parcel)) {
307+ return false;
308+ }
284 if (!parcel.ReadUint32(filterType_)) {309 if (!parcel.ReadUint32(filterType_)) {
285 ANS_LOGE("Can't read filterType_");310 ANS_LOGE("Can't read filterType_");
286 return false;311 return false;
@@ -359,6 +384,10 @@ int32_t NotificationSubscribeInfo::GetSubscriberUid() const
359 384 
360void NotificationSubscribeInfo::SetSubscriberBundleName(const std::string &bundleName)385void NotificationSubscribeInfo::SetSubscriberBundleName(const std::string &bundleName)
361{386{
387+ if (bundleName.empty() || bundleName.length() > STR_MAX_SIZE) {
388+ ANS_LOGE("invalid bundleName");
389+ return;
390+ }
362 subscriberBundleName_ = bundleName;391 subscriberBundleName_ = bundleName;
363}392}
364 393 
@@ -167,12 +167,22 @@ NotificationTrigger *NotificationTrigger::FromJson(const nlohmann::json &jsonObj
167 167 
168 if (jsonObject.find(TRIGGER_TYPE) != jsonEnd && jsonObject.at(TRIGGER_TYPE).is_number_integer()) {168 if (jsonObject.find(TRIGGER_TYPE) != jsonEnd && jsonObject.at(TRIGGER_TYPE).is_number_integer()) {
169 auto triggerType = jsonObject.at(TRIGGER_TYPE).get<int32_t>();169 auto triggerType = jsonObject.at(TRIGGER_TYPE).get<int32_t>();
170- pNotificationTrigger->type_ = static_cast<NotificationConstant::TriggerType>(triggerType);170+ if (triggerType < static_cast<int32_t>(NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE) ||
171+ triggerType > static_cast<int32_t>(NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE)) {
172+ ANS_LOGE("invalid TriggerType: %{public}d", triggerType);
173+ } else {
174+ pNotificationTrigger->type_ = static_cast<NotificationConstant::TriggerType>(triggerType);
175+ }
171 }176 }
172 177 
173 if (jsonObject.find(TRIGGER_CONFIG_PATH) != jsonEnd && jsonObject.at(TRIGGER_CONFIG_PATH).is_number_integer()) {178 if (jsonObject.find(TRIGGER_CONFIG_PATH) != jsonEnd && jsonObject.at(TRIGGER_CONFIG_PATH).is_number_integer()) {
174 auto configPath = jsonObject.at(TRIGGER_CONFIG_PATH).get<int32_t>();179 auto configPath = jsonObject.at(TRIGGER_CONFIG_PATH).get<int32_t>();
175- pNotificationTrigger->configPath_ = static_cast<NotificationConstant::ConfigPath>(configPath);180+ if (configPath < static_cast<int32_t>(NotificationConstant::ConfigPath::CONFIG_PATH_DEVICE_CONFIG) ||
181+ configPath > static_cast<int32_t>(NotificationConstant::ConfigPath::CONFIG_PATH_CLOUD_CONFIG)) {
182+ ANS_LOGE("invalid ConfigPath: %{public}d", configPath);
183+ } else {
184+ pNotificationTrigger->configPath_ = static_cast<NotificationConstant::ConfigPath>(configPath);
185+ }
176 }186 }
177 187 
178 if (!ConvertJsonToNotificationGeofence(pNotificationTrigger, jsonObject)) {188 if (!ConvertJsonToNotificationGeofence(pNotificationTrigger, jsonObject)) {
@@ -18,6 +18,7 @@
18#include <new>18#include <new>
19 19 
20#include "ans_log_wrapper.h"20#include "ans_log_wrapper.h"
21+#include "ans_const_define.h"
21#include "parcel.h"22#include "parcel.h"
22 23 
23namespace OHOS {24namespace OHOS {
@@ -69,6 +70,10 @@ bool PictureOption::ReadFromParcel(Parcel &parcel)
69 ANS_LOGE("Failed to read preparseLiveViewPicList_");70 ANS_LOGE("Failed to read preparseLiveViewPicList_");
70 return false;71 return false;
71 }72 }
73+ if (preparseLiveViewPicList_.size() > MAX_PARCELABLE_VECTOR_NUM) {
74+ ANS_LOGE("size exceeds limit");
75+ return false;
76+ }
72 return true;77 return true;
73}78}
74 79 
@@ -136,25 +136,25 @@ int32_t PushCallBackProxy::OnCheckNotification(
136 136 
137 if (!data.WriteInterfaceToken(PushCallBackProxy::GetDescriptor())) {137 if (!data.WriteInterfaceToken(PushCallBackProxy::GetDescriptor())) {
138 ANS_LOGE("Write interface token failed.");138 ANS_LOGE("Write interface token failed.");
139- return false;139+ return ERR_ANS_INNER_INVALID_PARAM;
guxiang49
guxiang49guxiang497月29日

不要直接使用ERR_ANS_INNER_INVALID_PARAM,而要新增一种PushCheckErrCode,在ConvertPushCheckCodeToErrCode中转换成ERR_ANS_INNER_INVALID_PARAM

likedislike
140 }140 }
141 141 
142 if (!data.WriteString(notificationData)) {142 if (!data.WriteString(notificationData)) {
143 ANS_LOGE("Connect done element error.");143 ANS_LOGE("Connect done element error.");
144- return false;144+ return ERR_ANS_INNER_INVALID_PARAM;
145 }145 }
146 146 
147 auto remote = Remote();147 auto remote = Remote();
148 if (remote == nullptr) {148 if (remote == nullptr) {
149 ANS_LOGE("null remote");149 ANS_LOGE("null remote");
150- return false;150+ return ERR_ANS_INNER_INVALID_PARAM;
151 }151 }
152 152 
153 int error = remote->SendRequest(static_cast<uint32_t>(NotificationInterfaceCode::ON_CHECK_NOTIFICATION),153 int error = remote->SendRequest(static_cast<uint32_t>(NotificationInterfaceCode::ON_CHECK_NOTIFICATION),
154 data, reply, option);154 data, reply, option);
155 if (error != NO_ERROR) {155 if (error != NO_ERROR) {
156 ANS_LOGE("error: %{public}d", error);156 ANS_LOGE("error: %{public}d", error);
157- return false;157+ return ERR_ANS_INNER_INVALID_PARAM;
158 }158 }
159 159 
160 int result = reply.ReadInt32();160 int result = reply.ReadInt32();
@@ -32,6 +32,7 @@ ohos_unittest("ans_test") {
32 "${core_path}/common/src/ans_service_errors.cpp",32 "${core_path}/common/src/ans_service_errors.cpp",
33 "${frameworks_module_ans_path}/test/unittest/ans_dialog_host_client_test.cpp",33 "${frameworks_module_ans_path}/test/unittest/ans_dialog_host_client_test.cpp",
34 "${frameworks_module_ans_path}/test/unittest/ans_log_test.cpp",34 "${frameworks_module_ans_path}/test/unittest/ans_log_test.cpp",
35+ "${frameworks_module_ans_path}/test/unittest/badge_number_callback_data_test.cpp",
35 "${frameworks_module_ans_path}/test/unittest/enabled_notification_callback_data_test.cpp",36 "${frameworks_module_ans_path}/test/unittest/enabled_notification_callback_data_test.cpp",
36 "${frameworks_module_ans_path}/test/unittest/enabled_priority_notification_by_bundle_callback_data_test.cpp",37 "${frameworks_module_ans_path}/test/unittest/enabled_priority_notification_by_bundle_callback_data_test.cpp",
37 "${frameworks_module_ans_path}/test/unittest/enabled_silent_reminder_callback_data_test.cpp",38 "${frameworks_module_ans_path}/test/unittest/enabled_silent_reminder_callback_data_test.cpp",
@@ -0,0 +1,167 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#include <gtest/gtest.h>
17+#include <string>
18+ 
19+#define private public
20+#define protected public
21+#include "badge_number_callback_data.h"
22+#undef private
23+#undef protected
24+#include "parcel.h"
25+#include "string_ex.h"
26+ 
27+using namespace testing::ext;
28+namespace OHOS {
29+namespace Notification {
30+class BadgeNumberCallbackDataTest : public testing::Test {
31+public:
32+ static void SetUpTestCase() {}
33+ static void TearDownTestCase() {}
34+ void SetUp() {}
35+ void TearDown() {}
36+};
37+ 
38+/**
39+ * @tc.name: Marshalling_0100
40+ * @tc.desc: Test Marshalling round-trip success.
41+ * @tc.type: FUNC
42+ */
43+HWTEST_F(BadgeNumberCallbackDataTest, Marshalling_0100, Function | SmallTest | Level1)
44+{
45+ BadgeNumberCallbackData data("com.test.bundle", "appInstanceKey", 100, 5, 1);
46+ Parcel parcel;
47+ EXPECT_TRUE(data.Marshalling(parcel));
48+ parcel.RewindRead(0);
49+ 
50+ auto *result = BadgeNumberCallbackData::Unmarshalling(parcel);
51+ ASSERT_NE(result, nullptr);
52+ EXPECT_EQ(result->GetBundle(), "com.test.bundle");
53+ EXPECT_EQ(result->GetAppInstanceKey(), "appInstanceKey");
54+ EXPECT_EQ(result->GetUid(), 100);
55+ EXPECT_EQ(result->GetBadgeNumber(), 5);
56+ EXPECT_EQ(result->GetInstanceKey(), 1);
57+ delete result;
58+}
59+ 
60+/**
61+ * @tc.name: ReadFromParcel_0100
62+ * @tc.desc: Test ReadFromParcel when ReadString16 fails (empty parcel).
63+ * @tc.type: FUNC
64+ */
65+HWTEST_F(BadgeNumberCallbackDataTest, ReadFromParcel_0100, Function | SmallTest | Level1)
66+{
67+ BadgeNumberCallbackData data;
68+ Parcel parcel;
69+ EXPECT_FALSE(data.ReadFromParcel(parcel));
70+}
71+ 
72+/**
73+ * @tc.name: ReadFromParcel_0200
74+ * @tc.desc: Test ReadFromParcel when ReadString(appInstanceKey) fails.
75+ * @tc.type: FUNC
76+ */
77+HWTEST_F(BadgeNumberCallbackDataTest, ReadFromParcel_0200, Function | SmallTest | Level1)
78+{
79+ BadgeNumberCallbackData data;
80+ Parcel parcel;
81+ parcel.WriteString16(Str8ToStr16("com.test.bundle"));
82+ parcel.RewindRead(0);
83+ EXPECT_FALSE(data.ReadFromParcel(parcel));
84+}
85+ 
86+/**
87+ * @tc.name: ReadFromParcel_0300
88+ * @tc.desc: Test ReadFromParcel when ReadInt32(uid) fails.
89+ * @tc.type: FUNC
90+ */
91+HWTEST_F(BadgeNumberCallbackDataTest, ReadFromParcel_0300, Function | SmallTest | Level1)
92+{
93+ BadgeNumberCallbackData data;
94+ Parcel parcel;
95+ parcel.WriteString16(Str8ToStr16("com.test.bundle"));
96+ parcel.WriteString("appInstanceKey");
97+ parcel.RewindRead(0);
98+ EXPECT_FALSE(data.ReadFromParcel(parcel));
99+}
100+ 
101+/**
102+ * @tc.name: ReadFromParcel_0400
103+ * @tc.desc: Test ReadFromParcel when ReadInt32(badgeNumber) fails.
104+ * @tc.type: FUNC
105+ */
106+HWTEST_F(BadgeNumberCallbackDataTest, ReadFromParcel_0400, Function | SmallTest | Level1)
107+{
108+ BadgeNumberCallbackData data;
109+ Parcel parcel;
110+ parcel.WriteString16(Str8ToStr16("com.test.bundle"));
111+ parcel.WriteString("appInstanceKey");
112+ parcel.WriteInt32(100);
113+ parcel.RewindRead(0);
114+ EXPECT_FALSE(data.ReadFromParcel(parcel));
115+}
116+ 
117+/**
118+ * @tc.name: ReadFromParcel_0500
119+ * @tc.desc: Test ReadFromParcel when ReadInt32(instanceKey) fails.
120+ * @tc.type: FUNC
121+ */
122+HWTEST_F(BadgeNumberCallbackDataTest, ReadFromParcel_0500, Function | SmallTest | Level1)
123+{
124+ BadgeNumberCallbackData data;
125+ Parcel parcel;
126+ parcel.WriteString16(Str8ToStr16("com.test.bundle"));
127+ parcel.WriteString("appInstanceKey");
128+ parcel.WriteInt32(100);
129+ parcel.WriteInt32(5);
130+ parcel.RewindRead(0);
131+ EXPECT_FALSE(data.ReadFromParcel(parcel));
132+}
133+ 
134+/**
135+ * @tc.name: GetSet_0100
136+ * @tc.desc: Test getters and setters.
137+ * @tc.type: FUNC
138+ */
139+HWTEST_F(BadgeNumberCallbackDataTest, GetSet_0100, Function | SmallTest | Level1)
140+{
141+ BadgeNumberCallbackData data;
142+ data.SetBundle("com.test");
143+ data.SetUid(200);
144+ data.SetBadgeNumber(10);
145+ data.SetInstanceKey(3);
146+ data.SetAppInstanceKey("key");
147+ EXPECT_EQ(data.GetBundle(), "com.test");
148+ EXPECT_EQ(data.GetUid(), 200);
149+ EXPECT_EQ(data.GetBadgeNumber(), 10);
150+ EXPECT_EQ(data.GetInstanceKey(), 3);
151+ EXPECT_EQ(data.GetAppInstanceKey(), "key");
152+}
153+ 
154+/**
155+ * @tc.name: Dump_0100
156+ * @tc.desc: Test Dump output.
157+ * @tc.type: FUNC
158+ */
159+HWTEST_F(BadgeNumberCallbackDataTest, Dump_0100, Function | SmallTest | Level1)
160+{
161+ BadgeNumberCallbackData data("com.test", "key1", 100, 5, 1);
162+ std::string dump = data.Dump();
163+ EXPECT_NE(dump.find("com.test"), std::string::npos);
164+ EXPECT_NE(dump.find("100"), std::string::npos);
165+}
166+}
167+}
@@ -74,8 +74,9 @@ HWTEST_F(MessageUserTest, FromJson_00003, Function | SmallTest | Level1)
74 {"version", 2}, {"tokenId", 685266937},74 {"version", 2}, {"tokenId", 685266937},
75 {"tokenAttr", 0},75 {"tokenAttr", 0},
76 {"dcaps", {"AT_CAP", "ST_CAP"}}};76 {"dcaps", {"AT_CAP", "ST_CAP"}}};
77- messageUser.FromJson(jsonObject);77+ auto result = messageUser.FromJson(jsonObject);
78 EXPECT_EQ(jsonObject.is_object(), true);78 EXPECT_EQ(jsonObject.is_object(), true);
79+ EXPECT_NE(result, nullptr);
79}80}
80 81 
81/**82/**
@@ -160,5 +161,97 @@ HWTEST_F(MessageUserTest, Marshalling_00001, Function | SmallTest | Level1)
160 auto res = messageUser.Marshalling(parcel);161 auto res = messageUser.Marshalling(parcel);
161 EXPECT_NE(res, false);162 EXPECT_NE(res, false);
162}163}
164+ 
165+/**
166+ * @tc.name: ReadFromParcel_00003
167+ * @tc.desc: Test ReadFromParcel when only key is written (name read fails).
168+ * @tc.type: FUNC
169+ * @tc.require: issue
170+ */
171+HWTEST_F(MessageUserTest, ReadFromParcel_00003, Function | SmallTest | Level1)
172+{
173+ MessageUser messageUser;
174+ Parcel parcel;
175+ 
176+ parcel.WriteString("key");
177+ EXPECT_EQ(messageUser.ReadFromParcel(parcel), false);
178+}
179+ 
180+/**
181+ * @tc.name: ReadFromParcel_00004
182+ * @tc.desc: Test ReadFromParcel when key and name are written (isMachine read fails).
183+ * @tc.type: FUNC
184+ * @tc.require: issue
185+ */
186+HWTEST_F(MessageUserTest, ReadFromParcel_00004, Function | SmallTest | Level1)
187+{
188+ MessageUser messageUser;
189+ Parcel parcel;
190+ 
191+ parcel.WriteString("key");
192+ parcel.WriteString("name");
193+ EXPECT_EQ(messageUser.ReadFromParcel(parcel), false);
194+}
195+ 
196+/**
197+ * @tc.name: ReadFromParcel_00005
198+ * @tc.desc: Test ReadFromParcel when key, name and isMachine are written (isUserImportant read fails).
199+ * @tc.type: FUNC
200+ * @tc.require: issue
201+ */
202+HWTEST_F(MessageUserTest, ReadFromParcel_00005, Function | SmallTest | Level1)
203+{
204+ MessageUser messageUser;
205+ Parcel parcel;
206+ 
207+ parcel.WriteString("key");
208+ parcel.WriteString("name");
209+ parcel.WriteBool(true);
210+ EXPECT_EQ(messageUser.ReadFromParcel(parcel), false);
211+}
212+ 
213+/**
214+ * @tc.name: ReadOptionalFromParcel_00001
215+ * @tc.desc: Test ReadOptionalFromParcel when ReadInt32 fails.
216+ * @tc.type: FUNC
217+ * @tc.require: issue
218+ */
219+HWTEST_F(MessageUserTest, ReadOptionalFromParcel_00001, Function | SmallTest | Level1)
220+{
221+ MessageUser messageUser;
222+ Parcel parcel;
223+ 
224+ EXPECT_EQ(messageUser.ReadOptionalFromParcel(parcel), false);
225+}
226+ 
227+/**
228+ * @tc.name: ReadOptionalFromParcel_00002
229+ * @tc.desc: Test ReadOptionalFromParcel when uri string read fails.
230+ * @tc.type: FUNC
231+ * @tc.require: issue
232+ */
233+HWTEST_F(MessageUserTest, ReadOptionalFromParcel_00002, Function | SmallTest | Level1)
234+{
235+ MessageUser messageUser;
236+ Parcel parcel;
237+ 
238+ parcel.WriteInt32(MessageUser::VALUE_OBJECT);
239+ EXPECT_EQ(messageUser.ReadOptionalFromParcel(parcel), false);
240+}
241+ 
242+/**
243+ * @tc.name: ReadOptionalFromParcel_00003
244+ * @tc.desc: Test ReadOptionalFromParcel when pixelMap valid bool read fails.
245+ * @tc.type: FUNC
246+ * @tc.require: issue
247+ */
248+HWTEST_F(MessageUserTest, ReadOptionalFromParcel_00003, Function | SmallTest | Level1)
249+{
250+ MessageUser messageUser;
251+ Parcel parcel;
252+ 
253+ parcel.WriteInt32(MessageUser::VALUE_NULL);
254+ EXPECT_EQ(messageUser.ReadOptionalFromParcel(parcel), false);
255+}
163}256}
164}257}
@@ -293,8 +293,9 @@ HWTEST_F(NotificationContentTest, FromJson_00003, Function | SmallTest | Level1)
293 {"version", 2}, {"tokenId", 685266937},293 {"version", 2}, {"tokenId", 685266937},
294 {"tokenAttr", 0},294 {"tokenAttr", 0},
295 {"dcaps", {"AT_CAP", "ST_CAP"}}};295 {"dcaps", {"AT_CAP", "ST_CAP"}}};
296- notificationContent.FromJson(jsonObject);296+ auto result = notificationContent.FromJson(jsonObject);
297 EXPECT_EQ(jsonObject.is_object(), true);297 EXPECT_EQ(jsonObject.is_object(), true);
298+ EXPECT_EQ(result, nullptr);
298}299}
299 300 
300/**301/**
@@ -360,22 +361,22 @@ HWTEST_F(NotificationContentTest, NotificationContentMarshalling_0200, Level1)
360{361{
361 std::shared_ptr<NotificationNormalContent> normalContent = nullptr;362 std::shared_ptr<NotificationNormalContent> normalContent = nullptr;
362 auto sptr1 = std::make_shared<NotificationContent>(normalContent);363 auto sptr1 = std::make_shared<NotificationContent>(normalContent);
363- EXPECT_NE(sptr1, nullptr);364+ EXPECT_EQ(sptr1->GetNotificationContent(), nullptr);
364 std::shared_ptr<NotificationLongTextContent> longTextContent = nullptr;365 std::shared_ptr<NotificationLongTextContent> longTextContent = nullptr;
365 auto sptr2 = std::make_shared<NotificationContent>(longTextContent);366 auto sptr2 = std::make_shared<NotificationContent>(longTextContent);
366- EXPECT_NE(sptr2, nullptr);367+ EXPECT_EQ(sptr2->GetNotificationContent(), nullptr);
367 std::shared_ptr<NotificationPictureContent> pictureContent = nullptr;368 std::shared_ptr<NotificationPictureContent> pictureContent = nullptr;
368 auto sptr3 = std::make_shared<NotificationContent>(pictureContent);369 auto sptr3 = std::make_shared<NotificationContent>(pictureContent);
369- EXPECT_NE(sptr3, nullptr);370+ EXPECT_EQ(sptr3->GetNotificationContent(), nullptr);
370 std::shared_ptr<NotificationConversationalContent> conversationContent = nullptr;371 std::shared_ptr<NotificationConversationalContent> conversationContent = nullptr;
371 auto sptr4 = std::make_shared<NotificationContent>(conversationContent);372 auto sptr4 = std::make_shared<NotificationContent>(conversationContent);
372- EXPECT_NE(sptr4, nullptr);373+ EXPECT_EQ(sptr4->GetNotificationContent(), nullptr);
373 std::shared_ptr<NotificationMultiLineContent> multiLineContent = nullptr;374 std::shared_ptr<NotificationMultiLineContent> multiLineContent = nullptr;
374 auto sptr5 = std::make_shared<NotificationContent>(multiLineContent);375 auto sptr5 = std::make_shared<NotificationContent>(multiLineContent);
375- EXPECT_NE(sptr5, nullptr);376+ EXPECT_EQ(sptr5->GetNotificationContent(), nullptr);
376 std::shared_ptr<NotificationMediaContent> mediaContent = nullptr;377 std::shared_ptr<NotificationMediaContent> mediaContent = nullptr;
377 auto sptr6 = std::make_shared<NotificationContent>(mediaContent);378 auto sptr6 = std::make_shared<NotificationContent>(mediaContent);
378- EXPECT_NE(sptr6, nullptr);379+ EXPECT_EQ(sptr6->GetNotificationContent(), nullptr);
379}380}
380 381 
381/**382/**
@@ -413,7 +414,9 @@ HWTEST_F(NotificationContentTest, NotificationBasicContentReadFromJson_00001, Le
413 {"title", "test"},414 {"title", "test"},
414 {"additionalText", "test"}};415 {"additionalText", "test"}};
415 notificationBasicContent->ReadFromJson(jsonObject);416 notificationBasicContent->ReadFromJson(jsonObject);
416- EXPECT_NE(notificationBasicContent, nullptr);417+ EXPECT_EQ(notificationBasicContent->GetText(), "test");
418+ EXPECT_EQ(notificationBasicContent->GetTitle(), "test");
419+ EXPECT_EQ(notificationBasicContent->GetAdditionalText(), "test");
417}420}
418 421 
419/**422/**
@@ -644,5 +647,21 @@ HWTEST_F(NotificationContentTest, ReadFromJson_StructuredText_00200, Level1)
644 content.ReadFromJson(jsonObject);647 content.ReadFromJson(jsonObject);
645 EXPECT_EQ(content.GetText(), "test");648 EXPECT_EQ(content.GetText(), "test");
646}649}
650+ 
651+/**
652+ * @tc.name: ReadFromParcel_LiveViewNull_00100
653+ * @tc.desc: Test ReadFromParcel returns false when contentType is LIVE_VIEW but content parcelable is null.
654+ * @tc.type: FUNC
655+ * @tc.require: issue
656+ */
657+HWTEST_F(NotificationContentTest, ReadFromParcel_LiveViewNull_00100, Function | SmallTest | Level1)
658+{
659+ Parcel parcel;
660+ parcel.WriteInt32(static_cast<int32_t>(NotificationContent::Type::LIVE_VIEW));
661+ parcel.WriteBool(true);
662+ parcel.WriteInt32(-1);
663+ NotificationContent content;
664+ EXPECT_EQ(content.ReadFromParcel(parcel), false);
665+}
647}666}
648}667}
@@ -17,6 +17,10 @@
17 17 
18#include "notification_disable.h"18#include "notification_disable.h"
19 19 
20+namespace {
21+constexpr int32_t MAX_NOTIFICATION_DISABLE_NUM = 1000;
22+}
23+ 
20using namespace testing::ext;24using namespace testing::ext;
21namespace OHOS {25namespace OHOS {
22namespace Notification {26namespace Notification {
@@ -79,32 +83,68 @@ HWTEST_F(NotificationDisableTest, Marshalling_0100, Function | SmallTest | Level
79 83 
80/**84/**
81 * @tc.name: ReadFromParcel_010085 * @tc.name: ReadFromParcel_0100
82- * @tc.desc: Test ReadFromParcel.86+ * @tc.desc: Test ReadFromParcel with empty parcel (ReadBool fails).
83 * @tc.type: FUNC87 * @tc.type: FUNC
84 */88 */
85HWTEST_F(NotificationDisableTest, ReadFromParcel_0100, Function | SmallTest | Level1)89HWTEST_F(NotificationDisableTest, ReadFromParcel_0100, Function | SmallTest | Level1)
86{90{
87 Parcel parcel;91 Parcel parcel;
88 auto rrc = std::make_shared<NotificationDisable>();92 auto rrc = std::make_shared<NotificationDisable>();
89- EXPECT_TRUE(rrc->ReadFromParcel(parcel));93+ EXPECT_FALSE(rrc->ReadFromParcel(parcel));
94+}
95+ 
96+/**
97+ * @tc.name: ReadFromParcel_0200
98+ * @tc.desc: Test ReadFromParcel when ReadUint32 fails (only bool written).
99+ * @tc.type: FUNC
100+ */
101+HWTEST_F(NotificationDisableTest, ReadFromParcel_0200, Function | SmallTest | Level1)
102+{
103+ Parcel parcel;
104+ parcel.WriteBool(false);
105+ auto rrc = std::make_shared<NotificationDisable>();
106+ EXPECT_FALSE(rrc->ReadFromParcel(parcel));
107+}
108+ 
109+/**
110+ * @tc.name: ReadFromParcel_0300
111+ * @tc.desc: Test ReadFromParcel when ReadString fails in bundle loop.
112+ * @tc.type: FUNC
113+ */
114+HWTEST_F(NotificationDisableTest, ReadFromParcel_0300, Function | SmallTest | Level1)
115+{
116+ Parcel parcel;
117+ parcel.WriteBool(false);
118+ parcel.WriteUint32(1);
119+ auto rrc = std::make_shared<NotificationDisable>();
120+ EXPECT_FALSE(rrc->ReadFromParcel(parcel));
121+}
122+ 
123+/**
124+ * @tc.name: ReadFromParcel_0400
125+ * @tc.desc: Test ReadFromParcel when ReadInt32(userId) fails.
126+ * @tc.type: FUNC
127+ */
128+HWTEST_F(NotificationDisableTest, ReadFromParcel_0400, Function | SmallTest | Level1)
129+{
130+ Parcel parcel;
131+ parcel.WriteBool(false);
132+ parcel.WriteUint32(0);
133+ auto rrc = std::make_shared<NotificationDisable>();
134+ EXPECT_FALSE(rrc->ReadFromParcel(parcel));
90}135}
91 136 
92/**137/**
93 * @tc.name: Unmarshalling_0100138 * @tc.name: Unmarshalling_0100
94- * @tc.desc: Test Unmarshalling.139+ * @tc.desc: Test Unmarshalling with empty parcel returns nullptr.
95 * @tc.type: FUNC140 * @tc.type: FUNC
96 */141 */
97HWTEST_F(NotificationDisableTest, Unmarshalling_0100, Function | SmallTest | Level1)142HWTEST_F(NotificationDisableTest, Unmarshalling_0100, Function | SmallTest | Level1)
98{143{
99- bool unmarshalling = true;
100 Parcel parcel;144 Parcel parcel;
101 auto rrc = std::make_shared<NotificationDisable>();145 auto rrc = std::make_shared<NotificationDisable>();
102- if (nullptr != rrc) {146+ ASSERT_NE(nullptr, rrc);
103- if (nullptr == rrc->Unmarshalling(parcel)) {147+ EXPECT_EQ(nullptr, rrc->Unmarshalling(parcel));
104- unmarshalling = false;
105- }
106- }
107- EXPECT_TRUE(unmarshalling);
108}148}
109 149 
110/**150/**
@@ -192,5 +232,39 @@ HWTEST_F(NotificationDisableTest, FromJson_0400, Function | SmallTest | Level1)
192 notificationDisable.FromJson(jsonObjString);232 notificationDisable.FromJson(jsonObjString);
193 EXPECT_FALSE(notificationDisable.GetDisabled());233 EXPECT_FALSE(notificationDisable.GetDisabled());
194}234}
235+ 
236+/**
237+ * @tc.name: FromJson_0500
238+ * @tc.desc: Test FromJson with bundleList exceeding MAX_NOTIFICATION_DISABLE_NUM.
239+ * @tc.type: FUNC
240+ */
241+HWTEST_F(NotificationDisableTest, FromJson_0500, Function | SmallTest | Level1)
242+{
243+ NotificationDisable notificationDisable;
244+ std::string bundleArray = "[";
245+ for (int32_t i = 0; i <= MAX_NOTIFICATION_DISABLE_NUM; ++i) {
246+ bundleArray += "\"bundle\",";
247+ }
248+ if (!bundleArray.empty()) {
249+ bundleArray.pop_back();
250+ }
251+ bundleArray += "]";
252+ std::string jsonObjString = "{\"disabled\": true, \"bundleList\": " + bundleArray + "}";
253+ notificationDisable.FromJson(jsonObjString);
254+ EXPECT_TRUE(notificationDisable.GetBundleList().empty());
255+}
256+ 
257+/**
258+ * @tc.name: FromJson_0600
259+ * @tc.desc: Test FromJson with userId out of int32 range.
260+ * @tc.type: FUNC
261+ */
262+HWTEST_F(NotificationDisableTest, FromJson_0600, Function | SmallTest | Level1)
263+{
264+ NotificationDisable notificationDisable;
265+ std::string jsonObjString = "{\"userId\": 2147483648}";
266+ notificationDisable.FromJson(jsonObjString);
267+ EXPECT_EQ(notificationDisable.GetUserId(), -1);
268+}
195}269}
196}270}
@@ -15,6 +15,7 @@
15 15 
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17 17 
18+#include "ans_const_define.h"
18#include "ans_log_wrapper.h"19#include "ans_log_wrapper.h"
19 20 
20#define private public21#define private public
@@ -152,7 +153,7 @@ HWTEST_F(NotificationDoNotDisturbProfileTest, Unmarshalling_0100, TestSize.Level
152 unmarshalling = false;153 unmarshalling = false;
153 }154 }
154 }155 }
155- EXPECT_EQ(unmarshalling, true);156+ EXPECT_EQ(unmarshalling, false);
156}157}
157 158 
158/**159/**
@@ -195,5 +196,59 @@ HWTEST_F(NotificationDoNotDisturbProfileTest, FromJson_0100, TestSize.Level1)
195 196 
196 ASSERT_EQ(temp.GetProfileTrustList().size(), 1);197 ASSERT_EQ(temp.GetProfileTrustList().size(), 1);
197}198}
199+ 
200+/**
201+ * @tc.name: ReadFromParcel_0400
202+ * @tc.desc: test ReadFromParcel when only id is written (name read fails).
203+ * @tc.type: FUNC
204+ */
205+HWTEST_F(NotificationDoNotDisturbProfileTest, ReadFromParcel_0400, TestSize.Level1)
206+{
207+ NotificationDoNotDisturbProfile profile;
208+ Parcel parcel;
209+ parcel.WriteInt64(1);
210+ EXPECT_EQ(profile.ReadFromParcel(parcel), false);
211+}
212+ 
213+/**
214+ * @tc.name: ReadFromParcel_0500
215+ * @tc.desc: test ReadFromParcel when id and name are written (size read fails).
216+ * @tc.type: FUNC
217+ */
218+HWTEST_F(NotificationDoNotDisturbProfileTest, ReadFromParcel_0500, TestSize.Level1)
219+{
220+ NotificationDoNotDisturbProfile profile;
221+ Parcel parcel;
222+ parcel.WriteInt64(1);
223+ parcel.WriteString("name");
224+ EXPECT_EQ(profile.ReadFromParcel(parcel), false);
225+}
226+ 
227+/**
228+ * @tc.name: ReadFromParcel_0600
229+ * @tc.desc: test ReadFromParcel when parcel is empty (ReadInt64 of id fails).
230+ * @tc.type: FUNC
231+ */
232+HWTEST_F(NotificationDoNotDisturbProfileTest, ReadFromParcel_0600, TestSize.Level1)
233+{
234+ NotificationDoNotDisturbProfile profile;
235+ Parcel parcel;
236+ EXPECT_EQ(profile.ReadFromParcel(parcel), false);
237+}
238+ 
239+/**
240+ * @tc.name: Marshalling_0200
241+ * @tc.desc: test Marshalling returns false when trust list size exceeds MAX_PARCELABLE_VECTOR_NUM.
242+ * @tc.type: FUNC
243+ */
244+HWTEST_F(NotificationDoNotDisturbProfileTest, Marshalling_0200, TestSize.Level1)
245+{
246+ int32_t id = 1;
247+ std::string name = "name";
248+ std::vector<NotificationBundleOption> trustlist(MAX_PARCELABLE_VECTOR_NUM + 1);
249+ auto rrc = std::make_shared<NotificationDoNotDisturbProfile>(id, name, trustlist);
250+ Parcel parcel;
251+ EXPECT_EQ(rrc->Marshalling(parcel), false);
252+}
198} // namespace Notification253} // namespace Notification
199} // namespace OHOS254} // namespace OHOS
@@ -277,7 +277,8 @@ HWTEST_F(NotificationHelperTest, CancelAsBundle_00002, Function | SmallTest | Le
277 bundleOption.SetUid(20);277 bundleOption.SetUid(20);
278 NotificationHelper notificationHelper;278 NotificationHelper notificationHelper;
279 ErrCode ret = notificationHelper.CancelAsBundle(bundleOption, notificationId);279 ErrCode ret = notificationHelper.CancelAsBundle(bundleOption, notificationId);
280- EXPECT_EQ(ret, (int)ERR_ANS_PERMISSION_DENIED);280+ // uid 20 is a system uid which maps to an invalid userId, so the service rejects it.
281+ EXPECT_EQ(ret, (int)ERR_ANS_GET_ACTIVE_USER_FAILED);
281}282}
282 283 
283/**284/**
@@ -1116,7 +1117,8 @@ HWTEST_F(NotificationHelperTest, GetNotificationParameters_100, Function | Small
1116 sptr<NotificationParameters> parameters = nullptr;1117 sptr<NotificationParameters> parameters = nullptr;
1117 NotificationHelper notificationHelper;1118 NotificationHelper notificationHelper;
1118 ErrCode ret = notificationHelper.GetNotificationParameters(notificationId, label, parameters);1119 ErrCode ret = notificationHelper.GetNotificationParameters(notificationId, label, parameters);
1119- EXPECT_EQ(ret, (int)ERR_ANS_NOTIFICATION_NOT_EXISTS);1120+ // The calling (native test process) uid maps to an invalid userId, so the service rejects it.
1121+ EXPECT_EQ(ret, (int)ERR_ANS_GET_ACTIVE_USER_FAILED);
1120}1122}
1121 1123 
1122/**1124/**
@@ -16,7 +16,11 @@
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17#include <string>17#include <string>
18#include <unistd.h>18#include <unistd.h>
19+#define private public
20+#define protected public
19#include "notification_icon_button.h"21#include "notification_icon_button.h"
22+#undef private
23+#undef protected
20#include "ans_image_util.h"24#include "ans_image_util.h"
21 25 
22using namespace testing::ext;26using namespace testing::ext;
@@ -410,5 +414,38 @@ HWTEST_F(NotificationIconButtonTest, ClearButtonIconsResource_00002, Function |
410 EXPECT_EQ(button->GetIconResource(), nullptr);414 EXPECT_EQ(button->GetIconResource(), nullptr);
411 EXPECT_EQ(button->GetIconImage(), nullptr);415 EXPECT_EQ(button->GetIconImage(), nullptr);
412}416}
417+ 
418+/**
419+ * @tc.name: ReadFromParcel_ReadBoolFail_001
420+ * @tc.desc: Test ReadFromParcel when iconImage valid bool read fails.
421+ * @tc.type: FUNC
422+ * @tc.require: issue
423+ */
424+HWTEST_F(NotificationIconButtonTest, ReadFromParcel_ReadBoolFail_001, Function | SmallTest | Level1)
425+{
426+ Parcel parcel;
427+ parcel.WriteString("text");
428+ parcel.WriteString("name");
429+ parcel.WriteBool(true);
430+ NotificationIconButton button;
431+ EXPECT_EQ(button.ReadFromParcel(parcel), false);
432+}
433+ 
434+/**
435+ * @tc.name: ReadFromParcel_ReadBoolFail_002
436+ * @tc.desc: Test ReadFromParcel when iconResource valid bool read fails.
437+ * @tc.type: FUNC
438+ * @tc.require: issue
439+ */
440+HWTEST_F(NotificationIconButtonTest, ReadFromParcel_ReadBoolFail_002, Function | SmallTest | Level1)
441+{
442+ Parcel parcel;
443+ parcel.WriteString("text");
444+ parcel.WriteString("name");
445+ parcel.WriteBool(true);
446+ parcel.WriteBool(false);
447+ NotificationIconButton button;
448+ EXPECT_EQ(button.ReadFromParcel(parcel), false);
449+}
413}450}
414}451}
@@ -16,6 +16,8 @@
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17#include <memory>17#include <memory>
18 18 
19+#include "ans_const_define.h"
20+ 
19#define private public21#define private public
20#define protected public22#define protected public
21#include "notification_live_view_content.h"23#include "notification_live_view_content.h"
@@ -441,5 +443,125 @@ HWTEST_F(NotificationLiveViewContentTest, ReadFromParcel_InvalidStatus_00002, Fu
441 parcel.WriteInt32(-1);443 parcel.WriteInt32(-1);
442 EXPECT_EQ(rrc->ReadFromParcel(parcel), false);444 EXPECT_EQ(rrc->ReadFromParcel(parcel), false);
443}445}
446+ 
447+/**
448+ * @tc.name: ReadTrailingFieldsFromParcel_ReadUint32Fail_001
449+ * @tc.desc: Test ReadTrailingFieldsFromParcel returns false when ReadUint32(removeState) fails.
450+ * @tc.type: FUNC
451+ * @tc.require: issue
452+ */
453+HWTEST_F(NotificationLiveViewContentTest, ReadTrailingFieldsFromParcel_ReadUint32Fail_001,
454+ Function | SmallTest | Level1)
455+{
456+ auto rrc = std::make_shared<NotificationLiveViewContent>();
457+ Parcel parcel;
458+ EXPECT_EQ(rrc->ReadTrailingFieldsFromParcel(parcel), false);
459+}
460+ 
461+/**
462+ * @tc.name: ReadTrailingFieldsFromParcel_InvalidRemoveState_001
463+ * @tc.desc: Test ReadTrailingFieldsFromParcel returns false when removeState exceeds LIVE_VIEW_NO_REMOVE.
464+ * @tc.type: FUNC
465+ * @tc.require: issue
466+ */
467+HWTEST_F(NotificationLiveViewContentTest, ReadTrailingFieldsFromParcel_InvalidRemoveState_001,
468+ Function | SmallTest | Level1)
469+{
470+ auto rrc = std::make_shared<NotificationLiveViewContent>();
471+ Parcel parcel;
472+ parcel.WriteUint32(static_cast<uint32_t>(NotificationLiveViewContent::LiveViewRemoveStatus::LIVE_VIEW_NO_REMOVE) +
473+ 1);
474+ parcel.RewindRead(0);
475+ EXPECT_EQ(rrc->ReadTrailingFieldsFromParcel(parcel), false);
476+}
477+ 
478+/**
479+ * @tc.name: ReadTrailingFieldsFromParcel_ReadInt32Fail_001
480+ * @tc.desc: Test ReadTrailingFieldsFromParcel returns false when ReadInt32(createPid_) fails.
481+ * @tc.type: FUNC
482+ * @tc.require: issue
483+ */
484+HWTEST_F(NotificationLiveViewContentTest, ReadTrailingFieldsFromParcel_ReadInt32Fail_001, Function | SmallTest | Level1)
485+{
486+ auto rrc = std::make_shared<NotificationLiveViewContent>();
487+ Parcel parcel;
488+ parcel.WriteUint32(static_cast<uint32_t>(NotificationLiveViewContent::LiveViewRemoveStatus::LIVE_VIEW_NO_REMOVE));
489+ parcel.RewindRead(0);
490+ EXPECT_EQ(rrc->ReadTrailingFieldsFromParcel(parcel), false);
491+}
492+ 
493+/**
494+ * @tc.name: ReadPictureMapFromParcel_EmptyParcel_001
495+ * @tc.desc: Test ReadPictureMapFromParcel returns true when parcel is empty (len reads 0).
496+ * @tc.type: FUNC
497+ * @tc.require: issue
498+ */
499+HWTEST_F(NotificationLiveViewContentTest, ReadPictureMapFromParcel_EmptyParcel_001,
500+ Function | SmallTest | Level1)
501+{
502+ auto rrc = std::make_shared<NotificationLiveViewContent>();
503+ Parcel parcel;
504+ EXPECT_EQ(rrc->ReadPictureMapFromParcel(parcel), true);
505+ EXPECT_TRUE(rrc->pictureMap_.empty());
506+}
507+ 
508+/**
509+ * @tc.name: ReadPictureMapFromParcel_TooLarge_001
510+ * @tc.desc: Test ReadPictureMapFromParcel returns false when len exceeds MAX_PARCELABLE_VECTOR_NUM.
511+ * @tc.type: FUNC
512+ * @tc.require: issue
513+ */
514+HWTEST_F(NotificationLiveViewContentTest, ReadPictureMapFromParcel_TooLarge_001,
515+ Function | SmallTest | Level1)
516+{
517+ auto rrc = std::make_shared<NotificationLiveViewContent>();
518+ Parcel parcel;
519+ parcel.WriteUint64(static_cast<uint64_t>(MAX_PARCELABLE_VECTOR_NUM) + 1);
520+ parcel.RewindRead(0);
521+ EXPECT_EQ(rrc->ReadPictureMapFromParcel(parcel), false);
522+}
523+ 
524+/**
525+ * @tc.name: ReadPictureMapFromParcel_VectorReadFail_001
526+ * @tc.desc: Test ReadPictureMapFromParcel returns false when pixel map vector read fails.
527+ * @tc.type: FUNC
528+ * @tc.require: issue
529+ */
530+HWTEST_F(NotificationLiveViewContentTest, ReadPictureMapFromParcel_VectorReadFail_001,
531+ Function | SmallTest | Level1)
532+{
533+ auto rrc = std::make_shared<NotificationLiveViewContent>();
534+ Parcel parcel;
535+ parcel.WriteUint64(1);
536+ parcel.WriteString("key");
537+ parcel.RewindRead(0);
538+ EXPECT_EQ(rrc->ReadPictureMapFromParcel(parcel), false);
539+}
540+ 
541+/**
542+ * @tc.name: ReadFromParcel_NullExtensionWantAgent_001
543+ * @tc.desc: Test ReadFromParcel returns false when extensionWantAgent flag is true but parcelable is null.
544+ * @tc.type: FUNC
545+ * @tc.require: issue
546+ */
547+HWTEST_F(NotificationLiveViewContentTest, ReadFromParcel_NullExtensionWantAgent_001,
548+ Function | SmallTest | Level1)
549+{
550+ auto rrc = std::make_shared<NotificationLiveViewContent>();
551+ Parcel parcel;
552+ parcel.WriteString("text");
553+ parcel.WriteString("title");
554+ parcel.WriteString("additionalText");
555+ parcel.WriteBool(false);
556+ parcel.WriteInt32(0);
557+ parcel.WriteInt32(static_cast<int32_t>(NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_CREATE));
558+ parcel.WriteUint32(1);
559+ parcel.WriteBool(false);
560+ parcel.WriteBool(false);
561+ parcel.WriteUint64(0);
562+ parcel.WriteBool(true);
563+ parcel.RewindRead(0);
564+ EXPECT_EQ(rrc->ReadFromParcel(parcel), false);
565+}
444}566}
445}567}
@@ -295,7 +295,7 @@ HWTEST_F(NotificationLocalLiveViewButtonTest, addSingleButtonIconResource_00001,
295 button->addSingleButtonIconResource(resource2);295 button->addSingleButtonIconResource(resource2);
296 button->addSingleButtonIconResource(resource3);296 button->addSingleButtonIconResource(resource3);
297 button->addSingleButtonIconResource(resource4);297 button->addSingleButtonIconResource(resource4);
298- EXPECT_EQ(button->GetAllButtonIconResource().size(), 4);298+ EXPECT_EQ(button->GetAllButtonIconResource().size(), 3);
299}299}
300 300 
301HWTEST_F(NotificationLocalLiveViewButtonTest, ClearButtonIcons_00001, Function | SmallTest | Level1)301HWTEST_F(NotificationLocalLiveViewButtonTest, ClearButtonIcons_00001, Function | SmallTest | Level1)
@@ -336,5 +336,22 @@ HWTEST_F(NotificationMultiLineContentTest, Marshalling_00002, Function | SmallTe
336 rrc->lineWantAgents_.resize(256);336 rrc->lineWantAgents_.resize(256);
337 EXPECT_EQ(rrc->Marshalling(parcel), false);337 EXPECT_EQ(rrc->Marshalling(parcel), false);
338}338}
339+ 
340+/**
341+ * @tc.name: ReadFromParcel_NullWantAgent_001
342+ * @tc.desc: Test ReadFromParcel returns false when a wantAgent parcelable reads as null.
343+ * @tc.type: FUNC
344+ * @tc.require: issue
345+ */
346+HWTEST_F(NotificationMultiLineContentTest, ReadFromParcel_NullWantAgent_001, Function | SmallTest | Level1)
347+{
348+ Parcel parcel;
349+ auto rrc = std::make_shared<NotificationMultiLineContent>();
350+ std::vector<std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>> agents = {nullptr};
351+ rrc->SetLineWantAgents(agents);
352+ rrc->Marshalling(parcel);
353+ parcel.RewindRead(0);
354+ EXPECT_EQ(rrc->ReadFromParcel(parcel), false);
355+}
339}356}
340}357}
@@ -27,6 +27,7 @@
27#include "notification_normal_content.h"27#include "notification_normal_content.h"
28#include "notification_picture_content.h"28#include "notification_picture_content.h"
29#include "notification_request.h"29#include "notification_request.h"
30+#include "notification_trigger.h"
30#include "pixel_map.h"31#include "pixel_map.h"
31#undef private32#undef private
32#undef protected33#undef protected
@@ -2214,5 +2215,574 @@ HWTEST_F(NotificationRequestTest, IncrementalUpdateLiveview_NullOldRequest_0001,
2214 notificationRequest.IncrementalUpdateLiveview(nullptr);2215 notificationRequest.IncrementalUpdateLiveview(nullptr);
2215 EXPECT_NE(notificationRequest.GetContent(), nullptr);2216 EXPECT_NE(notificationRequest.GetContent(), nullptr);
2216}2217}
2218+ 
2219+/**
2220+ * @tc.name: SetSlotType_Invalid_001
2221+ * @tc.desc: Test SetSlotType with invalid slot type does not set.
2222+ * @tc.type: FUNC
2223+ * @tc.require: issue
2224+ */
2225+HWTEST_F(NotificationRequestTest, SetSlotType_Invalid_001, Function | SmallTest | Level1)
2226+{
2227+ NotificationRequest notificationRequest(10);
2228+ auto before = notificationRequest.GetSlotType();
2229+ notificationRequest.SetSlotType(static_cast<NotificationConstant::SlotType>(-1));
2230+ EXPECT_EQ(notificationRequest.GetSlotType(), before);
2231+ notificationRequest.SetSlotType(static_cast<NotificationConstant::SlotType>(100));
2232+ EXPECT_EQ(notificationRequest.GetSlotType(), before);
2233+}
2234+ 
2235+/**
2236+ * @tc.name: SetNotificationUserInputHistory_TooLarge_001
2237+ * @tc.desc: Test SetNotificationUserInputHistory rejects vector exceeding MAX_USER_INPUT_HISTORY.
2238+ * @tc.type: FUNC
2239+ * @tc.require: issue
2240+ */
2241+HWTEST_F(NotificationRequestTest, SetNotificationUserInputHistory_TooLarge_001, Function | SmallTest | Level1)
2242+{
2243+ NotificationRequest notificationRequest(10);
2244+ std::vector<std::string> text(NotificationRequest::MAX_USER_INPUT_HISTORY + 1, "input");
2245+ notificationRequest.SetNotificationUserInputHistory(text);
2246+ EXPECT_EQ(notificationRequest.GetNotificationUserInputHistory().size(), 0);
2247+}
2248+ 
2249+/**
2250+ * @tc.name: SetDevicesSupportOperate_TooLarge_001
2251+ * @tc.desc: Test SetDevicesSupportOperate rejects vector exceeding MAX_PARCELABLE_VECTOR_NUM.
2252+ * @tc.type: FUNC
2253+ * @tc.require: issue
2254+ */
2255+HWTEST_F(NotificationRequestTest, SetDevicesSupportOperate_TooLarge_001, Function | SmallTest | Level1)
2256+{
2257+ NotificationRequest notificationRequest(10);
2258+ std::vector<std::string> devices(static_cast<size_t>(MAX_PARCELABLE_VECTOR_NUM) + 1, "device");
2259+ notificationRequest.SetDevicesSupportOperate(devices);
2260+ auto opts = notificationRequest.GetNotificationDistributedOptions();
2261+ EXPECT_EQ(opts.GetDevicesSupportOperate().size(), 0);
2262+}
2263+ 
2264+/**
2265+ * @tc.name: GetCreatorUserId_Invalid_001
2266+ * @tc.desc: Test GetCreatorUserId returns SUBSCRIBE_USER_INIT when creatorUserId_ < 0.
2267+ * @tc.type: FUNC
2268+ * @tc.require: issue
2269+ */
2270+HWTEST_F(NotificationRequestTest, GetCreatorUserId_Invalid_001, Function | SmallTest | Level1)
2271+{
2272+ NotificationRequest notificationRequest(10);
2273+ notificationRequest.creatorUserId_ = -100;
2274+ EXPECT_EQ(notificationRequest.GetCreatorUserId(), SUBSCRIBE_USER_INIT);
2275+}
2276+ 
2277+/**
2278+ * @tc.name: CollaborationFromJson_InvalidExtraInfo_001
2279+ * @tc.desc: Test CollaborationFromJson skips ParseWantParams when extraInfo is invalid JSON.
2280+ * @tc.type: FUNC
2281+ * @tc.require: issue
2282+ */
2283+HWTEST_F(NotificationRequestTest, CollaborationFromJson_InvalidExtraInfo_001, Function | SmallTest | Level1)
2284+{
2285+ std::string jsonStr = R"({"extraInfo": "not_json{"})";
2286+ auto *result = NotificationRequest::CollaborationFromJson(jsonStr);
2287+ ASSERT_NE(result, nullptr);
2288+ EXPECT_EQ(result->additionalParams_, nullptr);
2289+ delete result;
2290+}
2291+ 
2292+/**
2293+ * @tc.name: ConvertJsonToTemplate_TooLarge_001
2294+ * @tc.desc: Test ConvertJsonToTemplate skips templateData when size exceeds MAX_PARCELABLE_VECTOR_NUM.
2295+ * @tc.type: FUNC
2296+ * @tc.require: issue
2297+ */
2298+HWTEST_F(NotificationRequestTest, ConvertJsonToTemplate_TooLarge_001, Function | SmallTest | Level1)
2299+{
2300+ NotificationRequest notificationRequest(10);
2301+ std::string largeData(static_cast<size_t>(MAX_PARCELABLE_VECTOR_NUM) + 1, 'a');
2302+ nlohmann::json jsonObject = nlohmann::json{
2303+ {"template", {{"templateName", "test"}, {"templateData", largeData}}}
2304+ };
2305+ notificationRequest.ConvertJsonToTemplate(&notificationRequest, jsonObject);
2306+ ASSERT_NE(notificationRequest.notificationTemplate_, nullptr);
2307+ EXPECT_EQ(notificationRequest.notificationTemplate_->GetTemplateData(), nullptr);
2308+}
2309+ 
2310+/**
2311+ * @tc.name: ReadFromParcel_UserInputHistoryTooLarge_001
2312+ * @tc.desc: Test ReadFromParcel returns false when userInputHistory size exceeds MAX_USER_INPUT_HISTORY.
2313+ * @tc.type: FUNC
2314+ * @tc.require: issue
2315+ */
2316+HWTEST_F(NotificationRequestTest, ReadFromParcel_UserInputHistoryTooLarge_001, Function | SmallTest | Level1)
2317+{
2318+ NotificationRequest notificationRequest(10);
2319+ notificationRequest.userInputHistory_.resize(NotificationRequest::MAX_USER_INPUT_HISTORY + 1, "test");
2320+ Parcel parcel;
2321+ ASSERT_TRUE(notificationRequest.Marshalling(parcel));
2322+ parcel.RewindRead(0);
2323+ NotificationRequest result(10);
2324+ EXPECT_EQ(result.ReadFromParcel(parcel), false);
2325+}
2326+ 
2327+/**
2328+ * @tc.name: ConvertJsonToNumExt_OwnerUserIdOutOfRange_001
2329+ * @tc.desc: Test ConvertJsonToNumExt skips ownerUserId when out of int32 range.
2330+ * @tc.type: FUNC
2331+ * @tc.require: issue
2332+ */
2333+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_OwnerUserIdOutOfRange_001, Function | SmallTest | Level1)
2334+{
2335+ NotificationRequest notificationRequest(10);
2336+ int32_t defaultVal = notificationRequest.GetOwnerUserId();
2337+ nlohmann::json jsonObject = nlohmann::json{{"ownerUserId", 2147483648LL}};
2338+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2339+ EXPECT_EQ(notificationRequest.GetOwnerUserId(), defaultVal);
2340+}
2341+ 
2342+/**
2343+ * @tc.name: ConvertJsonToNumExt_OwnerUidOutOfRange_001
2344+ * @tc.desc: Test ConvertJsonToNumExt skips ownerUid when out of int32 range.
2345+ * @tc.type: FUNC
2346+ * @tc.require: issue
2347+ */
2348+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_OwnerUidOutOfRange_001, Function | SmallTest | Level1)
2349+{
2350+ NotificationRequest notificationRequest(10);
2351+ int32_t defaultVal = notificationRequest.GetOwnerUid();
2352+ nlohmann::json jsonObject = nlohmann::json{{"ownerUid", 2147483648LL}};
2353+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2354+ EXPECT_EQ(notificationRequest.GetOwnerUid(), defaultVal);
2355+}
2356+ 
2357+/**
2358+ * @tc.name: ConvertJsonToNumExt_NotificationControlFlagsOutOfRange_001
2359+ * @tc.desc: Test ConvertJsonToNumExt skips notificationControlFlags when out of range.
2360+ * @tc.type: FUNC
2361+ * @tc.require: issue
2362+ */
2363+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_NotificationControlFlagsOutOfRange_001,
2364+ Function | SmallTest | Level1)
2365+{
2366+ NotificationRequest notificationRequest(10);
2367+ uint32_t defaultVal = notificationRequest.GetNotificationControlFlags();
2368+ nlohmann::json jsonObject = nlohmann::json{{"notificationControlFlags", -1}};
2369+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2370+ EXPECT_EQ(notificationRequest.GetNotificationControlFlags(), defaultVal);
2371+}
2372+ 
2373+/**
2374+ * @tc.name: ConvertJsonToEnum_InvalidSlotType_001
2375+ * @tc.desc: Test ConvertJsonToEnum skips slotType when invalid.
2376+ * @tc.type: FUNC
2377+ * @tc.require: issue
2378+ */
2379+HWTEST_F(NotificationRequestTest, ConvertJsonToEnum_InvalidSlotType_001, Function | SmallTest | Level1)
2380+{
2381+ NotificationRequest notificationRequest(10);
2382+ auto before = notificationRequest.GetSlotType();
2383+ nlohmann::json jsonObject = nlohmann::json{{"slotType", -1}};
2384+ notificationRequest.ConvertJsonToEnum(&notificationRequest, jsonObject);
2385+ EXPECT_EQ(notificationRequest.GetSlotType(), before);
2386+ nlohmann::json jsonObject2 = nlohmann::json{{"slotType", 100}};
2387+ notificationRequest.ConvertJsonToEnum(&notificationRequest, jsonObject2);
2388+ EXPECT_EQ(notificationRequest.GetSlotType(), before);
2389+}
2390+ 
2391+/**
2392+ * @tc.name: ConvertJsonToNotificationActionButton_NotArray_001
2393+ * @tc.desc: Test ConvertJsonToNotificationActionButton returns false when actionButtons is not an array.
2394+ * @tc.type: FUNC
2395+ * @tc.require: issue
2396+ */
2397+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationActionButton_NotArray_001, Function | SmallTest | Level1)
2398+{
2399+ NotificationRequest notificationRequest(10);
2400+ nlohmann::json jsonObject = nlohmann::json{{"actionButtons", "not_array"}};
2401+ bool result = notificationRequest.ConvertJsonToNotificationActionButton(&notificationRequest, jsonObject);
2402+ EXPECT_EQ(result, false);
2403+}
2404+ 
2405+/**
2406+ * @tc.name: ConvertJsonToNotificationTrigger_InvalidTriggerType_001
2407+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns false when triggerType is out of range.
2408+ * @tc.type: FUNC
2409+ * @tc.require: issue
2410+ */
2411+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_InvalidTriggerType_001,
2412+ Function | SmallTest | Level1)
2413+{
2414+ NotificationRequest notificationRequest(10);
2415+ nlohmann::json jsonObject = nlohmann::json{
2416+ {"notificationTrigger", {{"triggerType", 0}}}
2417+ };
2418+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2419+ EXPECT_EQ(result, false);
2420+}
2421+ 
2422+/**
2423+ * @tc.name: ConvertJsonToNotificationTrigger_InvalidConfigPath_001
2424+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns false when triggerConfigPath is out of range.
2425+ * @tc.type: FUNC
2426+ * @tc.require: issue
2427+ */
2428+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_InvalidConfigPath_001, Function | SmallTest | Level1)
2429+{
2430+ NotificationRequest notificationRequest(10);
2431+ nlohmann::json jsonObject = nlohmann::json{
2432+ {"notificationTrigger", {{"triggerConfigPath", 0}}}
2433+ };
2434+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2435+ EXPECT_EQ(result, false);
2436+}
2437+ 
2438+/**
2439+ * @tc.name: NotificationTrigger_FromJson_InvalidTriggerType_001
2440+ * @tc.desc: Test NotificationTrigger::FromJson skips type_ when triggerType is out of range.
2441+ * @tc.type: FUNC
2442+ * @tc.require: issue
2443+ */
2444+HWTEST_F(NotificationRequestTest, NotificationTrigger_FromJson_InvalidTriggerType_001, Function | SmallTest | Level1)
2445+{
2446+ nlohmann::json jsonObject = nlohmann::json{{"triggerType", 0}};
2447+ auto *trigger = NotificationTrigger::FromJson(jsonObject);
2448+ ASSERT_NE(trigger, nullptr);
2449+ EXPECT_NE(trigger->GetTriggerType(), NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE);
2450+ delete trigger;
2451+}
2452+ 
2453+/**
2454+ * @tc.name: NotificationTrigger_FromJson_InvalidConfigPath_001
2455+ * @tc.desc: Test NotificationTrigger::FromJson skips configPath_ when triggerConfigPath is out of range.
2456+ * @tc.type: FUNC
2457+ * @tc.require: issue
2458+ */
2459+HWTEST_F(NotificationRequestTest, NotificationTrigger_FromJson_InvalidConfigPath_001, Function | SmallTest | Level1)
2460+{
2461+ nlohmann::json jsonObject = nlohmann::json{{"triggerConfigPath", 0}};
2462+ auto *trigger = NotificationTrigger::FromJson(jsonObject);
2463+ ASSERT_NE(trigger, nullptr);
2464+ EXPECT_EQ(trigger->GetConfigPath(), NotificationConstant::ConfigPath::CONFIG_PATH_DEVICE_CONFIG);
2465+ delete trigger;
2466+}
2467+ 
2468+/**
2469+ * @tc.name: ConvertJsonToNotificationTrigger_NoTriggerKey_001
2470+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns true when notificationTrigger key is absent.
2471+ * @tc.type: FUNC
2472+ * @tc.require: issue
2473+ */
2474+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NoTriggerKey_001,
2475+ Function | SmallTest | Level1)
2476+{
2477+ NotificationRequest notificationRequest(10);
2478+ nlohmann::json jsonObject = nlohmann::json{{"id", 1}};
2479+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2480+ EXPECT_EQ(result, true);
2481+ EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2482+}
2483+ 
2484+/**
2485+ * @tc.name: ConvertJsonToNotificationTrigger_NullTrigger_001
2486+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns true when notificationTrigger is null.
2487+ * @tc.type: FUNC
2488+ * @tc.require: issue
2489+ */
2490+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NullTrigger_001,
2491+ Function | SmallTest | Level1)
2492+{
2493+ NotificationRequest notificationRequest(10);
2494+ nlohmann::json jsonObject = nlohmann::json{{"notificationTrigger", nullptr}};
2495+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2496+ EXPECT_EQ(result, true);
2497+ EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2498+}
2499+ 
2500+/**
2501+ * @tc.name: SetNotificationUserInputHistory_Valid_001
2502+ * @tc.desc: Test SetNotificationUserInputHistory assigns all elements when size is within limit.
2503+ * @tc.type: FUNC
2504+ * @tc.require: issue
2505+ */
2506+HWTEST_F(NotificationRequestTest, SetNotificationUserInputHistory_Valid_001, Function | SmallTest | Level1)
2507+{
2508+ NotificationRequest notificationRequest(10);
2509+ std::vector<std::string> text {"input1", "input2", "input3"};
2510+ notificationRequest.SetNotificationUserInputHistory(text);
2511+ auto result = notificationRequest.GetNotificationUserInputHistory();
2512+ EXPECT_EQ(result.size(), 3);
2513+ EXPECT_EQ(result[0], "input1");
2514+ EXPECT_EQ(result[1], "input2");
2515+ EXPECT_EQ(result[2], "input3");
2516+ 
2517+ std::vector<std::string> boundary(NotificationRequest::MAX_USER_INPUT_HISTORY, "input");
2518+ notificationRequest.SetNotificationUserInputHistory(boundary);
2519+ EXPECT_EQ(
2520+ notificationRequest.GetNotificationUserInputHistory().size(), NotificationRequest::MAX_USER_INPUT_HISTORY);
2521+}
2522+ 
2523+/**
2524+ * @tc.name: ConvertJsonToEnum_ValidSlotType_001
2525+ * @tc.desc: Test ConvertJsonToEnum sets slotType when value is valid.
2526+ * @tc.type: FUNC
2527+ * @tc.require: issue
2528+ */
2529+HWTEST_F(NotificationRequestTest, ConvertJsonToEnum_ValidSlotType_001, Function | SmallTest | Level1)
2530+{
2531+ NotificationRequest notificationRequest(10);
2532+ nlohmann::json jsonObject = nlohmann::json{{"slotType", 5}};
2533+ notificationRequest.ConvertJsonToEnum(&notificationRequest, jsonObject);
2534+ EXPECT_EQ(notificationRequest.GetSlotType(), NotificationConstant::SlotType::LIVE_VIEW);
2535+}
2536+ 
2537+/**
2538+ * @tc.name: CollaborationFromJson_NoExtraInfo_001
2539+ * @tc.desc: Test CollaborationFromJson works when extraInfo key is absent.
2540+ * @tc.type: FUNC
2541+ * @tc.require: issue
2542+ */
2543+HWTEST_F(NotificationRequestTest, CollaborationFromJson_NoExtraInfo_001, Function | SmallTest | Level1)
2544+{
2545+ std::string jsonStr = R"({"id": 1})";
2546+ auto *result = NotificationRequest::CollaborationFromJson(jsonStr);
2547+ ASSERT_NE(result, nullptr);
2548+ EXPECT_EQ(result->additionalParams_, nullptr);
2549+ delete result;
2550+}
2551+ 
2552+/**
2553+ * @tc.name: CollaborationFromJson_ExtraInfoNotString_001
2554+ * @tc.desc: Test CollaborationFromJson skips extraInfo when it is not a string.
2555+ * @tc.type: FUNC
2556+ * @tc.require: issue
2557+ */
2558+HWTEST_F(NotificationRequestTest, CollaborationFromJson_ExtraInfoNotString_001, Function | SmallTest | Level1)
2559+{
2560+ std::string jsonStr = R"({"extraInfo": 123})";
2561+ auto *result = NotificationRequest::CollaborationFromJson(jsonStr);
2562+ ASSERT_NE(result, nullptr);
2563+ EXPECT_EQ(result->additionalParams_, nullptr);
2564+ delete result;
2565+}
2566+ 
2567+/**
2568+ * @tc.name: CollaborationFromJson_ExtraInfoEmpty_001
2569+ * @tc.desc: Test CollaborationFromJson skips extraInfo when it is an empty string.
2570+ * @tc.type: FUNC
2571+ * @tc.require: issue
2572+ */
2573+HWTEST_F(NotificationRequestTest, CollaborationFromJson_ExtraInfoEmpty_001, Function | SmallTest | Level1)
2574+{
2575+ std::string jsonStr = R"({"extraInfo": ""})";
2576+ auto *result = NotificationRequest::CollaborationFromJson(jsonStr);
2577+ ASSERT_NE(result, nullptr);
2578+ EXPECT_EQ(result->additionalParams_, nullptr);
2579+ delete result;
2580+}
2581+ 
2582+/**
2583+ * @tc.name: ConvertJsonToNumExt_ValidValues_001
2584+ * @tc.desc: Test ConvertJsonToNumExt assigns all fields when values are in range.
2585+ * @tc.type: FUNC
2586+ * @tc.require: issue
2587+ */
2588+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_ValidValues_001, Function | SmallTest | Level1)
2589+{
2590+ NotificationRequest notificationRequest(10);
2591+ nlohmann::json jsonObject = nlohmann::json{
2592+ {"updateDeadLine", 111},
2593+ {"finishDeadLine", 222},
2594+ {"triggerDeadLine", 333},
2595+ {"ownerUserId", 10},
2596+ {"ownerUid", 20},
2597+ {"notificationControlFlags", 30},
2598+ {"snoozeDelayTime", 444}
2599+ };
2600+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2601+ EXPECT_EQ(notificationRequest.GetUpdateDeadLine(), 111);
2602+ EXPECT_EQ(notificationRequest.GetFinishDeadLine(), 222);
2603+ EXPECT_EQ(notificationRequest.GetGeofenceTriggerDeadLine(), 333);
2604+ EXPECT_EQ(notificationRequest.GetOwnerUserId(), 10);
2605+ EXPECT_EQ(notificationRequest.GetOwnerUid(), 20);
2606+ EXPECT_EQ(notificationRequest.GetNotificationControlFlags(), 30U);
2607+ EXPECT_EQ(notificationRequest.GetSnoozeDelayTime(), 444);
2608+}
2609+ 
2610+/**
2611+ * @tc.name: ConvertJsonToNumExt_NonIntegerValues_001
2612+ * @tc.desc: Test ConvertJsonToNumExt skips fields when values are not integers.
2613+ * @tc.type: FUNC
2614+ * @tc.require: issue
2615+ */
2616+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_NonIntegerValues_001, Function | SmallTest | Level1)
2617+{
2618+ NotificationRequest notificationRequest(10);
2619+ int64_t defaultUpdateDeadLine = notificationRequest.GetUpdateDeadLine();
2620+ int64_t defaultFinishDeadLine = notificationRequest.GetFinishDeadLine();
2621+ int64_t defaultTriggerDeadLine = notificationRequest.GetGeofenceTriggerDeadLine();
2622+ int32_t defaultOwnerUserId = notificationRequest.GetOwnerUserId();
2623+ int32_t defaultOwnerUid = notificationRequest.GetOwnerUid();
2624+ uint32_t defaultFlags = notificationRequest.GetNotificationControlFlags();
2625+ int64_t defaultSnoozeDelayTime = notificationRequest.GetSnoozeDelayTime();
2626+ 
2627+ nlohmann::json jsonObject = nlohmann::json{
2628+ {"updateDeadLine", "abc"},
2629+ {"finishDeadLine", "abc"},
2630+ {"triggerDeadLine", "abc"},
2631+ {"ownerUserId", "abc"},
2632+ {"ownerUid", "abc"},
2633+ {"notificationControlFlags", "abc"},
2634+ {"snoozeDelayTime", "abc"}
2635+ };
2636+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2637+ EXPECT_EQ(notificationRequest.GetUpdateDeadLine(), defaultUpdateDeadLine);
2638+ EXPECT_EQ(notificationRequest.GetFinishDeadLine(), defaultFinishDeadLine);
2639+ EXPECT_EQ(notificationRequest.GetGeofenceTriggerDeadLine(), defaultTriggerDeadLine);
2640+ EXPECT_EQ(notificationRequest.GetOwnerUserId(), defaultOwnerUserId);
2641+ EXPECT_EQ(notificationRequest.GetOwnerUid(), defaultOwnerUid);
2642+ EXPECT_EQ(notificationRequest.GetNotificationControlFlags(), defaultFlags);
2643+ EXPECT_EQ(notificationRequest.GetSnoozeDelayTime(), defaultSnoozeDelayTime);
2644+}
2645+ 
2646+/**
2647+ * @tc.name: ConvertJsonToNumExt_BoundaryValues_001
2648+ * @tc.desc: Test ConvertJsonToNumExt assigns fields at boundary values.
2649+ * @tc.type: FUNC
2650+ * @tc.require: issue
2651+ */
2652+HWTEST_F(NotificationRequestTest, ConvertJsonToNumExt_BoundaryValues_001, Function | SmallTest | Level1)
2653+{
2654+ NotificationRequest notificationRequest(10);
2655+ nlohmann::json jsonObject = nlohmann::json{
2656+ {"updateDeadLine", INT64_MIN},
2657+ {"finishDeadLine", INT64_MAX},
2658+ {"triggerDeadLine", -1},
2659+ {"ownerUserId", INT32_MIN},
2660+ {"ownerUid", INT32_MAX},
2661+ {"notificationControlFlags", 4294967295LL},
2662+ {"snoozeDelayTime", 0}
2663+ };
2664+ notificationRequest.ConvertJsonToNumExt(&notificationRequest, jsonObject);
2665+ EXPECT_EQ(notificationRequest.GetUpdateDeadLine(), INT64_MIN);
2666+ EXPECT_EQ(notificationRequest.GetFinishDeadLine(), INT64_MAX);
2667+ EXPECT_EQ(notificationRequest.GetGeofenceTriggerDeadLine(), -1);
2668+ EXPECT_EQ(notificationRequest.GetOwnerUserId(), INT32_MIN);
2669+ EXPECT_EQ(notificationRequest.GetOwnerUid(), INT32_MAX);
2670+ EXPECT_EQ(notificationRequest.GetNotificationControlFlags(), 4294967295U);
2671+ EXPECT_EQ(notificationRequest.GetSnoozeDelayTime(), 0);
2672+}
2673+ 
2674+/**
2675+ * @tc.name: ConvertJsonToNotificationTrigger_ValidTrigger_001
2676+ * @tc.desc: Test ConvertJsonToNotificationTrigger succeeds with valid triggerType and triggerConfigPath.
2677+ * @tc.type: FUNC
2678+ * @tc.require: issue
2679+ */
2680+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_ValidTrigger_001,
2681+ Function | SmallTest | Level1)
2682+{
2683+ NotificationRequest notificationRequest(10);
2684+ nlohmann::json jsonObject = nlohmann::json{
2685+ {"notificationTrigger", {{"triggerType", 1}, {"triggerConfigPath", 2}, {"triggerDisplayTime", 100}}}
2686+ };
2687+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2688+ EXPECT_EQ(result, true);
2689+ auto trigger = notificationRequest.GetNotificationTrigger();
2690+ ASSERT_NE(trigger, nullptr);
2691+ EXPECT_EQ(trigger->GetTriggerType(), NotificationConstant::TriggerType::TRIGGER_TYPE_FENCE);
2692+ EXPECT_EQ(trigger->GetConfigPath(), NotificationConstant::ConfigPath::CONFIG_PATH_CLOUD_CONFIG);
2693+ EXPECT_EQ(trigger->GetDisplayTime(), 100);
2694+}
2695+ 
2696+/**
2697+ * @tc.name: ConvertJsonToNotificationTrigger_TriggerTypeTooLarge_001
2698+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns false when triggerType is greater than range.
2699+ * @tc.type: FUNC
2700+ * @tc.require: issue
2701+ */
2702+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_TriggerTypeTooLarge_001,
2703+ Function | SmallTest | Level1)
2704+{
2705+ NotificationRequest notificationRequest(10);
2706+ nlohmann::json jsonObject = nlohmann::json{
2707+ {"notificationTrigger", {{"triggerType", 2}}}
2708+ };
2709+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2710+ EXPECT_EQ(result, false);
2711+ EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2712+}
2713+ 
2714+/**
2715+ * @tc.name: ConvertJsonToNotificationTrigger_ConfigPathTooLarge_001
2716+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns false when triggerConfigPath is greater than range.
2717+ * @tc.type: FUNC
2718+ * @tc.require: issue
2719+ */
2720+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_ConfigPathTooLarge_001,
2721+ Function | SmallTest | Level1)
2722+{
2723+ NotificationRequest notificationRequest(10);
2724+ nlohmann::json jsonObject = nlohmann::json{
2725+ {"notificationTrigger", {{"triggerConfigPath", 3}}}
2726+ };
2727+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2728+ EXPECT_EQ(result, false);
2729+ EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2730+}
2731+ 
2732+/**
2733+ * @tc.name: ConvertJsonToNotificationTrigger_NonIntegerValues_001
2734+ * @tc.desc: Test ConvertJsonToNotificationTrigger skips validation when values are not integers.
2735+ * @tc.type: FUNC
2736+ * @tc.require: issue
2737+ */
2738+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NonIntegerValues_001,
2739+ Function | SmallTest | Level1)
2740+{
2741+ NotificationRequest notificationRequest(10);
2742+ nlohmann::json jsonObject = nlohmann::json{
2743+ {"notificationTrigger", {{"triggerType", "abc"}, {"triggerConfigPath", "xyz"}}}
2744+ };
2745+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2746+ EXPECT_EQ(result, true);
2747+ auto trigger = notificationRequest.GetNotificationTrigger();
2748+ ASSERT_NE(trigger, nullptr);
2749+ EXPECT_EQ(trigger->GetConfigPath(), NotificationConstant::ConfigPath::CONFIG_PATH_DEVICE_CONFIG);
2750+}
2751+ 
2752+/**
2753+ * @tc.name: ConvertJsonToNotificationTrigger_NoTypeAndConfigKeys_001
2754+ * @tc.desc: Test ConvertJsonToNotificationTrigger succeeds when triggerType and triggerConfigPath keys are absent.
2755+ * @tc.type: FUNC
2756+ * @tc.require: issue
2757+ */
2758+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NoTypeAndConfigKeys_001,
2759+ Function | SmallTest | Level1)
2760+{
2761+ NotificationRequest notificationRequest(10);
2762+ nlohmann::json jsonObject = nlohmann::json{
2763+ {"notificationTrigger", {{"triggerDisplayTime", 50}}}
2764+ };
2765+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2766+ EXPECT_EQ(result, true);
2767+ auto trigger = notificationRequest.GetNotificationTrigger();
2768+ ASSERT_NE(trigger, nullptr);
2769+ EXPECT_EQ(trigger->GetDisplayTime(), 50);
2770+}
2771+ 
2772+/**
2773+ * @tc.name: ConvertJsonToNotificationTrigger_NotObject_001
2774+ * @tc.desc: Test ConvertJsonToNotificationTrigger returns false when notificationTrigger is not an object.
2775+ * @tc.type: FUNC
2776+ * @tc.require: issue
2777+ */
2778+HWTEST_F(NotificationRequestTest, ConvertJsonToNotificationTrigger_NotObject_001,
2779+ Function | SmallTest | Level1)
2780+{
2781+ NotificationRequest notificationRequest(10);
2782+ nlohmann::json jsonObject = nlohmann::json{{"notificationTrigger", 123}};
2783+ bool result = notificationRequest.ConvertJsonToNotificationTrigger(&notificationRequest, jsonObject);
2784+ EXPECT_EQ(result, false);
2785+ EXPECT_EQ(notificationRequest.GetNotificationTrigger(), nullptr);
2786+}
2217} // namespace Notification2787} // namespace Notification
2218} // namespace OHOS2788} // namespace OHOS
@@ -15,6 +15,7 @@
15 15 
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17 17 
18+#include "ans_const_define.h"
18#include "nlohmann/json.hpp"19#include "nlohmann/json.hpp"
19#define private public20#define private public
20#define protected public21#define protected public
@@ -216,8 +217,8 @@ HWTEST_F(NotificationRingtoneInfoTest, SetRingtoneUri_0001, Level1)
216HWTEST_F(NotificationRingtoneInfoTest, SetRingtoneUri_0002, Level1)217HWTEST_F(NotificationRingtoneInfoTest, SetRingtoneUri_0002, Level1)
217{218{
218 NotificationRingtoneInfo info;219 NotificationRingtoneInfo info;
219- std::string ringtoneUri = "";220+ std::string ringtoneUri = "uri2";
220- info.SetRingtoneFileName(ringtoneUri);221+ info.SetRingtoneUri(ringtoneUri);
221 EXPECT_EQ(info.GetRingtoneUri(), ringtoneUri);222 EXPECT_EQ(info.GetRingtoneUri(), ringtoneUri);
222}223}
223 224 
@@ -252,7 +253,7 @@ HWTEST_F(NotificationRingtoneInfoTest, Unmarshalling_0001, Level1)
252 unmarshalling = false;253 unmarshalling = false;
253 }254 }
254 }255 }
255- EXPECT_EQ(unmarshalling, true);256+ EXPECT_EQ(unmarshalling, false);
256}257}
257 258 
258/**259/**
@@ -303,5 +304,120 @@ HWTEST_F(NotificationRingtoneInfoTest, Dump_0001, TestSize.Level1)
303 304 
304 EXPECT_EQ(result, ret);305 EXPECT_EQ(result, ret);
305}306}
307+ 
308+/**
309+ * @tc.name: Marshalling_TitleTooLong_0001
310+ * @tc.desc: Test Marshalling fails when ringtone title exceeds STR_MAX_SIZE.
311+ * @tc.type: FUNC
312+ * @tc.require: issue
313+ */
314+HWTEST_F(NotificationRingtoneInfoTest, Marshalling_TitleTooLong_0001, Level1)
315+{
316+ NotificationRingtoneInfo info;
317+ info.SetRingtoneTitle(std::string(STR_MAX_SIZE + 1, 'a'));
318+ Parcel parcel;
319+ EXPECT_EQ(info.Marshalling(parcel), false);
320+}
321+ 
322+/**
323+ * @tc.name: Marshalling_FileNameTooLong_0001
324+ * @tc.desc: Test Marshalling fails when ringtone file name exceeds STR_MAX_SIZE.
325+ * @tc.type: FUNC
326+ * @tc.require: issue
327+ */
328+HWTEST_F(NotificationRingtoneInfoTest, Marshalling_FileNameTooLong_0001, Level1)
329+{
330+ NotificationRingtoneInfo info;
331+ info.SetRingtoneFileName(std::string(STR_MAX_SIZE + 1, 'a'));
332+ Parcel parcel;
333+ EXPECT_EQ(info.Marshalling(parcel), false);
334+}
335+ 
336+/**
337+ * @tc.name: Marshalling_UriTooLong_0001
338+ * @tc.desc: Test Marshalling fails when ringtone uri exceeds STR_MAX_SIZE.
339+ * @tc.type: FUNC
340+ * @tc.require: issue
341+ */
342+HWTEST_F(NotificationRingtoneInfoTest, Marshalling_UriTooLong_0001, Level1)
343+{
344+ NotificationRingtoneInfo info;
345+ info.SetRingtoneUri(std::string(STR_MAX_SIZE + 1, 'a'));
346+ Parcel parcel;
347+ EXPECT_EQ(info.Marshalling(parcel), false);
348+}
349+ 
350+/**
351+ * @tc.name: ReadFromParcel_InvalidType_0001
352+ * @tc.desc: Test ReadFromParcel fails when ringtone type is invalid.
353+ * @tc.type: FUNC
354+ * @tc.require: issue
355+ */
356+HWTEST_F(NotificationRingtoneInfoTest, ReadFromParcel_InvalidType_0001, Level1)
357+{
358+ NotificationRingtoneInfo info;
359+ Parcel parcel;
360+ parcel.WriteInt32(-1);
361+ EXPECT_EQ(info.ReadFromParcel(parcel), false);
362+}
363+ 
364+/**
365+ * @tc.name: ReadFromParcel_TypeOnly_0001
366+ * @tc.desc: Test ReadFromParcel fails when only type is written (title read fails).
367+ * @tc.type: FUNC
368+ * @tc.require: issue
369+ */
370+HWTEST_F(NotificationRingtoneInfoTest, ReadFromParcel_TypeOnly_0001, Level1)
371+{
372+ NotificationRingtoneInfo info;
373+ Parcel parcel;
374+ parcel.WriteInt32(static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_LOCAL));
375+ EXPECT_EQ(info.ReadFromParcel(parcel), false);
376+}
377+ 
378+/**
379+ * @tc.name: ReadFromParcel_TypeTitleOnly_0001
380+ * @tc.desc: Test ReadFromParcel fails when type and title are written (file name read fails).
381+ * @tc.type: FUNC
382+ * @tc.require: issue
383+ */
384+HWTEST_F(NotificationRingtoneInfoTest, ReadFromParcel_TypeTitleOnly_0001, Level1)
385+{
386+ NotificationRingtoneInfo info;
387+ Parcel parcel;
388+ parcel.WriteInt32(static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_LOCAL));
389+ parcel.WriteString("title");
390+ EXPECT_EQ(info.ReadFromParcel(parcel), false);
391+}
392+ 
393+/**
394+ * @tc.name: ReadFromParcel_TypeTitleNameOnly_0001
395+ * @tc.desc: Test ReadFromParcel fails when type, title and file name are written (uri read fails).
396+ * @tc.type: FUNC
397+ * @tc.require: issue
398+ */
399+HWTEST_F(NotificationRingtoneInfoTest, ReadFromParcel_TypeTitleNameOnly_0001, Level1)
400+{
401+ NotificationRingtoneInfo info;
402+ Parcel parcel;
403+ parcel.WriteInt32(static_cast<int32_t>(NotificationConstant::RingtoneType::RINGTONE_TYPE_LOCAL));
404+ parcel.WriteString("title");
405+ parcel.WriteString("name");
406+ EXPECT_EQ(info.ReadFromParcel(parcel), false);
407+}
408+ 
409+/**
410+ * @tc.name: FromJson_InvalidType_0001
411+ * @tc.desc: Test FromJson leaves ringtone type unchanged when type is invalid.
412+ * @tc.type: FUNC
413+ * @tc.require: issue
414+ */
415+HWTEST_F(NotificationRingtoneInfoTest, FromJson_InvalidType_0001, Level1)
416+{
417+ NotificationRingtoneInfo info;
418+ info.SetRingtoneType(NotificationConstant::RingtoneType::RINGTONE_TYPE_LOCAL);
419+ info.FromJson(R"({"ringtoneType": -1})");
420+ EXPECT_EQ(info.GetRingtoneType(), NotificationConstant::RingtoneType::RINGTONE_TYPE_LOCAL);
421+}
306}422}
307}423}
@@ -17,7 +17,11 @@
17#include <memory>17#include <memory>
18#include <string>18#include <string>
19#include "int_wrapper.h"19#include "int_wrapper.h"
20+#define private public
21+#define protected public
20#include "notification_statistics.h"22#include "notification_statistics.h"
23+#undef private
24+#undef protected
21 25 
22using namespace testing::ext;26using namespace testing::ext;
23namespace OHOS {27namespace OHOS {
@@ -229,5 +233,36 @@ HWTEST_F(NotificationStatisticsTest, Marshalling_00002, Function | SmallTest | L
229 auto ptr = statistics.Unmarshalling(parcel);233 auto ptr = statistics.Unmarshalling(parcel);
230 EXPECT_EQ(ptr, nullptr);234 EXPECT_EQ(ptr, nullptr);
231}235}
236+ 
237+/**
238+ * @tc.name: ReadFromParcel_ReadInt64Fail_001
239+ * @tc.desc: Test ReadFromParcel when ReadInt64 fails after a valid bundleOption.
240+ * @tc.type: FUNC
241+ * @tc.require: issue
242+ */
243+HWTEST_F(NotificationStatisticsTest, ReadFromParcel_ReadInt64Fail_001, Function | SmallTest | Level1)
244+{
245+ Parcel parcel;
246+ sptr<NotificationBundleOption> bundle = new (std::nothrow) NotificationBundleOption();
247+ parcel.WriteParcelable(bundle);
248+ NotificationStatistics statistics;
249+ EXPECT_EQ(statistics.ReadFromParcel(parcel), false);
250+}
251+ 
252+/**
253+ * @tc.name: ReadFromParcel_ReadInt32Fail_001
254+ * @tc.desc: Test ReadFromParcel when ReadInt32 fails after a valid bundleOption and lastTime.
255+ * @tc.type: FUNC
256+ * @tc.require: issue
257+ */
258+HWTEST_F(NotificationStatisticsTest, ReadFromParcel_ReadInt32Fail_001, Function | SmallTest | Level1)
259+{
260+ Parcel parcel;
261+ sptr<NotificationBundleOption> bundle = new (std::nothrow) NotificationBundleOption();
262+ parcel.WriteParcelable(bundle);
263+ parcel.WriteInt64(1000);
264+ NotificationStatistics statistics;
265+ EXPECT_EQ(statistics.ReadFromParcel(parcel), false);
266+}
232}267}
233}268}
@@ -18,6 +18,7 @@
18 18 
19#define private public19#define private public
20#define protected public20#define protected public
21+#include "ans_const_define.h"
21#include "notification_subscribe_info.h"22#include "notification_subscribe_info.h"
22#include "picture_option.h"23#include "picture_option.h"
23#include "voice_content_option.h"24#include "voice_content_option.h"
@@ -903,5 +904,120 @@ HWTEST_F(NotificationSubscribeInfoTest, PriorityStrategy_Marshalling_00001, Func
903 EXPECT_EQ(result->GetPriorityStrategy(), 0);904 EXPECT_EQ(result->GetPriorityStrategy(), 0);
904 delete result;905 delete result;
905}906}
907+ 
908+/**
909+ * @tc.name: ReadSlotTypesFromParcel_InvalidSlotType_001
910+ * @tc.desc: Test ReadSlotTypesFromParcel returns false when slotType is out of range.
911+ * @tc.type: FUNC
912+ * @tc.require: issueI5WRQ2
913+ */
914+HWTEST_F(NotificationSubscribeInfoTest, ReadSlotTypesFromParcel_InvalidSlotType_001, Function | SmallTest | Level1)
915+{
916+ NotificationSubscribeInfo subscribeInfo;
917+ Parcel parcel;
918+ parcel.WriteUint32(1);
919+ parcel.WriteInt32(-1);
920+ parcel.RewindRead(0);
921+ EXPECT_EQ(subscribeInfo.ReadSlotTypesFromParcel(parcel), false);
922+}
923+ 
924+/**
925+ * @tc.name: ReadSlotTypesFromParcel_InvalidSlotType_002
926+ * @tc.desc: Test ReadSlotTypesFromParcel returns false when slotType >= ILLEGAL_TYPE.
927+ * @tc.type: FUNC
928+ * @tc.require: issueI5WRQ2
929+ */
930+HWTEST_F(NotificationSubscribeInfoTest, ReadSlotTypesFromParcel_InvalidSlotType_002, Function | SmallTest | Level1)
931+{
932+ NotificationSubscribeInfo subscribeInfo;
933+ Parcel parcel;
934+ parcel.WriteUint32(1);
935+ parcel.WriteInt32(static_cast<int32_t>(NotificationConstant::SlotType::ILLEGAL_TYPE));
936+ parcel.RewindRead(0);
937+ EXPECT_EQ(subscribeInfo.ReadSlotTypesFromParcel(parcel), false);
938+}
939+ 
940+/**
941+ * @tc.name: ReadFromParcel_AppNamesTooLarge_001
942+ * @tc.desc: Test ReadFromParcel returns false when appNames size exceeds MAX_BUNDLE_LIST_SIZE.
943+ * @tc.type: FUNC
944+ * @tc.require: issueI5WRQ2
945+ */
946+HWTEST_F(NotificationSubscribeInfoTest, ReadFromParcel_AppNamesTooLarge_001, Function | SmallTest | Level1)
947+{
948+ std::vector<std::string> appNames(MAX_BUNDLE_LIST_SIZE + 1, "app");
949+ Parcel parcel;
950+ parcel.WriteStringVector(appNames);
951+ parcel.RewindRead(0);
952+ NotificationSubscribeInfo subscribeInfo;
953+ EXPECT_EQ(subscribeInfo.ReadFromParcel(parcel), false);
954+}
955+ 
956+/**
957+ * @tc.name: ReadVoiceContentOptionFromParcel_ReadBoolFail_001
958+ * @tc.desc: Test ReadVoiceContentOptionFromParcel returns false when ReadBool fails.
959+ * @tc.type: FUNC
960+ * @tc.require: issueI5WRQ2
961+ */
962+HWTEST_F(NotificationSubscribeInfoTest, ReadVoiceContentOptionFromParcel_ReadBoolFail_001,
963+ Function | SmallTest | Level1)
964+{
965+ NotificationSubscribeInfo subscribeInfo;
966+ Parcel parcel;
967+ EXPECT_EQ(subscribeInfo.ReadVoiceContentOptionFromParcel(parcel), false);
968+}
969+ 
970+/**
971+ * @tc.name: ReadPictureOptionFromParcel_ReadBoolFail_001
972+ * @tc.desc: Test ReadPictureOptionFromParcel returns false when ReadBool fails.
973+ * @tc.type: FUNC
974+ * @tc.require: issueI5WRQ2
975+ */
976+HWTEST_F(NotificationSubscribeInfoTest, ReadPictureOptionFromParcel_ReadBoolFail_001, Function | SmallTest | Level1)
977+{
978+ NotificationSubscribeInfo subscribeInfo;
979+ Parcel parcel;
980+ EXPECT_EQ(subscribeInfo.ReadPictureOptionFromParcel(parcel), false);
981+}
982+ 
983+/**
984+ * @tc.name: SetSubscriberBundleName_Empty_001
985+ * @tc.desc: Test SetSubscriberBundleName rejects empty string.
986+ * @tc.type: FUNC
987+ * @tc.require: issueI5WRQ2
988+ */
989+HWTEST_F(NotificationSubscribeInfoTest, SetSubscriberBundleName_Empty_001, Function | SmallTest | Level1)
990+{
991+ NotificationSubscribeInfo subscribeInfo;
992+ subscribeInfo.SetSubscriberBundleName("");
993+ EXPECT_EQ(subscribeInfo.GetSubscriberBundleName(), "");
994+}
995+ 
996+/**
997+ * @tc.name: SetSubscriberBundleName_TooLarge_001
998+ * @tc.desc: Test SetSubscriberBundleName rejects string exceeding STR_MAX_SIZE.
999+ * @tc.type: FUNC
1000+ * @tc.require: issueI5WRQ2
1001+ */
1002+HWTEST_F(NotificationSubscribeInfoTest, SetSubscriberBundleName_TooLarge_001, Function | SmallTest | Level1)
1003+{
1004+ NotificationSubscribeInfo subscribeInfo;
1005+ std::string largeName(STR_MAX_SIZE + 1, 'a');
1006+ subscribeInfo.SetSubscriberBundleName(largeName);
1007+ EXPECT_EQ(subscribeInfo.GetSubscriberBundleName(), "");
1008+}
1009+ 
1010+/**
1011+ * @tc.name: SetSubscriberBundleName_Valid_001
1012+ * @tc.desc: Test SetSubscriberBundleName accepts valid string.
1013+ * @tc.type: FUNC
1014+ * @tc.require: issueI5WRQ2
1015+ */
1016+HWTEST_F(NotificationSubscribeInfoTest, SetSubscriberBundleName_Valid_001, Function | SmallTest | Level1)
1017+{
1018+ NotificationSubscribeInfo subscribeInfo;
1019+ subscribeInfo.SetSubscriberBundleName("com.test.bundle");
1020+ EXPECT_EQ(subscribeInfo.GetSubscriberBundleName(), "com.test.bundle");
1021+}
906}1022}
907}1023}