已合并
社区漏洞fix #813
社区漏洞fix #813
已合并
liuzongze创建于 6月23日
共 7 个文件变更+324-22
@@ -127,6 +127,21 @@ zchar Char::GetChar(const std::string &str,
127 unsigned int size = str.length();127 unsigned int size = str.length();
128 unsigned int now = 0;128 unsigned int now = 0;
129 while (*p && p < end) {129 while (*p && p < end) {
130+ unsigned char firstByte = static_cast<unsigned char>(*p);
131+ unsigned int seqLen = BYTE_COUNT_1;
132+ if (firstByte >= 0xC0 && firstByte <= 0xDF) {
133+ seqLen = BYTE_COUNT_2;
134+ } else if (firstByte >= 0xE0 && firstByte <= 0xEF) {
135+ seqLen = BYTE_COUNT_3;
136+ } else if (firstByte >= 0xF0 && firstByte <= 0xF7) {
137+ seqLen = BYTE_COUNT_4;
138+ } else if (firstByte >= 0xF8) {
139+ break;
140+ }
141+ if (now + seqLen > size) {
142+ break;
143+ }
144+ 
130 zchar unicode = GetCharInternal((unsigned char *)p, bsize);145 zchar unicode = GetCharInternal((unsigned char *)p, bsize);
131 if (bsize == 0 || now + bsize > size) {146 if (bsize == 0 || now + bsize > size) {
132 break;147 break;
@@ -147,7 +162,7 @@ zchar Char::GetCharInternal(const unsigned char *cur,
147 unsigned int &size)162 unsigned int &size)
148{163{
149 if (isascii(*cur) != 0) {164 if (isascii(*cur) != 0) {
150- size = 1;165+ size = BYTE_COUNT_1;
151 return *cur;166 return *cur;
152 }167 }
153 168 
@@ -155,12 +170,12 @@ zchar Char::GetCharInternal(const unsigned char *cur,
155 zchar result = firstChar;170 zchar result = firstChar;
156 zchar mask = 0x40;171 zchar mask = 0x40;
157 zchar ignoreMask = 0xFFFFFF80;172 zchar ignoreMask = 0xFFFFFF80;
158- unsigned int num2Read = 1;173+ unsigned int num2Read = BYTE_COUNT_1;
159- for (; (firstChar & mask); num2Read++, ignoreMask |= mask, mask >>= 1) {174+ for (; (firstChar & mask) && num2Read < BYTE_COUNT_4; num2Read++, ignoreMask |= mask, mask >>= 1) {
160 result = (result << BYTE_SHIFT) + (*cur++ & 0x3F);175 result = (result << BYTE_SHIFT) + (*cur++ & 0x3F);
161 }176 }
162 ignoreMask |= mask;177 ignoreMask |= mask;
163- result &= ~(ignoreMask << (BYTE_SHIFT * (num2Read - 1)));178+ result &= ~(ignoreMask << (BYTE_SHIFT * (num2Read - BYTE_COUNT_1)));
164 size = num2Read;179 size = num2Read;
165 return result;180 return result;
166}181}
@@ -74,7 +74,7 @@ public:
74 static constexpr char SIGNATURE = '[';74 static constexpr char SIGNATURE = '[';
75 75 
76private:76private:
77- static void ParseElement(IArray *array, /* [in] */77+ static bool ParseElement(IArray *array, /* [in] */
78 std::function<sptr<IInterface>(std::string &)> func, /* [in] */78 std::function<sptr<IInterface>(std::string &)> func, /* [in] */
79 const std::string &values, /* [in] */79 const std::string &values, /* [in] */
80 long size); /* [in] */80 long size); /* [in] */
@@ -99,7 +99,15 @@ bool Array::Equals(IObject &other) /* [in] */
99 }99 }
100 100 
101 for (long i = 0; i < size_; i++) {101 for (long i = 0; i < size_; i++) {
102- if (!Object::Equals(*(values_[i].GetRefPtr()), *(otherObj->values_[i].GetRefPtr()))) {102+ auto *left = values_[i].GetRefPtr();
103+ auto *right = otherObj->values_[i].GetRefPtr();
104+ if (left == nullptr && right == nullptr) {
105+ continue;
106+ }
107+ if (left == nullptr || right == nullptr) {
108+ return false;
109+ }
110+ if (!Object::Equals(*left, *right)) {
103 return false;111 return false;
104 }112 }
105 }113 }
@@ -154,7 +162,9 @@ sptr<IArray> Array::ParseString(const std::string &values, long size)
154 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IString);162 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IString);
155 if (array != nullptr) {163 if (array != nullptr) {
156 auto func = [](const std::string &str) -> sptr<IInterface> { return String::Parse(str); };164 auto func = [](const std::string &str) -> sptr<IInterface> { return String::Parse(str); };
157- ParseElement(array, func, values, size);165+ if (!ParseElement(array, func, values, size)) {
166+ return nullptr;
167+ }
158 }168 }
159 return array;169 return array;
160}170}
@@ -164,7 +174,9 @@ sptr<IArray> Array::ParseBoolean(const std::string &values, long size)
164 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IBoolean);174 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IBoolean);
165 if (array != nullptr) {175 if (array != nullptr) {
166 auto func = [](const std::string &str) -> sptr<IInterface> { return Boolean::Parse(str); };176 auto func = [](const std::string &str) -> sptr<IInterface> { return Boolean::Parse(str); };
167- ParseElement(array, func, values, size);177+ if (!ParseElement(array, func, values, size)) {
178+ return nullptr;
179+ }
168 }180 }
169 return array;181 return array;
170}182}
@@ -174,7 +186,9 @@ sptr<IArray> Array::ParseByte(const std::string &values, long size)
174 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IByte);186 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IByte);
175 if (array != nullptr) {187 if (array != nullptr) {
176 auto func = [](const std::string &str) -> sptr<IInterface> { return Byte::Parse(str); };188 auto func = [](const std::string &str) -> sptr<IInterface> { return Byte::Parse(str); };
177- ParseElement(array, func, values, size);189+ if (!ParseElement(array, func, values, size)) {
190+ return nullptr;
191+ }
178 }192 }
179 return array;193 return array;
180}194}
@@ -184,7 +198,9 @@ sptr<IArray> Array::ParseShort(const std::string &values, long size)
184 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IShort);198 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IShort);
185 if (array != nullptr) {199 if (array != nullptr) {
186 auto func = [](const std::string &str) -> sptr<IInterface> { return Short::Parse(str); };200 auto func = [](const std::string &str) -> sptr<IInterface> { return Short::Parse(str); };
187- ParseElement(array, func, values, size);201+ if (!ParseElement(array, func, values, size)) {
202+ return nullptr;
203+ }
188 }204 }
189 return array;205 return array;
190}206}
@@ -194,7 +210,9 @@ sptr<IArray> Array::ParseInteger(const std::string &values, long size)
194 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IInteger);210 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IInteger);
195 if (array != nullptr) {211 if (array != nullptr) {
196 auto func = [](const std::string &str) -> sptr<IInterface> { return Integer::Parse(str); };212 auto func = [](const std::string &str) -> sptr<IInterface> { return Integer::Parse(str); };
197- ParseElement(array, func, values, size);213+ if (!ParseElement(array, func, values, size)) {
214+ return nullptr;
215+ }
198 }216 }
199 return array;217 return array;
200}218}
@@ -204,7 +222,9 @@ sptr<IArray> Array::ParseLong(const std::string &values, long size)
204 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_ILong);222 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_ILong);
205 if (array != nullptr) {223 if (array != nullptr) {
206 auto func = [](const std::string &str) -> sptr<IInterface> { return Long::Parse(str); };224 auto func = [](const std::string &str) -> sptr<IInterface> { return Long::Parse(str); };
207- ParseElement(array, func, values, size);225+ if (!ParseElement(array, func, values, size)) {
226+ return nullptr;
227+ }
208 }228 }
209 return array;229 return array;
210}230}
@@ -214,7 +234,9 @@ sptr<IArray> Array::ParseFloat(const std::string &values, long size)
214 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IFloat);234 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IFloat);
215 if (array != nullptr) {235 if (array != nullptr) {
216 auto func = [](const std::string &str) -> sptr<IInterface> { return Float::Parse(str); };236 auto func = [](const std::string &str) -> sptr<IInterface> { return Float::Parse(str); };
217- ParseElement(array, func, values, size);237+ if (!ParseElement(array, func, values, size)) {
238+ return nullptr;
239+ }
218 }240 }
219 return array;241 return array;
220}242}
@@ -224,7 +246,9 @@ sptr<IArray> Array::ParseDouble(const std::string &values, long size)
224 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IDouble);246 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IDouble);
225 if (array != nullptr) {247 if (array != nullptr) {
226 auto func = [](const std::string &str) -> sptr<IInterface> { return Double::Parse(str); };248 auto func = [](const std::string &str) -> sptr<IInterface> { return Double::Parse(str); };
227- ParseElement(array, func, values, size);249+ if (!ParseElement(array, func, values, size)) {
250+ return nullptr;
251+ }
228 }252 }
229 return array;253 return array;
230}254}
@@ -233,7 +257,9 @@ sptr<IArray> Array::ParseChar(const std::string &values, long size)
233 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IChar);257 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IChar);
234 if (array != nullptr) {258 if (array != nullptr) {
235 auto func = [](const std::string &str) -> sptr<IInterface> { return Char::Parse(str); };259 auto func = [](const std::string &str) -> sptr<IInterface> { return Char::Parse(str); };
236- ParseElement(array, func, values, size);260+ if (!ParseElement(array, func, values, size)) {
261+ return nullptr;
262+ }
237 }263 }
238 return array;264 return array;
239}265}
@@ -242,7 +268,9 @@ sptr<IArray> Array::ParseArray(const std::string &values, long size)
242 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IArray);268 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IArray);
243 if (array != nullptr) {269 if (array != nullptr) {
244 auto func = [](const std::string &str) -> sptr<IInterface> { return Array::Parse(str); };270 auto func = [](const std::string &str) -> sptr<IInterface> { return Array::Parse(str); };
245- ParseElement(array, func, values, size);271+ if (!ParseElement(array, func, values, size)) {
272+ return nullptr;
273+ }
246 }274 }
247 return array;275 return array;
248}276}
@@ -252,7 +280,9 @@ sptr<IArray> Array::ParseWantParams(const std::string &values, long size)
252 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IWantParams);280 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IWantParams);
253 if (array != nullptr) {281 if (array != nullptr) {
254 auto func = [](const std::string &str) -> sptr<IInterface> { return WantParamWrapper::Parse(str); };282 auto func = [](const std::string &str) -> sptr<IInterface> { return WantParamWrapper::Parse(str); };
255- ParseElement(array, func, values, size);283+ if (!ParseElement(array, func, values, size)) {
284+ return nullptr;
285+ }
256 }286 }
257 return array;287 return array;
258}288}
@@ -314,13 +344,13 @@ sptr<IArray> Array::Parse(const std::string &arrayStr) /* [in] */
314 return nullptr;344 return nullptr;
315}345}
316 346 
317-void Array::ParseElement(IArray *array, /* [in] */347+bool Array::ParseElement(IArray *array, /* [in] */
318 std::function<sptr<IInterface>(std::string &)> func, /* [in] */348 std::function<sptr<IInterface>(std::string &)> func, /* [in] */
319 const std::string &values, /* [in] */349 const std::string &values, /* [in] */
320 long size) /* [in] */350 long size) /* [in] */
321{351{
322 if (array == nullptr) {352 if (array == nullptr) {
323- return;353+ return false;
324 }354 }
325 355 
326 std::size_t beginIdx = 0;356 std::size_t beginIdx = 0;
@@ -338,8 +368,13 @@ void Array::ParseElement(IArray *array, /* [in] */
338 } else {368 } else {
339 valueStr = values.substr(beginIdx, values.length() - beginIdx);369 valueStr = values.substr(beginIdx, values.length() - beginIdx);
340 }370 }
341- array->Set(i, func(valueStr));371+ auto element = func(valueStr);
372+ if (element == nullptr) {
373+ return false;
374+ }
375+ array->Set(i, element);
342 }376 }
377+ return true;
343}378}
344 379 
345bool Array::IsBooleanArray(IArray *array) /* [in] */380bool Array::IsBooleanArray(IArray *array) /* [in] */
@@ -223,5 +223,41 @@ HWTEST_F(AAfWKZcharWrapperTest, ZcharWrapperTest_GetCharInternal_001, TestSize.L
223 zcharValue.GetCharInternal(cur, size);223 zcharValue.GetCharInternal(cur, size);
224 EXPECT_EQ(3, size);224 EXPECT_EQ(3, size);
225}225}
226+ 
227+/**
228+ * @tc.number: ZcharWrapperTest_GetCharInternal_002
229+ * @tc.name: GetCharInternal
230+ * @tc.desc: Verify GetCharInternal caps num2Read at 4 for invalid leading byte 0xFF.
231+ * Without the cap, 0xFF would trigger 7 continuation byte reads (OOB + UB shift).
232+ */
233+HWTEST_F(AAfWKZcharWrapperTest, ZcharWrapperTest_GetCharInternal_002, TestSize.Level1)
234+{
235+ zchar value = 0;
236+ Char zcharValue(value);
237+ // 0xFF is never valid in UTF-8. The num2Read < 4 cap limits continuation reads to 3.
238+ unsigned char buf[4] = {0xFF, 0x80, 0x80, 0x80};
239+ unsigned int size = 0;
240+ zcharValue.GetCharInternal(buf, size);
241+ // With cap: size is 4 (not 8). Without cap: undefined behavior (shift > 31 bits).
242+ EXPECT_EQ(4, size);
243+}
244+ 
245+/**
246+ * @tc.number: ZcharWrapperTest_GetCharInternal_003
247+ * @tc.name: GetCharInternal
248+ * @tc.desc: Verify GetCharInternal correctly decodes a valid 4-byte UTF-8 sequence
249+ * (U+1F600 😀 = F0 9F 98 80).
250+ */
251+HWTEST_F(AAfWKZcharWrapperTest, ZcharWrapperTest_GetCharInternal_003, TestSize.Level1)
252+{
253+ zchar value = 0;
254+ Char zcharValue(value);
255+ // U+1F600 😀 in UTF-8: F0 9F 98 80
256+ unsigned char buf[4] = {0xF0, 0x9F, 0x98, 0x80};
257+ unsigned int size = 0;
258+ zchar result = zcharValue.GetCharInternal(buf, size);
259+ EXPECT_EQ(4, size);
260+ EXPECT_EQ(static_cast<zchar>(0x1F600), result);
261+}
226}262}
227}263}
@@ -412,14 +412,14 @@ HWTEST_F(ArrayWrapperBaseTest, AaFwk_Array_Wrapper_Parse_0100, Function | Medium
412 EXPECT_EQ(arrFunction("{Test}"), nullptr);412 EXPECT_EQ(arrFunction("{Test}"), nullptr);
413 EXPECT_NE(arrFunction("C3{1,2,3}"), nullptr);413 EXPECT_NE(arrFunction("C3{1,2,3}"), nullptr);
414 EXPECT_NE(arrFunction("T3{1,2,3}"), nullptr);414 EXPECT_NE(arrFunction("T3{1,2,3}"), nullptr);
415- EXPECT_NE(arrFunction("Z3{1,2,3}"), nullptr);415+ EXPECT_EQ(arrFunction("Z3{1,2,3}"), nullptr);
416 EXPECT_NE(arrFunction("B3{1,2,3}"), nullptr);416 EXPECT_NE(arrFunction("B3{1,2,3}"), nullptr);
417 EXPECT_NE(arrFunction("S3{1,2,3}"), nullptr);417 EXPECT_NE(arrFunction("S3{1,2,3}"), nullptr);
418 EXPECT_NE(arrFunction("I3{1,2,3}"), nullptr);418 EXPECT_NE(arrFunction("I3{1,2,3}"), nullptr);
419 EXPECT_NE(arrFunction("J3{1,2,3}"), nullptr);419 EXPECT_NE(arrFunction("J3{1,2,3}"), nullptr);
420 EXPECT_NE(arrFunction("F3{1,2,3}"), nullptr);420 EXPECT_NE(arrFunction("F3{1,2,3}"), nullptr);
421 EXPECT_NE(arrFunction("D3{1,2,3}"), nullptr);421 EXPECT_NE(arrFunction("D3{1,2,3}"), nullptr);
422- EXPECT_NE(arrFunction("[3{1,2,3}"), nullptr);422+ EXPECT_EQ(arrFunction("[3{1,2,3}"), nullptr);
423 EXPECT_NE(arrFunction("W3{1,2,3}"), nullptr);423 EXPECT_NE(arrFunction("W3{1,2,3}"), nullptr);
424}424}
425}425}
@@ -926,6 +926,53 @@ HWTEST_F(WantParamsBaseTest, AaFwk_WantParams_CompareInterface_1002, Function |
926 EXPECT_TRUE(result);926 EXPECT_TRUE(result);
927}927}
928 928 
929+/**
930+ * @tc.number: AaFwk_WantParams_GetInterfaceByType_InvalidArray_0100
931+ * @tc.name: GetInterfaceByType
932+ * @tc.desc: Verify GetInterfaceByType returns nullptr when array parsing fails
933+ * due to an invalid element that ParseElement rejects.
934+ */
935+HWTEST_F(WantParamsBaseTest, AaFwk_WantParams_GetInterfaceByType_InvalidArray_0100, Function | MediumTest | Level1)
936+{
937+ // "Z3{true,maybe,false}" — "maybe" is not a valid Boolean.
938+ // Boolean::Parse("maybe") returns nullptr, ParseElement detects this,
939+ // ParseBoolean returns nullptr, Array::Parse returns nullptr.
940+ const std::string value = "Z3{true,maybe,false}";
941+ sptr<IInterface> result = WantParams::GetInterfaceByType(WantParams::VALUE_TYPE_ARRAY, value);
942+ EXPECT_TRUE(result == nullptr);
943+}
944+ 
945+/**
946+ * @tc.number: AaFwk_WantParams_GetInterfaceByType_InvalidArray_0200
947+ * @tc.name: GetInterfaceByType
948+ * @tc.desc: Verify GetInterfaceByType returns nullptr for an integer array
949+ * containing a non-integer element.
950+ */
951+HWTEST_F(WantParamsBaseTest, AaFwk_WantParams_GetInterfaceByType_InvalidArray_0200, Function | MediumTest | Level1)
952+{
953+ // "I3{2,abc,4}" — "abc" is not a valid integer.
954+ const std::string value = "I3{2,abc,4}";
955+ sptr<IInterface> result = WantParams::GetInterfaceByType(WantParams::VALUE_TYPE_ARRAY, value);
956+ EXPECT_TRUE(result == nullptr);
957+}
958+ 
959+/**
960+ * @tc.number: AaFwk_WantParams_CompareInterface_InvalidArray_0100
961+ * @tc.name: CompareInterface
962+ * @tc.desc: Verify CompareInterface returns false when both interfaces are nullptr
963+ * (GetInterfaceByType returns nullptr for invalid array, type checks fail).
964+ */
965+HWTEST_F(WantParamsBaseTest, AaFwk_WantParams_CompareInterface_InvalidArray_0100, Function | MediumTest | Level1)
966+{
967+ // Both elements fail to parse → both are nullptr → GetDataType returns VALUE_TYPE_NULL
968+ // VALUE_TYPE_NULL != VALUE_TYPE_ARRAY → CompareInterface returns false
969+ const std::string value = "Z3{true,maybe,false}";
970+ sptr<IInterface> iObj1 = WantParams::GetInterfaceByType(WantParams::VALUE_TYPE_ARRAY, value);
971+ sptr<IInterface> iObj2 = WantParams::GetInterfaceByType(WantParams::VALUE_TYPE_ARRAY, value);
972+ bool result = WantParams::CompareInterface(iObj1, iObj2, WantParams::VALUE_TYPE_ARRAY);
973+ EXPECT_FALSE(result);
974+}
975+ 
929/**976/**
930 * @tc.number: AaFwk_WantParams_WriteArrayToParcelString_0100977 * @tc.number: AaFwk_WantParams_WriteArrayToParcelString_0100
931 * @tc.name: WriteArrayToParcelString978 * @tc.name: WriteArrayToParcelString
@@ -22,6 +22,7 @@
22#include "float_wrapper.h"22#include "float_wrapper.h"
23#include "long_wrapper.h"23#include "long_wrapper.h"
24#include "array_wrapper.h"24#include "array_wrapper.h"
25+#include "zchar_wrapper.h"
25 26 
26#define private public27#define private public
27#define protected public28#define protected public
@@ -4046,6 +4047,174 @@ HWTEST_F(WantBaseTest, array_test_006, TestSize.Level1)
4046 EXPECT_EQ(arrayObj->ToString(), std::string("I5{}"));4047 EXPECT_EQ(arrayObj->ToString(), std::string("I5{}"));
4047}4048}
4048 4049 
4050+/*
4051+ * Feature: Array
4052+ * Function: Parse
4053+ * SubFunction: NA
4054+ * FunctionPoints: ParseElement rejects null from Boolean::Parse callback
4055+ * EnvConditions: NA
4056+ * CaseDescription: Verify Parse returns nullptr when a Boolean element fails to parse.
4057+ */
4058+HWTEST_F(WantBaseTest, array_test_007, TestSize.Level1)
liuzongze
liuzongzeliuzongze6月25日

TDD已通过

likedislike
4059+{
4060+ // "maybe" is not a valid Boolean, Boolean::Parse returns nullptr,
4061+ // ParseElement detects this and returns false, ParseBoolean propagates nullptr.
4062+ sptr<IArray> arrayObj = Array::Parse("Z3{true,maybe,false}");
4063+ EXPECT_TRUE(arrayObj == nullptr);
4064+}
4065+ 
4066+/*
4067+ * Feature: Array
4068+ * Function: Parse
4069+ * SubFunction: NA
4070+ * FunctionPoints: ParseElement rejects null from Integer::Parse callback
4071+ * EnvConditions: NA
4072+ * CaseDescription: Verify Parse returns nullptr when an Integer element fails to parse.
4073+ */
4074+HWTEST_F(WantBaseTest, array_test_008, TestSize.Level1)
4075+{
4076+ // "abc" is not a valid integer, Integer::Parse returns nullptr,
4077+ // ParseElement detects this and returns false, ParseInteger propagates nullptr.
4078+ sptr<IArray> arrayObj = Array::Parse("I3{2,abc,4}");
4079+ EXPECT_TRUE(arrayObj == nullptr);
4080+}
4081+ 
4082+/*
4083+ * Feature: Array
4084+ * Function: Parse
4085+ * SubFunction: NA
4086+ * FunctionPoints: ParseElement rejects null from Float::Parse callback
4087+ * EnvConditions: NA
4088+ * CaseDescription: Verify Parse returns nullptr when a Float element fails to parse.
4089+ */
4090+HWTEST_F(WantBaseTest, array_test_009, TestSize.Level1)
4091+{
4092+ // "notanum" is not a valid float, Float::Parse returns nullptr,
4093+ // ParseElement detects this and returns false, ParseFloat propagates nullptr.
4094+ sptr<IArray> arrayObj = Array::Parse("F3{1.5,notanum,3.0}");
4095+ EXPECT_TRUE(arrayObj == nullptr);
4096+}
4097+ 
4098+/*
4099+ * Feature: Array
4100+ * Function: Parse
4101+ * SubFunction: NA
4102+ * FunctionPoints: ParseElement rejects null from Byte::Parse callback
4103+ * EnvConditions: NA
4104+ * CaseDescription: Verify Parse returns nullptr when a Byte element fails to parse.
4105+ */
4106+HWTEST_F(WantBaseTest, array_test_010, TestSize.Level1)
4107+{
4108+ // "" (empty string) is not a valid byte, Byte::Parse returns nullptr,
4109+ // ParseElement detects this and returns false, ParseByte propagates nullptr.
4110+ sptr<IArray> arrayObj = Array::Parse("B3{1,,3}");
4111+ EXPECT_TRUE(arrayObj == nullptr);
4112+}
4113+ 
4114+/*
4115+ * Feature: Array
4116+ * Function: Equals
4117+ * SubFunction: NA
4118+ * FunctionPoints: Equals with null elements (defense-in-depth)
4119+ * EnvConditions: NA
4120+ * CaseDescription: Verify Equals treats both-null elements as equal (no crash).
4121+ */
4122+HWTEST_F(WantBaseTest, array_test_011, TestSize.Level1)
4123+{
4124+ // Two arrays where the same index is null (unset) in both:
4125+ // null == null → continue (treated as equal)
4126+ sptr<IArray> arrayObj1 = new Array(2, g_IID_IInteger);
4127+ arrayObj1->Set(0, Integer::Box(1));
4128+ // arrayObj1 index 1 is still nullptr (unset)
4129+ 
4130+ sptr<IArray> arrayObj2 = new Array(2, g_IID_IInteger);
4131+ arrayObj2->Set(0, Integer::Box(1));
4132+ // arrayObj2 index 1 is still nullptr (unset)
4133+ 
4134+ EXPECT_TRUE(Object::Equals(*(arrayObj1.GetRefPtr()), *(arrayObj2.GetRefPtr())));
4135+}
4136+ 
4137+/*
4138+ * Feature: Array
4139+ * Function: Equals
4140+ * SubFunction: NA
4141+ * FunctionPoints: Equals with null vs non-null elements (defense-in-depth)
4142+ * EnvConditions: NA
4143+ * CaseDescription: Verify Equals handles null vs non-null safely — not equal, no crash.
4144+ */
4145+HWTEST_F(WantBaseTest, array_test_012, TestSize.Level1)
4146+{
4147+ // One array has an element set, the other has nullptr at same index:
4148+ // null != value → return false
4149+ sptr<IArray> arrayObj1 = new Array(2, g_IID_IInteger);
4150+ arrayObj1->Set(0, Integer::Box(1));
4151+ arrayObj1->Set(1, Integer::Box(2));
4152+ 
4153+ sptr<IArray> arrayObj2 = new Array(2, g_IID_IInteger);
4154+ arrayObj2->Set(0, Integer::Box(1));
4155+ // arrayObj2 index 1 is nullptr (unset)
4156+ 
4157+ EXPECT_FALSE(Object::Equals(*(arrayObj1.GetRefPtr()), *(arrayObj2.GetRefPtr())));
4158+}
4159+ 
4160+/*
4161+ * Feature: Array
4162+ * Function: Parse
4163+ * SubFunction: NA
4164+ * FunctionPoints: ParseElement with valid Boolean array still succeeds
4165+ * EnvConditions: NA
4166+ * CaseDescription: Verify a fully valid Boolean array still parses correctly after fix.
4167+ */
4168+HWTEST_F(WantBaseTest, array_test_013, TestSize.Level1)
4169+{
4170+ sptr<IArray> arrayObj = Array::Parse("Z3{true,false,true}");
4171+ EXPECT_TRUE(arrayObj != nullptr);
4172+ sptr<IInterface> valueObj;
4173+ arrayObj->Get(0, valueObj);
4174+ EXPECT_EQ(Boolean::Unbox(IBoolean::Query(valueObj)), true);
4175+ arrayObj->Get(1, valueObj);
4176+ EXPECT_EQ(Boolean::Unbox(IBoolean::Query(valueObj)), false);
4177+ arrayObj->Get(2, valueObj);
4178+ EXPECT_EQ(Boolean::Unbox(IBoolean::Query(valueObj)), true);
4179+}
4180+ 
4181+/*
4182+ * Feature: Array
4183+ * Function: Parse
4184+ * SubFunction: NA
4185+ * FunctionPoints: ParseElement with valid Char array still succeeds
4186+ * EnvConditions: NA
4187+ * CaseDescription: Verify Char array (never returns null from callback) still parses correctly.
4188+ */
4189+HWTEST_F(WantBaseTest, array_test_014, TestSize.Level1)
4190+{
4191+ sptr<IArray> arrayObj = Array::Parse("C3{a,b,c}");
4192+ EXPECT_TRUE(arrayObj != nullptr);
4193+ sptr<IInterface> valueObj;
4194+ arrayObj->Get(0, valueObj);
4195+ EXPECT_EQ(Char::Unbox(IChar::Query(valueObj)), U'a');
4196+ arrayObj->Get(1, valueObj);
4197+ EXPECT_EQ(Char::Unbox(IChar::Query(valueObj)), U'b');
4198+ arrayObj->Get(2, valueObj);
4199+ EXPECT_EQ(Char::Unbox(IChar::Query(valueObj)), U'c');
4200+}
4201+ 
4202+/*
4203+ * Feature: Array
4204+ * Function: Parse
4205+ * SubFunction: NA
4206+ * FunctionPoints: Parse with empty values string returns nullptr
4207+ * EnvConditions: NA
4208+ * CaseDescription: Verify an array with empty values string fails to parse
4209+ * (empty string is an invalid element for all numeric/boolean types).
4210+ */
4211+HWTEST_F(WantBaseTest, array_test_015, TestSize.Level1)
4212+{
4213+ // size=1 but values string is empty
4214+ sptr<IArray> arrayObj = Array::Parse("I1{}");
4215+ EXPECT_TRUE(arrayObj == nullptr);
4216+}
4217+ 
4049/**4218/**
4050 * @tc.number: DumpInfo_test_0014219 * @tc.number: DumpInfo_test_001
4051 * @tc.name: DumpInfo4220 * @tc.name: DumpInfo