@ohos-graphics/stability-code-review 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -0
- package/SKILL.md +518 -0
- package/bin/install.js +165 -0
- package/config/rules.yaml +445 -0
- package/config/whitelist.yaml +52 -0
- package/package.json +40 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_001.md +275 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_002.md +273 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_003.md +305 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_004.md +350 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_005.md +301 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_006.md +320 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_007.md +432 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_008.md +394 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_009.md +425 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_010.md +472 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_011.md +204 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_012.md +210 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_013.md +226 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_014.md +222 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_015.md +256 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_016.md +269 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_017.md +222 -0
- package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_018.md +336 -0
- package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_001.md +414 -0
- package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_002.md +335 -0
- package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_003.md +284 -0
- package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_004.md +313 -0
- package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_005.md +364 -0
- package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_001.md +142 -0
- package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_002.md +222 -0
- package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_003.md +383 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_001.md +258 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_002.md +131 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_003.md +220 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_004.md +224 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_005.md +250 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_006.md +153 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_007.md +169 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_008.md +153 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_009.md +144 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_010.md +152 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_011.md +221 -0
- package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_012.md +318 -0
- package/references/InitializationOrder/StabilityCodeReview_InitializationOrder_001.md +411 -0
- package/references/Lifecycle/StabilityCodeReview_Lifecycle_001.md +255 -0
- package/references/Lifecycle/StabilityCodeReview_Lifecycle_002.md +177 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_001.md +332 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_002.md +261 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_003.md +428 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_004.md +400 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_005.md +364 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_006.md +359 -0
- package/references/MemoryStability/StabilityCodeReview_MemoryStability_007.md +279 -0
- package/references/PROBLEM_TEMPLATE.md +65 -0
- package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_001.md +380 -0
- package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_002.md +437 -0
- package/references/REPORT_TEMPLATE.csv +5 -0
- package/references/REPORT_TEMPLATE.md +132 -0
- package/references/RULE_DEVELOPMENT_GUIDE.md +711 -0
- package/references/RULE_INDEX.md +101 -0
- package/references/RULE_TEMPLATE.md +192 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_001.md +334 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_002.md +425 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_003.md +420 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_004.md +409 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_005.md +445 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_006.md +384 -0
- package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_007.md +395 -0
- package/scripts/add-rule.py +423 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
---
|
|
2
|
+
rule_id: "StabilityCodeReview_BoundaryCondition_007"
|
|
3
|
+
name: "Parcel序列化和反序列化必须匹配"
|
|
4
|
+
category: "边界条件"
|
|
5
|
+
severity: "HIGH"
|
|
6
|
+
language: ["cpp", "c++"]
|
|
7
|
+
author: "OH-Department7 Stability Team"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Parcel序列化和反序列化必须匹配
|
|
11
|
+
|
|
12
|
+
## 问题描述
|
|
13
|
+
|
|
14
|
+
Parcel的序列化和反序列化必须完全匹配,包括顺序、类型和数量。不匹配的序列化/反序列化会导致数据错误、内存越界读取或程序崩溃。
|
|
15
|
+
|
|
16
|
+
## 检测示例
|
|
17
|
+
|
|
18
|
+
### ❌ 问题代码
|
|
19
|
+
|
|
20
|
+
```cpp
|
|
21
|
+
// 错误示例1:顺序不匹配
|
|
22
|
+
// 序列化
|
|
23
|
+
void WriteData(Parcel& parcel)
|
|
24
|
+
{
|
|
25
|
+
parcel.WriteInt32(count); // 1. 写入count
|
|
26
|
+
parcel.WriteString(name); // 2. 写入name
|
|
27
|
+
parcel.WriteBool(enabled); // 3. 写入enabled
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 反序列化 - 顺序错误
|
|
31
|
+
void ReadData(Parcel& parcel)
|
|
32
|
+
{
|
|
33
|
+
enabled = parcel.ReadBool(); // 错误:先读Bool,但实际是Int32
|
|
34
|
+
name = parcel.ReadString(); // 错误:读取顺序不匹配
|
|
35
|
+
count = parcel.ReadInt32(); // 错误:顺序不匹配
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 错误示例2:类型不匹配
|
|
39
|
+
// 序列化
|
|
40
|
+
void Serialize(Packet& packet)
|
|
41
|
+
{
|
|
42
|
+
parcel.WriteUint32(id);
|
|
43
|
+
parcel.WriteFloat(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 反序列化 - 类型错误
|
|
47
|
+
void Deserialize(Packet& packet)
|
|
48
|
+
{
|
|
49
|
+
id = parcel.ReadInt32(); // 错误:Uint32用Int32读取
|
|
50
|
+
value = parcel.ReadDouble(); // 错误:Float用Double读取
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 错误示例3:数量不匹配(多读)
|
|
54
|
+
// 序列化
|
|
55
|
+
void Save(Parcel& parcel)
|
|
56
|
+
{
|
|
57
|
+
parcel.WriteInt32(a);
|
|
58
|
+
parcel.WriteInt32(b);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 反序列化 - 多读
|
|
62
|
+
void Load(Parcel& parcel)
|
|
63
|
+
{
|
|
64
|
+
a = parcel.ReadInt32();
|
|
65
|
+
b = parcel.ReadInt32();
|
|
66
|
+
c = parcel.ReadInt32(); // 错误:多读了一个,越界读取
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 错误示例4:数量不匹配(少读)
|
|
70
|
+
// 序列化
|
|
71
|
+
void Store(Parcel& parcel)
|
|
72
|
+
{
|
|
73
|
+
parcel.WriteInt32(x);
|
|
74
|
+
parcel.WriteInt32(y);
|
|
75
|
+
parcel.WriteInt32(z);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 反序列化 - 少读
|
|
79
|
+
void Restore(Parcel& parcel)
|
|
80
|
+
{
|
|
81
|
+
x = parcel.ReadInt32();
|
|
82
|
+
y = parcel.ReadInt32();
|
|
83
|
+
// 错误:少读了z,可能导致后续读取错误
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 错误示例5:条件字段不匹配
|
|
87
|
+
// 序列化
|
|
88
|
+
void SerializeData(Parcel& parcel, const Data& data)
|
|
89
|
+
{
|
|
90
|
+
parcel.WriteBool(data.hasExtra);
|
|
91
|
+
parcel.WriteInt32(data.value);
|
|
92
|
+
if (data.hasExtra) {
|
|
93
|
+
parcel.WriteString(data.extra);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 反序列化 - 条件不匹配
|
|
98
|
+
void DeserializeData(Parcel& parcel, Data& data)
|
|
99
|
+
{
|
|
100
|
+
data.hasExtra = parcel.ReadBool();
|
|
101
|
+
data.value = parcel.ReadInt32();
|
|
102
|
+
data.extra = parcel.ReadString(); // 错误:无条件读取,hasExtra为false时越界
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 错误示例6:数组处理不匹配
|
|
106
|
+
// 序列化
|
|
107
|
+
void SerializeArray(Parcel& parcel, const std::vector<int>& arr)
|
|
108
|
+
{
|
|
109
|
+
parcel.WriteUint32(arr.size());
|
|
110
|
+
for (int val : arr) {
|
|
111
|
+
parcel.WriteInt32(val);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 反序列化 - 数量不匹配
|
|
116
|
+
void DeserializeArray(Parcel& parcel, std::vector<int>& arr)
|
|
117
|
+
{
|
|
118
|
+
uint32_t count = parcel.ReadUint32();
|
|
119
|
+
for (uint32_t i = 0; i < count + 1; i++) { // 错误:多读一个
|
|
120
|
+
arr.push_back(parcel.ReadInt32());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 错误示例7:版本兼容问题
|
|
125
|
+
// 旧版本序列化
|
|
126
|
+
void SerializeV1(Parcel& parcel)
|
|
127
|
+
{
|
|
128
|
+
parcel.WriteInt32(version);
|
|
129
|
+
parcel.WriteString(name);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 新版本反序列化 - 期望更多字段
|
|
133
|
+
void DeserializeV2(Parcel& parcel)
|
|
134
|
+
{
|
|
135
|
+
int version = parcel.ReadInt32();
|
|
136
|
+
std::string name = parcel.ReadString();
|
|
137
|
+
std::string extra = parcel.ReadString(); // 错误:V1没有这个字段
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### ✅ 修复方案
|
|
142
|
+
|
|
143
|
+
```cpp
|
|
144
|
+
// 正确示例1:顺序匹配
|
|
145
|
+
// 序列化
|
|
146
|
+
void WriteData(Parcel& parcel)
|
|
147
|
+
{
|
|
148
|
+
parcel.WriteInt32(count);
|
|
149
|
+
parcel.WriteString(name);
|
|
150
|
+
parcel.WriteBool(enabled);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 反序列化 - 顺序正确
|
|
154
|
+
void ReadData(Parcel& parcel)
|
|
155
|
+
{
|
|
156
|
+
count = parcel.ReadInt32(); // 1. 读取count
|
|
157
|
+
name = parcel.ReadString(); // 2. 读取name
|
|
158
|
+
enabled = parcel.ReadBool(); // 3. 读取enabled
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 正确示例2:类型匹配
|
|
162
|
+
// 序列化
|
|
163
|
+
void Serialize(Packet& packet)
|
|
164
|
+
{
|
|
165
|
+
parcel.WriteUint32(id);
|
|
166
|
+
parcel.WriteFloat(value);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 反序列化 - 类型正确
|
|
170
|
+
void Deserialize(Packet& packet)
|
|
171
|
+
{
|
|
172
|
+
id = parcel.ReadUint32(); // 正确:Uint32匹配
|
|
173
|
+
value = parcel.ReadFloat(); // 正确:Float匹配
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// 正确示例3:数量匹配
|
|
177
|
+
// 序列化
|
|
178
|
+
void Save(Parcel& parcel)
|
|
179
|
+
{
|
|
180
|
+
parcel.WriteInt32(a);
|
|
181
|
+
parcel.WriteInt32(b);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 反序列化 - 数量正确
|
|
185
|
+
void Load(Parcel& parcel)
|
|
186
|
+
{
|
|
187
|
+
a = parcel.ReadInt32();
|
|
188
|
+
b = parcel.ReadInt32();
|
|
189
|
+
// 数量完全匹配
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 正确示例4:条件字段匹配
|
|
193
|
+
// 序列化
|
|
194
|
+
void SerializeData(Parcel& parcel, const Data& data)
|
|
195
|
+
{
|
|
196
|
+
parcel.WriteBool(data.hasExtra);
|
|
197
|
+
parcel.WriteInt32(data.value);
|
|
198
|
+
if (data.hasExtra) {
|
|
199
|
+
parcel.WriteString(data.extra);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 反序列化 - 条件匹配
|
|
204
|
+
void DeserializeData(Parcel& parcel, Data& data)
|
|
205
|
+
{
|
|
206
|
+
data.hasExtra = parcel.ReadBool();
|
|
207
|
+
data.value = parcel.ReadInt32();
|
|
208
|
+
if (data.hasExtra) { // 正确:条件匹配
|
|
209
|
+
data.extra = parcel.ReadString();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// 正确示例5:数组处理匹配
|
|
214
|
+
// 序列化
|
|
215
|
+
void SerializeArray(Parcel& parcel, const std::vector<int>& arr)
|
|
216
|
+
{
|
|
217
|
+
parcel.WriteUint32(arr.size());
|
|
218
|
+
for (int val : arr) {
|
|
219
|
+
parcel.WriteInt32(val);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 反序列化 - 数量正确
|
|
224
|
+
void DeserializeArray(Parcel& parcel, std::vector<int>& arr)
|
|
225
|
+
{
|
|
226
|
+
uint32_t count = parcel.ReadUint32();
|
|
227
|
+
if (count > MAX_ARRAY_SIZE) { // 安全检查
|
|
228
|
+
LOGE("Invalid array count");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
for (uint32_t i = 0; i < count; i++) { // 正确:数量匹配
|
|
232
|
+
arr.push_back(parcel.ReadInt32());
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 正确示例6:版本兼容处理
|
|
237
|
+
// 序列化 - 包含版本号
|
|
238
|
+
void SerializeV2(Parcel& parcel)
|
|
239
|
+
{
|
|
240
|
+
parcel.WriteInt32(2); // version
|
|
241
|
+
parcel.WriteString(name);
|
|
242
|
+
parcel.WriteString(extra); // V2新增字段
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 反序列化 - 版本兼容
|
|
246
|
+
void Deserialize(Parcel& parcel)
|
|
247
|
+
{
|
|
248
|
+
int version = parcel.ReadInt32();
|
|
249
|
+
std::string name = parcel.ReadString();
|
|
250
|
+
std::string extra = "";
|
|
251
|
+
if (version >= 2) { // 正确:根据版本处理
|
|
252
|
+
extra = parcel.ReadString();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 正确示例7:使用统一的结构体方法
|
|
257
|
+
struct PacketData {
|
|
258
|
+
int32_t count;
|
|
259
|
+
std::string name;
|
|
260
|
+
bool enabled;
|
|
261
|
+
|
|
262
|
+
void Marshal(Parcel& parcel) const {
|
|
263
|
+
parcel.WriteInt32(count);
|
|
264
|
+
parcel.WriteString(name);
|
|
265
|
+
parcel.WriteBool(enabled);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void Unmarshal(Parcel& parcel) {
|
|
269
|
+
count = parcel.ReadInt32();
|
|
270
|
+
name = parcel.ReadString();
|
|
271
|
+
enabled = parcel.ReadBool();
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// 正确示例8:使用辅助工具确保匹配
|
|
276
|
+
class ParcelHelper {
|
|
277
|
+
public:
|
|
278
|
+
template<typename T>
|
|
279
|
+
static void Write(Parcel& parcel, const T& value) {
|
|
280
|
+
parcel.WriteParcelable(value);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
template<typename T>
|
|
284
|
+
static bool Read(Parcel& parcel, T& value) {
|
|
285
|
+
return parcel.ReadParcelable(&value);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 检测范围
|
|
291
|
+
|
|
292
|
+
检查以下模式:
|
|
293
|
+
|
|
294
|
+
1. 同一类的序列化和反序列化函数
|
|
295
|
+
2. `Write`/`Read`函数对
|
|
296
|
+
3. `Serialize`/`Deserialize`函数对
|
|
297
|
+
4. `Marshal`/`Unmarshal`函数对
|
|
298
|
+
5. `Save`/`Load`函数对
|
|
299
|
+
|
|
300
|
+
## 检测要点
|
|
301
|
+
|
|
302
|
+
1. 识别序列化和反序列化函数对
|
|
303
|
+
2. 比较`Write*`和`Read*`的调用顺序
|
|
304
|
+
3. 比较`Write*`和`Read*`的类型
|
|
305
|
+
4. 比较`Write*`和`Read*`的数量
|
|
306
|
+
5. 检查条件字段的处理是否一致
|
|
307
|
+
6. 排除NOPROTECT标记的代码
|
|
308
|
+
|
|
309
|
+
## 风险流分析(RiskFlow)
|
|
310
|
+
|
|
311
|
+
- **RISK_SOURCE**: 序列化/反序列化函数不匹配
|
|
312
|
+
- **RISK_TYPE**: 数据解析错误
|
|
313
|
+
- **RISK_PATH**: 不匹配操作 -> 数据错误/越界读取 -> 程序崩溃
|
|
314
|
+
- **IMPACT_POINT**: 数据完整性、程序稳定性
|
|
315
|
+
|
|
316
|
+
## 影响分析(ImpactAnalysis)
|
|
317
|
+
|
|
318
|
+
- **Trigger**: 序列化与反序列化不匹配
|
|
319
|
+
- **Propagation**: 数据读取错误导致后续解析失败
|
|
320
|
+
- **Consequence**: 数据损坏、越界读取、程序崩溃
|
|
321
|
+
- **Mitigation**: 确保Write/Read顺序、类型、数量完全匹配
|
|
322
|
+
|
|
323
|
+
## 误报排除
|
|
324
|
+
|
|
325
|
+
| 场景 | 识别特征 | 处理方式 |
|
|
326
|
+
|------|----------|----------|
|
|
327
|
+
| NOPROTECT 标记 | 有 // NOPROTECT 注释 | 不报 |
|
|
328
|
+
| 版本兼容处理 | 有版本号判断逻辑 | 不报 |
|
|
329
|
+
| 条件分支一致 | Write和Read都有相同条件 | 不报 |
|
|
330
|
+
| 第三方库 | 位于 third_party 目录 | 白名单排除 |
|
|
331
|
+
## 测试用例
|
|
332
|
+
|
|
333
|
+
### 触发用例(应该报)
|
|
334
|
+
|
|
335
|
+
```cpp
|
|
336
|
+
// test_BoundaryCondition_007_trigger.cpp
|
|
337
|
+
// 序列化
|
|
338
|
+
void TriggerBad1Write(Parcel& parcel)
|
|
339
|
+
{
|
|
340
|
+
parcel.WriteInt32(count);
|
|
341
|
+
parcel.WriteString(name);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// 反序列化 - 顺序错误
|
|
345
|
+
void TriggerBad1Read(Parcel& parcel)
|
|
346
|
+
{
|
|
347
|
+
name = parcel.ReadString(); // 应该报:顺序不匹配
|
|
348
|
+
count = parcel.ReadInt32();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// 序列化
|
|
352
|
+
void TriggerBad2Write(Parcel& parcel)
|
|
353
|
+
{
|
|
354
|
+
parcel.WriteInt32(a);
|
|
355
|
+
parcel.WriteInt32(b);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// 反序列化 - 多读
|
|
359
|
+
void TriggerBad2Read(Parcel& parcel)
|
|
360
|
+
{
|
|
361
|
+
a = parcel.ReadInt32();
|
|
362
|
+
b = parcel.ReadInt32();
|
|
363
|
+
c = parcel.ReadInt32(); // 应该报:数量不匹配
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// 序列化
|
|
367
|
+
void TriggerBad3Write(Parcel& parcel)
|
|
368
|
+
{
|
|
369
|
+
parcel.WriteBool(hasData);
|
|
370
|
+
if (hasData) {
|
|
371
|
+
parcel.WriteString(data);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// 反序列化 - 条件不匹配
|
|
376
|
+
void TriggerBad3Read(Parcel& parcel)
|
|
377
|
+
{
|
|
378
|
+
hasData = parcel.ReadBool();
|
|
379
|
+
data = parcel.ReadString(); // 应该报:无条件读取
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### 安全用例(不应该报)
|
|
384
|
+
|
|
385
|
+
```cpp
|
|
386
|
+
// test_BoundaryCondition_007_safe.cpp
|
|
387
|
+
// 序列化
|
|
388
|
+
void SafeGood1Write(Parcel& parcel)
|
|
389
|
+
{
|
|
390
|
+
parcel.WriteInt32(count);
|
|
391
|
+
parcel.WriteString(name);
|
|
392
|
+
parcel.WriteBool(enabled);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// 反序列化 - 完全匹配
|
|
396
|
+
void SafeGood1Read(Parcel& parcel)
|
|
397
|
+
{
|
|
398
|
+
count = parcel.ReadInt32();
|
|
399
|
+
name = parcel.ReadString();
|
|
400
|
+
enabled = parcel.ReadBool();
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// 序列化
|
|
404
|
+
void SafeGood2Write(Parcel& parcel)
|
|
405
|
+
{
|
|
406
|
+
parcel.WriteBool(hasData);
|
|
407
|
+
if (hasData) {
|
|
408
|
+
parcel.WriteString(data);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// 反序列化 - 条件匹配
|
|
413
|
+
void SafeGood2Read(Parcel& parcel)
|
|
414
|
+
{
|
|
415
|
+
hasData = parcel.ReadBool();
|
|
416
|
+
if (hasData) { // 安全:条件匹配
|
|
417
|
+
data = parcel.ReadString();
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// NOPROTECT: 特殊处理场景
|
|
422
|
+
void noprotect_write(Parcel& parcel)
|
|
423
|
+
{
|
|
424
|
+
parcel.WriteInt32(a);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
void noprotect_read(Parcel& parcel)
|
|
428
|
+
{
|
|
429
|
+
a = parcel.ReadInt32();
|
|
430
|
+
b = parcel.ReadInt32();
|
|
431
|
+
}
|
|
432
|
+
```
|