@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.
Files changed (70) hide show
  1. package/README.md +169 -0
  2. package/SKILL.md +518 -0
  3. package/bin/install.js +165 -0
  4. package/config/rules.yaml +445 -0
  5. package/config/whitelist.yaml +52 -0
  6. package/package.json +40 -0
  7. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_001.md +275 -0
  8. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_002.md +273 -0
  9. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_003.md +305 -0
  10. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_004.md +350 -0
  11. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_005.md +301 -0
  12. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_006.md +320 -0
  13. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_007.md +432 -0
  14. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_008.md +394 -0
  15. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_009.md +425 -0
  16. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_010.md +472 -0
  17. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_011.md +204 -0
  18. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_012.md +210 -0
  19. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_013.md +226 -0
  20. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_014.md +222 -0
  21. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_015.md +256 -0
  22. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_016.md +269 -0
  23. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_017.md +222 -0
  24. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_018.md +336 -0
  25. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_001.md +414 -0
  26. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_002.md +335 -0
  27. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_003.md +284 -0
  28. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_004.md +313 -0
  29. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_005.md +364 -0
  30. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_001.md +142 -0
  31. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_002.md +222 -0
  32. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_003.md +383 -0
  33. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_001.md +258 -0
  34. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_002.md +131 -0
  35. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_003.md +220 -0
  36. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_004.md +224 -0
  37. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_005.md +250 -0
  38. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_006.md +153 -0
  39. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_007.md +169 -0
  40. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_008.md +153 -0
  41. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_009.md +144 -0
  42. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_010.md +152 -0
  43. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_011.md +221 -0
  44. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_012.md +318 -0
  45. package/references/InitializationOrder/StabilityCodeReview_InitializationOrder_001.md +411 -0
  46. package/references/Lifecycle/StabilityCodeReview_Lifecycle_001.md +255 -0
  47. package/references/Lifecycle/StabilityCodeReview_Lifecycle_002.md +177 -0
  48. package/references/MemoryStability/StabilityCodeReview_MemoryStability_001.md +332 -0
  49. package/references/MemoryStability/StabilityCodeReview_MemoryStability_002.md +261 -0
  50. package/references/MemoryStability/StabilityCodeReview_MemoryStability_003.md +428 -0
  51. package/references/MemoryStability/StabilityCodeReview_MemoryStability_004.md +400 -0
  52. package/references/MemoryStability/StabilityCodeReview_MemoryStability_005.md +364 -0
  53. package/references/MemoryStability/StabilityCodeReview_MemoryStability_006.md +359 -0
  54. package/references/MemoryStability/StabilityCodeReview_MemoryStability_007.md +279 -0
  55. package/references/PROBLEM_TEMPLATE.md +65 -0
  56. package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_001.md +380 -0
  57. package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_002.md +437 -0
  58. package/references/REPORT_TEMPLATE.csv +5 -0
  59. package/references/REPORT_TEMPLATE.md +132 -0
  60. package/references/RULE_DEVELOPMENT_GUIDE.md +711 -0
  61. package/references/RULE_INDEX.md +101 -0
  62. package/references/RULE_TEMPLATE.md +192 -0
  63. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_001.md +334 -0
  64. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_002.md +425 -0
  65. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_003.md +420 -0
  66. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_004.md +409 -0
  67. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_005.md +445 -0
  68. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_006.md +384 -0
  69. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_007.md +395 -0
  70. package/scripts/add-rule.py +423 -0
@@ -0,0 +1,256 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_BoundaryCondition_015"
3
+ name: "数组下标的计算应避免整数回绕导致内存越界访问"
4
+ category: "边界条件"
5
+ severity: "HIGH"
6
+ language: ["cpp", "c++"]
7
+ author: "OH-Department7 Stability Team"
8
+ ---
9
+
10
+ # 数组下标的计算应避免整数回绕导致内存越界访问
11
+
12
+ ## 问题描述
13
+
14
+ 数组下标计算时若存在整数溢出或回绕,可能导致产生非法下标值,造成内存越界访问。无符号整数减法回绕尤其危险,可能产生超大值导致严重的内存安全问题。
15
+
16
+ ## 检测示例
17
+
18
+ ### ❌ 问题代码
19
+
20
+ ```cpp
21
+ // 错误示例1:无符号整数减法回绕
22
+ void ProcessRange(uint32_t start, uint32_t end)
23
+ {
24
+ uint32_t size = end - start; // 危险:若end < start,回绕到超大值
25
+ char* buffer = new char[size];
26
+ memcpy(buffer, data, size); // 可能分配超大内存或越界
27
+ }
28
+
29
+ // 错误示例2:乘法溢出作为下标
30
+ void AllocateMatrix(int width, int height)
31
+ {
32
+ int index = width * height; // 危险:可能溢出
33
+ buffer[index] = value; // 可能越界访问
34
+ }
35
+
36
+ // 错误示例3:加法溢出作为下标
37
+ void AccessBuffer(int base, int offset)
38
+ {
39
+ int index = base + offset; // 危险:可能溢出
40
+ array[index] = data; // 可能越界
41
+ }
42
+
43
+ // 错误示例4:复杂表达式下标
44
+ void ProcessBuffer(int a, int b, int c)
45
+ {
46
+ int idx = a * b + c; // 危险:多次运算可能溢出
47
+ buffer[idx] = value;
48
+ }
49
+
50
+ // 错误示例5:无符号减法用于数组访问
51
+ void CopyItems(uint32_t count, uint32_t start)
52
+ {
53
+ for (uint32_t i = 0; i < count; i++) {
54
+ uint32_t idx = start - 1 + i; // 危险:start=0时回绕
55
+ array[idx] = items[i];
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### ✅ 修复方案
61
+
62
+ ```cpp
63
+ // 正确示例1:检查无符号减法
64
+ void ProcessRange(uint32_t start, uint32_t end)
65
+ {
66
+ if (end < start) {
67
+ LOGE("Invalid range: end < start");
68
+ return;
69
+ }
70
+ uint32_t size = end - start;
71
+ if (size > MAX_BUFFER_SIZE) {
72
+ LOGE("Size too large: %u", size);
73
+ return;
74
+ }
75
+ char* buffer = new char[size];
76
+ memcpy(buffer, data, size);
77
+ }
78
+
79
+ // 正确示例2:安全乘法
80
+ void AllocateMatrix(int width, int height)
81
+ {
82
+ if (width <= 0 || height <= 0) {
83
+ LOGE("Invalid dimensions");
84
+ return;
85
+ }
86
+ if (width > INT_MAX / height) {
87
+ LOGE("Multiplication overflow");
88
+ return;
89
+ }
90
+ int index = width * height;
91
+ if (index >= buffer_size) {
92
+ LOGE("Index out of range");
93
+ return;
94
+ }
95
+ buffer[index] = value;
96
+ }
97
+
98
+ // 正确示例3:安全加法
99
+ void AccessBuffer(int base, int offset)
100
+ {
101
+ if (offset > 0 && base > INT_MAX - offset) {
102
+ LOGE("Addition overflow");
103
+ return;
104
+ }
105
+ if (offset < 0 && base < INT_MIN - offset) {
106
+ LOGE("Addition underflow");
107
+ return;
108
+ }
109
+ int index = base + offset;
110
+ if (index < 0 || index >= array_size) {
111
+ LOGE("Index out of range: %d", index);
112
+ return;
113
+ }
114
+ array[index] = data;
115
+ }
116
+
117
+ // 正确示例4:使用64位中间值
118
+ void ProcessBuffer(int a, int b, int c)
119
+ {
120
+ int64_t idx = static_cast<int64_t>(a) * b + c;
121
+ if (idx < 0 || idx >= buffer_size) {
122
+ LOGE("Index out of range: %lld", idx);
123
+ return;
124
+ }
125
+ buffer[static_cast<size_t>(idx)] = value;
126
+ }
127
+
128
+ // 正确示例5:安全的无符号运算
129
+ void CopyItems(uint32_t count, uint32_t start)
130
+ {
131
+ if (start == 0) {
132
+ LOGE("Invalid start index");
133
+ return;
134
+ }
135
+ for (uint32_t i = 0; i < count; i++) {
136
+ uint32_t idx = start - 1 + i;
137
+ if (idx >= array_size) {
138
+ LOGE("Index out of range: %u", idx);
139
+ return;
140
+ }
141
+ array[idx] = items[i];
142
+ }
143
+ }
144
+ ```
145
+
146
+ ## 检测范围
147
+
148
+ 检查以下下标计算模式:
149
+
150
+ - `array[a + b]` - 加法下标
151
+ - `array[a - b]` - 减法下标(尤其无符号)
152
+ - `array[a * b]` - 乘法下标
153
+ - `array[a * b + c]` - 复合表达式下标
154
+ - `uint` 类型减法表达式
155
+
156
+ ## 检测要点
157
+
158
+ 1. 识别数组访问表达式
159
+ 2. 检测下标中是否包含算术运算
160
+ 3. 判断是否为危险的无符号减法
161
+ 4. 检查是否有边界检查
162
+ 5. 检查是否使用了安全运算函数
163
+ 6. 排除NOPROTECT标记的代码
164
+
165
+ ## 风险流分析(RiskFlow)
166
+
167
+ - **RISK_SOURCE**: 数组下标计算表达式
168
+ - **RISK_TYPE**: 整数溢出/回绕
169
+ - **RISK_PATH**: 下标计算溢出 -> 产生非法值 -> 内存越界访问
170
+ - **IMPACT_POINT**: 内存破坏、信息泄露、安全漏洞
171
+
172
+ ## 影响分析(ImpactAnalysis)
173
+
174
+ - **Trigger**: 下标计算结果超出数组范围
175
+ - **Propagation**: 整数回绕产生非法下标值
176
+ - **Consequence**: 越界读写、内存破坏、安全漏洞
177
+ - **Mitigation**: 使用安全整数运算库,添加边界检查
178
+
179
+ ## 误报排除
180
+
181
+ | 场景 | 识别特征 | 处理方式 |
182
+ |------|----------|----------|
183
+ | NOPROTECT 标记 | 有 // NOPROTECT 注释 | 不报 |
184
+ | 已有边界检查 | 存在范围比较、size检查 | 不报 |
185
+ | 使用安全运算 | 使用 SAFE_ADD、SafeMul 等 | 不报 |
186
+ | 第三方库 | 位于 third_party 目录 | 白名单排除 |
187
+ | 测试代码 | 位于 test 目录 | 自动跳过 |
188
+ | 常量下标 | 编译期可计算的常量 | 不报 |
189
+ ## 测试用例
190
+
191
+ ### 触发用例(应该报)
192
+
193
+ ```cpp
194
+ // test_BoundaryCondition_015_trigger.cpp
195
+ void trigger_bad_1(uint32_t start, uint32_t end)
196
+ {
197
+ uint32_t size = end - start; // 应该报:无符号减法可能回绕
198
+ char* buf = new char[size];
199
+ }
200
+
201
+ void trigger_bad_2(int a, int b)
202
+ {
203
+ int idx = a * b; // 应该报:乘法可能溢出
204
+ buffer[idx] = value;
205
+ }
206
+
207
+ void trigger_bad_3(int base, int offset)
208
+ {
209
+ int idx = base + offset; // 应该报:加法可能溢出
210
+ array[idx] = data;
211
+ }
212
+
213
+ void trigger_bad_4(uint32_t count, uint32_t start)
214
+ {
215
+ uint32_t idx = start - 1; // 应该报:无符号减法可能回绕
216
+ array[idx] = 0;
217
+ }
218
+ ```
219
+
220
+ ### 安全用例(不应该报)
221
+
222
+ ```cpp
223
+ // test_BoundaryCondition_015_safe.cpp
224
+ void safe_good_1(uint32_t start, uint32_t end)
225
+ {
226
+ if (end < start) { // 安全:有边界检查
227
+ return;
228
+ }
229
+ uint32_t size = end - start;
230
+ char* buf = new char[size];
231
+ }
232
+
233
+ void safe_good_2(int a, int b)
234
+ {
235
+ if (a > 0 && b > 0 && a <= INT_MAX / b) { // 安全:有溢出检查
236
+ int idx = a * b;
237
+ if (idx < buffer_size) {
238
+ buffer[idx] = value;
239
+ }
240
+ }
241
+ }
242
+
243
+ void safe_good_3(int base, int offset)
244
+ {
245
+ int idx = SafeAdd(base, offset); // 安全:使用安全运算函数
246
+ if (idx >= 0 && idx < array_size) {
247
+ array[idx] = data;
248
+ }
249
+ }
250
+
251
+ // NOPROTECT: 下标已确认在范围内
252
+ void noprotect_case(int idx)
253
+ {
254
+ buffer[idx] = value; // 已确认idx合法
255
+ }
256
+ ```
@@ -0,0 +1,269 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_BoundaryCondition_016"
3
+ name: "内存操作越界风险"
4
+ category: "边界条件"
5
+ severity: "CRITICAL"
6
+ language: ["cpp", "c++"]
7
+ author: "OH-Department7 Stability Team"
8
+ ---
9
+
10
+ # 内存操作越界风险
11
+
12
+ ## 问题描述
13
+
14
+ 代码在执行内存拷贝(memcpy / memmove / std::copy)、指针偏移(base + offset)、数组索引(arr[idx])或类似内存操作时,长度、偏移或下标参数来自外部可控输入(文件、网络、IPC、库返回值),未校验其是否在目标缓冲区的有效范围内。攻击者构造特定输入可触发越界读/写,造成内存破坏或任意地址写。
15
+
16
+ ## 检测示例
17
+
18
+ ### ❌ 问题代码
19
+
20
+ ```cpp
21
+ // 场景1:memcpy长度来自外部未校验
22
+ void CopyData(const char* source, size_t length)
23
+ {
24
+ char buffer[1024];
25
+ memcpy(buffer, source, length); // 错误:length未校验,可能超过buffer大小
26
+ }
27
+
28
+ // 场景2:指针偏移未校验范围
29
+ void AccessOffset(Data* base, int offset)
30
+ {
31
+ Data* target = base + offset; // 错误:offset未校验,可能越界
32
+ target->value = 100;
33
+ }
34
+
35
+ // 场景3:数组下标来自Parcel未校验
36
+ void ProcessParcel(Parcel* parcel)
37
+ {
38
+ int index = parcel->ReadInt32(); // 来自Parcel,不可信
39
+ int arr[100];
40
+ arr[index] = 100; // 错误:index未校验,可能越界访问
41
+ }
42
+
43
+ // 场景4:网络数据长度未校验
44
+ void ProcessNetworkPacket(const char* packet, size_t packetSize)
45
+ {
46
+ char* buffer = new char[1024];
47
+ memcpy(buffer, packet, packetSize); // 错误:packetSize可能超过1024
48
+ delete[] buffer;
49
+ }
50
+
51
+ // 场景5:std::copy长度未校验
52
+ void CopyVector(const std::vector<int>& source, size_t count)
53
+ {
54
+ int dest[100];
55
+ std::copy(source.begin(), source.begin() + count, dest); // 错误:count未校验
56
+ }
57
+
58
+ // 场景6:realloc后使用原大小访问
59
+ void ResizeAndAccess(char* buffer, int oldSize, int newSize)
60
+ {
61
+ char* newBuffer = (char*)realloc(buffer, newSize);
62
+ if (newBuffer == nullptr) {
63
+ return;
64
+ }
65
+
66
+ for (int i = 0; i < oldSize; i++) { // 错误:使用oldSize访问,但缓冲区可能已缩小
67
+ newBuffer[i] = '\0';
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### ✅ 修复方案
73
+
74
+ ```cpp
75
+ // 修复场景1:memcpy前校验长度
76
+ void CopyData(const char* source, size_t length)
77
+ {
78
+ char buffer[1024];
79
+ if (length > sizeof(buffer)) { // 正确:校验长度不超过缓冲区大小
80
+ LOGE("length exceeds buffer size");
81
+ return;
82
+ }
83
+ memcpy(buffer, source, length);
84
+ }
85
+
86
+ // 修复场景2:指针偏移前校验范围
87
+ void AccessOffset(Data* base, int offset, size_t arraySize)
88
+ {
89
+ if (offset < 0 || offset >= arraySize) { // 正确:校验offset在有效范围内
90
+ LOGE("invalid offset");
91
+ return;
92
+ }
93
+ Data* target = base + offset;
94
+ target->value = 100;
95
+ }
96
+
97
+ // 修复场景3:Parcel数据校验后使用
98
+ void ProcessParcel(Parcel* parcel)
99
+ {
100
+ int index = parcel->ReadInt32();
101
+ int arr[100];
102
+ if (index < 0 || index >= 100) { // 正确:校验index在数组范围内
103
+ LOGE("invalid index");
104
+ return;
105
+ }
106
+ arr[index] = 100;
107
+ }
108
+
109
+ // 修复场景4:网络数据大小校验
110
+ void ProcessNetworkPacket(const char* packet, size_t packetSize)
111
+ {
112
+ const size_t MAX_PACKET_SIZE = 1024;
113
+ if (packetSize > MAX_PACKET_SIZE) { // 正确:校验packetSize不超过限制
114
+ LOGE("packet too large");
115
+ return;
116
+ }
117
+
118
+ char* buffer = new char[packetSize]; // 使用packetSize分配
119
+ memcpy(buffer, packet, packetSize);
120
+ delete[] buffer;
121
+ }
122
+
123
+ // 修复场景5:std::copy前校验count
124
+ void CopyVector(const std::vector<int>& source, size_t count)
125
+ {
126
+ int dest[100];
127
+ if (count > source.size() || count > 100) { // 正确:校验count不超过源和目标大小
128
+ LOGE("invalid count");
129
+ return;
130
+ }
131
+ std::copy(source.begin(), source.begin() + count, dest);
132
+ }
133
+
134
+ // 修复场景6:realloc后使用新大小访问
135
+ void ResizeAndAccess(char* buffer, int oldSize, int newSize)
136
+ {
137
+ char* newBuffer = (char*)realloc(buffer, newSize);
138
+ if (newBuffer == nullptr) {
139
+ free(buffer);
140
+ return;
141
+ }
142
+
143
+ int accessSize = (newSize < oldSize) ? newSize : oldSize; // 正确:使用安全的访问大小
144
+ for (int i = 0; i < accessSize; i++) {
145
+ newBuffer[i] = '\0';
146
+ }
147
+ }
148
+ ```
149
+
150
+ ## 检测范围
151
+
152
+ 检查以下模式:
153
+
154
+ - `memcpy(dest, src, len)` - len来自外部输入未校验
155
+ - `memmove(dest, src, len)` - len来自外部输入未校验
156
+ - `std::copy(begin, end, dest)` - end与begin的距离来自外部输入
157
+ - `指针 + offset` - offset来自外部输入未校验
158
+ - `数组[index]` - index来自Parcel/网络/文件等外部输入
159
+ - `memset(ptr, value, len)` - len来自外部输入未校验
160
+ - `realloc(ptr, size)` - size来自外部输入未校验
161
+
162
+ ## 检测要点
163
+
164
+ 1. 识别内存操作函数调用(memcpy、memmove、std::copy等)
165
+ 2. 检查长度/偏移/下标参数的来源(Parcel、网络、文件、参数)
166
+ 3. 判断是否在操作前有范围校验(if判断、assert、clamp等)
167
+ 4. 检查是否与缓冲区大小比较
168
+ 5. 排除NOPROTECT标记和已知安全的常量值
169
+
170
+ ## 风险流分析(RiskFlow)
171
+
172
+ - **RISK_SOURCE**:外部可控的长度/偏移/下标参数
173
+ - **RISK_TYPE**:内存越界访问
174
+ - **RISK_PATH**:外部输入恶意构造 → 未校验直接使用 → 越界读写 → 内存破坏
175
+ - **IMPACT_POINT**:程序崩溃、数据损坏、任意地址读写、安全漏洞
176
+
177
+ ## 影响分析(ImpactAnalysis)
178
+
179
+ - **Trigger**:恶意构造的输入值超出缓冲区范围
180
+ - **Propagation**:越界读写相邻内存或任意地址
181
+ - **Consequence**:内存破坏、程序崩溃、潜在任意代码执行
182
+ - **Mitigation**:所有外部输入的长度/偏移/下标必须校验范围
183
+
184
+ ## 误报排除
185
+
186
+ | 场景 | 识别特征 | 处理方式 |
187
+ |------|----------|----------|
188
+ | 常量长度 | length是编译期常量或constexpr | 不报 |
189
+ | 已有校验 | 有if判断或assert校验范围 | 不报 |
190
+ | 使用sizeof | length = sizeof(buffer) | 不报 |
191
+ | 使用容器size | length = vector.size() 且容器大小受控 | 需上下文分析 |
192
+ | NOPROTECT标记 | // NOPROTECT 注释 | 不报 |
193
+ | 测试代码 | 文件名包含 _test.cpp | 白名单排除 |
194
+ ## 测试用例
195
+
196
+ ### 触发用例(应该报)
197
+
198
+ ```cpp
199
+ // test_BoundaryCondition_016_trigger.cpp
200
+ void trigger_bad_1(Parcel* parcel)
201
+ {
202
+ int index = parcel->ReadInt32(); // 应该报:Parcel数据未校验作为数组下标
203
+ int arr[100];
204
+ arr[index] = 100;
205
+ }
206
+
207
+ void trigger_bad_2(const char* data, size_t len)
208
+ {
209
+ char buffer[1024];
210
+ memcpy(buffer, data, len); // 应该报:len未校验,可能越界
211
+ }
212
+
213
+ void trigger_bad_3(Data* base, int offset)
214
+ {
215
+ Data* target = base + offset; // 应该报:offset未校验
216
+ target->value = 100;
217
+ }
218
+
219
+ void trigger_bad_4(const char* packet, size_t packetSize)
220
+ {
221
+ char* buffer = new char[1024];
222
+ memcpy(buffer, packet, packetSize); // 应该报:packetSize未校验
223
+ delete[] buffer;
224
+ }
225
+ ```
226
+
227
+ ### 安全用例(不应该报)
228
+
229
+ ```cpp
230
+ // test_BoundaryCondition_016_safe.cpp
231
+ void safe_good_1(Parcel* parcel)
232
+ {
233
+ int index = parcel->ReadInt32();
234
+ int arr[100];
235
+ if (index >= 0 && index < 100) { // 安全:有范围校验
236
+ arr[index] = 100;
237
+ }
238
+ }
239
+
240
+ void safe_good_2(const char* data, size_t len)
241
+ {
242
+ char buffer[1024];
243
+ if (len <= sizeof(buffer)) { // 安全:有长度校验
244
+ memcpy(buffer, data, len);
245
+ }
246
+ }
247
+
248
+ void safe_good_3(Data* base, int offset, size_t size)
249
+ {
250
+ if (offset >= 0 && offset < size) { // 安全:有偏移校验
251
+ Data* target = base + offset;
252
+ target->value = 100;
253
+ }
254
+ }
255
+
256
+ void safe_good_4()
257
+ {
258
+ char buffer[1024];
259
+ memcpy(buffer, source, 512); // 安全:长度是常量
260
+ }
261
+
262
+ // NOPROTECT: 特殊场景
263
+ void noprotect_case(Parcel* parcel)
264
+ {
265
+ int index = parcel->ReadInt32();
266
+ int arr[100];
267
+ arr[index] = 100; // NOPROTECT标记,不报
268
+ }
269
+ ```