@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,411 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_InitializationOrder_001"
3
+ name: "类的数据成员需要显式初始化"
4
+ category: "初始化顺序"
5
+ severity: "MEDIUM"
6
+ language: ["cpp", "c++"]
7
+ author: "OH-Department7 Stability Team"
8
+ ---
9
+
10
+ # 类的数据成员需要显式初始化
11
+
12
+ ## 问题描述
13
+
14
+ 类的数据成员如果没有显式初始化,且该类型没有默认构造函数,可能导致未定义行为或程序崩溃。即使是POD类型(如int、指针等),不显式初始化也会导致成员值不确定,在后续使用时可能产生不可预期的结果,严重影响系统稳定性。
15
+
16
+ ## 检测示例
17
+
18
+ ### ❌ 问题代码
19
+
20
+ ```cpp
21
+ // 场景1:类成员未显式初始化(POD类型)
22
+ class UserInfo {
23
+ public:
24
+ int userId; // 未初始化
25
+ int age; // 未初始化
26
+ char* name; // 未初始化
27
+ bool isActive; // 未初始化
28
+
29
+ void Print() {
30
+ printf("userId: %d, age: %d\n", userId, age); // 未定义行为
31
+ }
32
+ };
33
+
34
+ // 场景2:类成员未显式初始化(无默认构造函数的类型)
35
+ class Config {
36
+ public:
37
+ std::string serverUrl; // 有默认构造函数,可以不初始化
38
+ int port; // 未初始化
39
+ bool enabled; // 未初始化
40
+ Logger* logger; // 未初始化
41
+
42
+ void Connect() {
43
+ if (enabled) { // enabled值不确定
44
+ ConnectToServer(serverUrl.c_str(), port); // port值不确定
45
+ }
46
+ }
47
+ };
48
+
49
+ // 场景3:结构体成员未初始化
50
+ struct NetworkConfig {
51
+ int timeout; // 未初始化
52
+ int retryCount; // 未初始化
53
+ char* proxyHost; // 未初始化
54
+ int proxyPort; // 未初始化
55
+ };
56
+
57
+ NetworkConfig config; // 所有成员值不确定
58
+
59
+ // 场景4:嵌套类成员未初始化
60
+ class Service {
61
+ class InnerConfig {
62
+ public:
63
+ int maxConnections; // 未初始化
64
+ int timeout; // 未初始化
65
+ };
66
+
67
+ InnerConfig innerConfig; // 内部类成员未初始化
68
+ int requestId; // 未初始化
69
+
70
+ public:
71
+ void Process() {
72
+ for (int i = 0; i < innerConfig.maxConnections; i++) { // 未定义行为
73
+ // ...
74
+ }
75
+ }
76
+ };
77
+
78
+ // 场景5:类数组未初始化
79
+ class DataBuffer {
80
+ int buffer[1024]; // 数组未初始化
81
+ int count; // 未初始化
82
+
83
+ public:
84
+ int GetCount() { return count; } // 未定义行为
85
+ };
86
+ ```
87
+
88
+ ### ✅ 修复方案
89
+
90
+ ```cpp
91
+ // 修复场景1:类成员显式初始化(构造函数初始化列表)
92
+ class UserInfo {
93
+ public:
94
+ int userId;
95
+ int age;
96
+ char* name;
97
+ bool isActive;
98
+
99
+ UserInfo() : userId(0), age(0), name(nullptr), isActive(false) {}
100
+
101
+ void Print() {
102
+ printf("userId: %d, age: %d\n", userId, age); // 安全
103
+ }
104
+ };
105
+
106
+ // 修复场景2:类成员显式初始化(类内初始化)
107
+ class Config {
108
+ public:
109
+ std::string serverUrl;
110
+ int port = 8080; // C++11 类内初始化
111
+ bool enabled = false; // C++11 类内初始化
112
+ Logger* logger = nullptr; // C++11 类内初始化
113
+
114
+ void Connect() {
115
+ if (enabled) {
116
+ ConnectToServer(serverUrl.c_str(), port); // 安全
117
+ }
118
+ }
119
+ };
120
+
121
+ // 修复场景3:结构体成员初始化
122
+ struct NetworkConfig {
123
+ int timeout = 30000; // 默认值
124
+ int retryCount = 3; // 默认值
125
+ char* proxyHost = nullptr; // 默认值
126
+ int proxyPort = 0; // 默认值
127
+ };
128
+
129
+ NetworkConfig config; // 所有成员有确定值
130
+
131
+ // 修复场景4:嵌套类成员初始化
132
+ class Service {
133
+ class InnerConfig {
134
+ public:
135
+ int maxConnections = 100; // 默认值
136
+ int timeout = 5000; // 默认值
137
+ };
138
+
139
+ InnerConfig innerConfig;
140
+ int requestId = 0;
141
+
142
+ public:
143
+ void Process() {
144
+ for (int i = 0; i < innerConfig.maxConnections; i++) { // 安全
145
+ // ...
146
+ }
147
+ }
148
+ };
149
+
150
+ // 修复场景5:类数组初始化
151
+ class DataBuffer {
152
+ int buffer[1024] = {0}; // 数组初始化为0
153
+ int count = 0;
154
+
155
+ public:
156
+ int GetCount() { return count; } // 安全
157
+ };
158
+
159
+ // 修复场景6:使用默认构造函数
160
+ class SafeConfig {
161
+ public:
162
+ std::string serverUrl; // 有默认构造函数
163
+ std::vector<int> ports; // 有默认构造函数
164
+ std::map<int, std::string> data; // 有默认构造函数
165
+
166
+ // 这些类型有默认构造函数,无需显式初始化
167
+ };
168
+
169
+ // 修复场景7:构造函数体内赋值
170
+ class LegacyConfig {
171
+ public:
172
+ int port;
173
+ bool enabled;
174
+
175
+ LegacyConfig() {
176
+ port = 8080; // 构造函数体内赋值
177
+ enabled = false; // 构造函数体内赋值
178
+ }
179
+ };
180
+ ```
181
+
182
+ ## 检测范围
183
+
184
+ 检查以下模式:
185
+
186
+ - 类/结构体的数据成员声明(非静态成员变量)
187
+ - 未使用类内初始化器(C++11)
188
+ - 未在构造函数初始化列表中初始化
189
+ - 未在构造函数体内赋值
190
+ - 类型没有默认构造函数
191
+
192
+ ## 检测要点
193
+
194
+ 1. 识别类/结构体中的非静态数据成员
195
+ 2. 判断成员类型是否有默认构造函数
196
+ 3. 检查是否存在类内初始化器(`= value`)
197
+ 4. 检查构造函数初始化列表是否包含该成员
198
+ 5. 检查构造函数体内是否对该成员赋值
199
+ 6. 排除已有默认构造函数的类型(如std::string、std::vector等)
200
+
201
+ ### 初始化方式的优先级
202
+
203
+ 三种初始化方式的推荐优先级(从高到低):
204
+
205
+ 1. **类内初始化器(C++11)** - 最高优先级
206
+ - 在成员声明时直接赋值:`int value = 0;`
207
+ - 优点:代码清晰、避免遗漏、支持所有构造函数
208
+ - 推荐用于:简单类型、常量默认值
209
+ - 示例:
210
+ ```cpp
211
+ class Config {
212
+ int port = 8080; // 推荐
213
+ bool enabled = false; // 推荐
214
+ std::string host = ""; // 推荐
215
+ };
216
+ ```
217
+
218
+ 2. **构造函数初始化列表** - 次优先级
219
+ - 在构造函数`: value(arg)`形式
220
+ - 优点:可接收参数、性能最优
221
+ - 推荐用于:需要参数初始化的成员、const成员
222
+ - 示例:
223
+ ```cpp
224
+ class Config {
225
+ int port;
226
+ Config(int p) : port(p) {} // 推荐
227
+ };
228
+ ```
229
+
230
+ 3. **构造函数体内赋值** - 不推荐
231
+ - 在构造函数体`{ value = arg; }`
232
+ - 缺点:先默认初始化再赋值,效率较低
233
+ - 仅用于:无法使用初始化列表的场景
234
+ - 示例:
235
+ ```cpp
236
+ class LegacyConfig {
237
+ int port;
238
+ LegacyConfig(int p) {
239
+ port = p; // 不推荐:先默认初始化再赋值
240
+ }
241
+ };
242
+ ```
243
+
244
+ ### POD类型与非POD类型的差异
245
+
246
+ #### POD类型(Plain Old Data)- 必须显式初始化
247
+
248
+ POD类型没有默认构造函数,未初始化时值为随机值:
249
+
250
+ - **基本类型**:`int`, `long`, `float`, `double`, `char`, `bool`
251
+ - **指针类型**:`int*`, `void*`, `char*`, `Logger*`
252
+ - **枚举类型**:`enum Status { ... };`
253
+ - **数组类型**:`int buffer[10];`
254
+
255
+ **未初始化的后果**:
256
+ ```cpp
257
+ int value; // 未初始化,值可能是任意值(如-12345)
258
+ bool flag; // 未初始化,可能既不是true也不是false
259
+ int* ptr; // 未初始化,可能是野指针
260
+ int arr[10]; // 未初始化,所有元素值不确定
261
+ ```
262
+
263
+ **必须显式初始化**:
264
+ ```cpp
265
+ int value = 0; // ✅
266
+ bool flag = false; // ✅
267
+ int* ptr = nullptr; // ✅
268
+ int arr[10] = {0}; // ✅
269
+ ```
270
+
271
+ #### 非POD类型 - 通常有默认构造函数
272
+
273
+ 有默认构造函数的类型,不显式初始化时会调用默认构造函数:
274
+
275
+ - **STL容器**:`std::string`, `std::vector`, `std::map`
276
+ - **智能指针**:`std::unique_ptr`, `std::shared_ptr`
277
+ - **自定义类**:有默认构造函数的类
278
+
279
+ **可以不显式初始化**:
280
+ ```cpp
281
+ std::string name; // ✅ 调用默认构造,为空字符串
282
+ std::vector<int> data; // ✅ 调用默认构造,为空vector
283
+ std::shared_ptr<Node> ptr; // ✅ 调用默认构造,为nullptr
284
+ ```
285
+
286
+ **建议显式初始化(更清晰)**:
287
+ ```cpp
288
+ std::string name = ""; // ✅ 更清晰
289
+ std::vector<int> data = {}; // ✅ 更清晰
290
+ std::shared_ptr<Node> ptr = nullptr; // ✅ 更清晰
291
+ ```
292
+
293
+ ### 结构体初始化列表(C++11)
294
+
295
+ C++11支持结构体的聚合初始化:
296
+
297
+ ```cpp
298
+ struct NetworkConfig {
299
+ int timeout;
300
+ int retryCount;
301
+ char* proxyHost;
302
+ int proxyPort;
303
+ };
304
+
305
+ // 方式1:聚合初始化(使用默认值)
306
+ NetworkConfig config1 = {30000, 3, nullptr, 0}; // ✅ 推荐
307
+
308
+ // 方式2:类内初始化器(成员默认值)
309
+ struct NetworkConfig {
310
+ int timeout = 30000; // ✅ 推荐
311
+ int retryCount = 3;
312
+ char* proxyHost = nullptr;
313
+ int proxyPort = 0;
314
+ };
315
+ NetworkConfig config2; // ✅ 使用类内默认值
316
+
317
+ // 方式3:空初始化列表(零初始化)
318
+ NetworkConfig config3 = {}; // ✅ 所有成员零初始化
319
+ ```
320
+
321
+ ## 风险流分析(RiskFlow)
322
+
323
+ - **RISK_SOURCE**:类/结构体中未显式初始化的数据成员
324
+ - **RISK_TYPE**:未定义行为、数据不一致
325
+ - **RISK_PATH**:成员声明 -> 未初始化 -> 使用未定义值 -> 逻辑错误或崩溃
326
+ - **IMPACT_POINT**:程序运行时行为不可预测、服务不稳定
327
+
328
+ ## 影响分析(ImpactAnalysis)
329
+
330
+ - **Trigger**:创建对象实例时,未初始化成员包含随机值
331
+ - **Propagation**:使用未初始化成员的值进行计算、判断或访问
332
+ - **Consequence**:程序行为不可预测、逻辑错误、内存访问错误、服务崩溃
333
+ - **Mitigation**:为所有数据成员提供显式初始化(类内初始化器或构造函数初始化)
334
+
335
+ ## 误报排除
336
+
337
+ | 场景 | 识别特征 | 处理方式 |
338
+ |------|----------|----------|
339
+ | 有默认构造函数的类型 | std::string、std::vector等STL类型 | 不报 |
340
+ | 有类内初始化器 | 成员声明有 `= value` | 不报 |
341
+ | 在初始化列表初始化 | 构造函数 `: member(value)` | 不报 |
342
+ | 在构造函数体赋值 | 构造函数内有 `member = value` | 不报 |
343
+ | 静态成员 | static 声明 | 不报 |
344
+ | const成员 | const 声明(必须在初始化列表) | 不报 |
345
+ | NOPROTECT标记 | 有 // NOPROTECT 注释 | 不报 |
346
+ | 第三方库 | 位于 third_party 目录 | 白名单排除 |
347
+ | 测试代码 | 位于 test 目录 | 可选白名单 |
348
+ ## 测试用例
349
+
350
+ ### 触发用例(应该报)
351
+
352
+ ```cpp
353
+ // test_InitializationOrder_001_trigger.cpp
354
+ class BadConfig {
355
+ public:
356
+ int port; // 应该报:未初始化
357
+ bool enabled; // 应该报:未初始化
358
+ char* host; // 应该报:未初始化
359
+ int count; // 应该报:未初始化
360
+ };
361
+
362
+ struct NetworkInfo {
363
+ int timeout; // 应该报:未初始化
364
+ int retryCount; // 应应该报:未初始化
365
+ };
366
+ ```
367
+
368
+ ### 安全用例(不应该报)
369
+
370
+ ```cpp
371
+ // test_InitializationOrder_001_safe.cpp
372
+ class GoodConfig {
373
+ public:
374
+ int port = 8080; // 安全:类内初始化
375
+ bool enabled = false; // 安全:类内初始化
376
+ char* host = nullptr; // 安全:类内初始化
377
+ int count = 0; // 安全:类内初始化
378
+ };
379
+
380
+ class SafeConfig {
381
+ public:
382
+ int port;
383
+ bool enabled;
384
+
385
+ SafeConfig() : port(8080), enabled(false) {} // 安全:初始化列表
386
+ };
387
+
388
+ class AssignConfig {
389
+ public:
390
+ int port;
391
+ bool enabled;
392
+
393
+ AssignConfig() {
394
+ port = 8080; // 安全:构造函数体赋值
395
+ enabled = false;
396
+ }
397
+ };
398
+
399
+ class STLConfig {
400
+ public:
401
+ std::string name; // 安全:有默认构造函数
402
+ std::vector<int> data; // 安全:有默认构造函数
403
+ };
404
+
405
+ // NOPROTECT: 特殊场景
406
+ // NOPROTECT: 测试代码
407
+ class NoProtectConfig {
408
+ public:
409
+ int value; // 不报:有NOPROTECT标记
410
+ };
411
+ ```
@@ -0,0 +1,255 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_Lifecycle_001"
3
+ name: "返回引用的函数返回局部变量"
4
+ category: "生命周期"
5
+ severity: "CRITICAL"
6
+ language: ["cpp", "c++"]
7
+ author: "OH-Department7 Stability Team"
8
+ ---
9
+
10
+ # 返回引用的函数返回局部变量
11
+
12
+ ## 问题描述
13
+
14
+ 返回值类型是引用的函数,不应该返回局部变量,否则存在UAF(Use-After-Free)产生未定义行为。当函数返回局部变量的引用时,由于局部变量在函数返回后即被销毁,调用者获取的引用将指向已释放的栈内存,访问该引用将导致未定义行为,可能引发程序崩溃或数据损坏。
15
+
16
+ ## 检测示例
17
+
18
+ ### ❌ 问题代码
19
+
20
+ ```cpp
21
+ // 场景1:返回局部变量的引用
22
+ int& GetValue(int x) {
23
+ int value = x * 2; // 局部变量
24
+ return value; // 错误:返回局部变量的引用
25
+ }
26
+
27
+ // 场景2:返回局部数组元素的引用
28
+ int& GetElement(int index) {
29
+ int arr[10]; // 局部数组
30
+ for (int i = 0; i < 10; i++) {
31
+ arr[i] = i;
32
+ }
33
+ return arr[index]; // 错误:返回局部数组元素的引用
34
+ }
35
+
36
+ // 场景3:返回条件表达式中局部变量的引用
37
+ int& GetMax(int a, int b) {
38
+ int maxVal = (a > b) ? a : b; // 局部变量
39
+ return maxVal; // 错误:返回局部变量的引用
40
+ }
41
+
42
+ // 场景4:返回局部对象的引用
43
+ std::string& GetName() {
44
+ std::string name = "local"; // 局部对象
45
+ return name; // 错误:返回局部对象的引用
46
+ }
47
+
48
+ // 场景5:返回局部静态变量的引用(特殊场景)
49
+ int& GetCounter() {
50
+ int counter = 0; // 非静态局部变量
51
+ counter++;
52
+ return counter; // 错误:每次调用都重新初始化
53
+ }
54
+
55
+ // 场景6:返回局部容器的引用
56
+ std::vector<int>& GetValues() {
57
+ std::vector<int> values = {1, 2, 3}; // 局部容器
58
+ return values; // 错误:返回局部容器的引用
59
+ }
60
+ ```
61
+
62
+ ### ✅ 修复方案
63
+
64
+ ```cpp
65
+ // 修复场景1:返回值而非引用
66
+ int GetValue(int x) {
67
+ int value = x * 2;
68
+ return value; // 正确:返回值
69
+ }
70
+
71
+ // 修复场景2:使用静态变量
72
+ int& GetElement(int index) {
73
+ static int arr[10]; // 静态变量
74
+ for (int i = 0; i < 10; i++) {
75
+ arr[i] = i;
76
+ }
77
+ return arr[index]; // 正确:返回静态变量的引用
78
+ }
79
+
80
+ // 修复场景3:使用参数引用输出
81
+ void GetMax(int a, int b, int& outMax) {
82
+ outMax = (a > b) ? a : b; // 通过引用参数输出
83
+ }
84
+
85
+ // 修复场景4:返回静态或成员变量
86
+ std::string& GetName() {
87
+ static std::string name = "local"; // 静态变量
88
+ return name; // 正确:返回静态变量的引用
89
+ }
90
+
91
+ // 修复场景5:正确使用静态变量
92
+ int& GetCounter() {
93
+ static int counter = 0; // 静态变量
94
+ counter++;
95
+ return counter; // 正确:静态变量生命周期贯穿整个程序
96
+ }
97
+
98
+ // 修复场景6:返回指针或值
99
+ std::vector<int> GetValues() {
100
+ std::vector<int> values = {1, 2, 3};
101
+ return values; // 正确:返回值
102
+ }
103
+
104
+ // 修复场景7:返回成员变量的引用(实际代码中常见)
105
+ class DataStore {
106
+ private:
107
+ std::map<int, std::string> data_;
108
+
109
+ public:
110
+ const std::string& GetValue(int key) {
111
+ auto it = data_.find(key);
112
+ if (it != data_.end()) {
113
+ return it->second; // ✅ 正确:返回成员变量map中的元素引用
114
+ }
115
+ static const std::string empty = "";
116
+ return empty; // ✅ 正确:返回静态变量的引用
117
+ }
118
+
119
+ std::map<int, std::string>& GetData() {
120
+ return data_; // ✅ 正确:返回成员变量的引用
121
+ }
122
+ };
123
+
124
+ // 修复场景8:返回成员变量的成员引用(实际代码中常见)
125
+ class Node {
126
+ private:
127
+ struct Decoration {
128
+ Color backgroundColor_;
129
+ };
130
+ std::shared_ptr<Decoration> decoration_;
131
+
132
+ public:
133
+ const Color& GetBackgroundColor() {
134
+ if (decoration_) {
135
+ return decoration_->backgroundColor_; // ✅ 正确:返回成员变量的成员
136
+ }
137
+ static Color defaultColor = Color::White();
138
+ return defaultColor; // ✅ 正确:返回静态变量
139
+ }
140
+ };
141
+
142
+ // 修复场景9:单例模式的静态局部变量引用(Meyers单例)
143
+ class MemoryTrack {
144
+ public:
145
+ static MemoryTrack& Instance() {
146
+ static MemoryTrack instance; // ✅ 正确:Meyers单例,静态局部变量
147
+ return instance; // ✅ 正确:返回静态局部变量的引用,生命周期贯穿整个程序
148
+ }
149
+ };
150
+
151
+ // 修复场景10:返回智能指针管理的对象引用(需确保生命周期)
152
+ class CacheManager {
153
+ private:
154
+ std::shared_ptr<Image> cachedImage_;
155
+
156
+ public:
157
+ const Image& GetCachedImage() {
158
+ if (cachedImage_) {
159
+ return *cachedImage_; // ✅ 正确:cachedImage_是成员,管理对象生命周期
160
+ }
161
+ static Image emptyImage;
162
+ return emptyImage; // ✅ 正确:静态对象
163
+ }
164
+ };
165
+ ```
166
+
167
+ ## 检测范围
168
+
169
+ 检查以下模式:
170
+
171
+ - 返回类型包含 `&` 的函数
172
+ - 返回语句中返回局部变量
173
+ - 返回语句中返回临时对象
174
+ - 返回语句中返回函数内的栈变量
175
+
176
+ ## 检测要点
177
+
178
+ 1. 识别函数返回类型是否为引用类型(包含 `&`)
179
+ 2. 追踪函数体内的局部变量定义
180
+ 3. 检测返回语句是否返回这些局部变量
181
+ 4. 排除返回静态变量、成员变量、参数引用、全局变量的情况
182
+
183
+ ## 风险流分析(RiskFlow)
184
+
185
+ - **RISK_SOURCE**:函数返回类型声明为引用
186
+ - **RISK_TYPE**:悬垂引用(Dangling Reference)/ UAF
187
+ - **RISK_PATH**:返回局部变量引用 -> 函数返回栈帧销毁 -> 引用指向已释放内存 -> 访问导致UAF
188
+ - **IMPACT_POINT**:调用者使用返回的引用时,访问已释放的栈内存
189
+
190
+ ## 影响分析(ImpactAnalysis)
191
+
192
+ - **Trigger**:函数返回后,调用者尝试使用返回的引用
193
+ - **Propagation**:返回的引用指向已销毁的栈内存,内存可能被后续函数调用覆盖
194
+ - **Consequence**:未定义行为,可能表现为随机值、程序崩溃、数据损坏、安全漏洞
195
+ - **Mitigation**:返回值而非引用,或返回静态变量/成员变量的引用
196
+
197
+ ## 误报排除
198
+
199
+ | 场景 | 识别特征 | 处理方式 |
200
+ |------|----------|----------|
201
+ | 返回静态变量 | 变量声明含 `static` | 不报 |
202
+ | 返回成员变量 | 返回 `this->member` 或 `member_` | 不报 |
203
+ | 返回参数引用 | 返回参数本身或参数的成员 | 不报 |
204
+ | 返回全局变量 | 返回全局/命名空间作用域变量 | 不报 |
205
+ | NOPROTECT标记 | 有 `// NOPROTECT` 注释 | 不报 |
206
+ | 第三方库 | 位于 `third_party` 目录 | 白名单排除 |
207
+ ## 测试用例
208
+
209
+ ### 触发用例(应该报)
210
+
211
+ ```cpp
212
+ // test_Lifecycle_001_trigger.cpp
213
+ int& trigger_bad_1(int x) {
214
+ int value = x * 2; // 应该报:返回局部变量引用
215
+ return value;
216
+ }
217
+
218
+ int& trigger_bad_2(int index) {
219
+ int arr[10]; // 应该报:返回局部数组元素引用
220
+ return arr[index];
221
+ }
222
+
223
+ std::string& trigger_bad_3() {
224
+ std::string name = "local"; // 应该报:返回局部对象引用
225
+ return name;
226
+ }
227
+ ```
228
+
229
+ ### 安全用例(不应该报)
230
+
231
+ ```cpp
232
+ // test_Lifecycle_001_safe.cpp
233
+ int& safe_good_1(int index) {
234
+ static int arr[10]; // 安全:返回静态变量引用
235
+ return arr[index];
236
+ }
237
+
238
+ int& safe_good_2(int& param) {
239
+ return param; // 安全:返回参数引用
240
+ }
241
+
242
+ class MyClass {
243
+ public:
244
+ int& safe_good_3() {
245
+ return member_; // 安全:返回成员变量引用
246
+ }
247
+ private:
248
+ int member_;
249
+ };
250
+
251
+ int safe_good_4(int x) {
252
+ int value = x * 2;
253
+ return value; // 安全:返回值而非引用
254
+ }
255
+ ```