@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,177 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_Lifecycle_002"
3
+ name: "获取临时变量指针"
4
+ category: "生命周期"
5
+ severity: "HIGH"
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
+ std::string* ptr = &GetString(); // GetString()返回临时对象
23
+
24
+ // 场景2:获取表达式临时对象的指针
25
+ int* ptr = &(a + b); // (a+b)是临时值
26
+
27
+ // 场景3:保存临时容器的指针
28
+ std::vector<int>* vec = &GetVector(); // GetVector()返回临时容器
29
+
30
+ // 场景4:获取临时字符串的指针
31
+ const char* str = GetTempString().c_str(); // GetTempString()返回临时string
32
+
33
+ // 场景5:获取临时对象的成员指针
34
+ int* ptr = &GetObject().value; // GetObject()返回临时对象
35
+
36
+ // 场景6:在条件表达式中使用临时变量指针
37
+ int* ptr = condition ? &GetValue1() : &GetValue2(); // 两个都是临时对象
38
+
39
+ // 场景7:获取强制类型转换临时对象的指针
40
+ Derived* d = dynamic_cast<Derived*>(&GetBase()); // GetBase()返回临时对象
41
+ ```
42
+
43
+ ### ✅ 修复方案
44
+
45
+ ```cpp
46
+ // 修复场景1:先存储到局部变量
47
+ std::string temp = GetString();
48
+ std::string* ptr = &temp; // 正确:ptr指向有效的局部变量
49
+
50
+ // 修复场景2:直接使用值
51
+ int result = a + b; // 使用值而非指针
52
+
53
+ // 修复场景3:先存储容器
54
+ std::vector<int> vec = GetVector();
55
+ std::vector<int>* vecPtr = &vec; // 正确
56
+
57
+ // 修复场景4:先存储字符串
58
+ std::string temp = GetTempString();
59
+ const char* str = temp.c_str(); // 正确:temp生命周期足够
60
+
61
+ // 修复场景5:先存储对象
62
+ Object obj = GetObject();
63
+ int* ptr = &obj.value; // 正确
64
+
65
+ // 修复场景6:存储结果后再使用
66
+ int v1 = GetValue1();
67
+ int v2 = GetValue2();
68
+ int* ptr = condition ? &v1 : &v2; // 正确
69
+
70
+ // 修复场景7:正确处理类型转换
71
+ Base base = GetBase();
72
+ Derived* d = dynamic_cast<Derived*>(&base); // 正确
73
+ ```
74
+
75
+ ## 检测范围
76
+
77
+ 检查以下模式:
78
+
79
+ - `&函数调用()` - 获取函数返回临时对象的地址
80
+ - `&(表达式)` - 获取表达式结果的地址
81
+ - `&对象.成员` 结合临时对象
82
+ - `临时对象.c_str()` - 获取临时字符串的C指针
83
+ - `&强制转换表达式` - 获取临时转换结果的地址
84
+
85
+ ## 检测要点
86
+
87
+ 1. 识别取地址运算符 `&` 的使用
88
+ 2. 判断 `&` 后面是否为临时对象(函数调用返回值、表达式结果)
89
+ 3. 检测指针变量是否保存了临时对象的地址
90
+ 4. 排除取局部变量、成员变量地址的情况
91
+
92
+ ## 风险流分析(RiskFlow)
93
+
94
+ - **RISK_SOURCE**:取地址运算符作用于临时对象
95
+ - **RISK_TYPE**:悬垂指针(Dangling Pointer)/ UAF
96
+ - **RISK_PATH**:获取临时对象指针 -> 表达式结束临时对象销毁 -> 指针指向已释放内存 -> 使用指针导致UAF
97
+ - **IMPACT_POINT**:通过指针访问已销毁的临时对象内存
98
+
99
+ ## 影响分析(ImpactAnalysis)
100
+
101
+ - **Trigger**:表达式结束后使用保存的临时对象指针
102
+ - **Propagation**:临时对象内存被回收或重用,指针变为悬垂指针
103
+ - **Consequence**:未定义行为,可能表现为随机值、程序崩溃、数据损坏、安全漏洞
104
+ - **Mitigation**:先将临时对象存储到具名变量,再获取其地址
105
+
106
+ ## 误报排除
107
+
108
+ | 场景 | 识别特征 | 处理方式 |
109
+ |------|----------|----------|
110
+ | 取局部变量地址 | `&variable` 其中variable是局部变量 | 不报 |
111
+ | 取成员变量地址 | `&this->member` 或 `&member_` | 不报 |
112
+ | 取参数地址 | `&param` | 不报 |
113
+ | 取静态变量地址 | `&static_var` | 不报 |
114
+ | 取数组元素地址 | `&arr[i]` | 不报 |
115
+ | NOPROTECT标记 | 有 `// NOPROTECT` 注释 | 不报 |
116
+ | 第三方库 | 位于 `third_party` 目录 | 白名单排除 |
117
+ ## 测试用例
118
+
119
+ ### 触发用例(应该报)
120
+
121
+ ```cpp
122
+ // test_Lifecycle_002_trigger.cpp
123
+ std::string* trigger_bad_1() {
124
+ std::string* ptr = &GetString(); // 应该报:获取临时对象指针
125
+ return ptr;
126
+ }
127
+
128
+ int* trigger_bad_2(int a, int b) {
129
+ int* ptr = &(a + b); // 应该报:获取表达式临时结果指针
130
+ return ptr;
131
+ }
132
+
133
+ const char* trigger_bad_3() {
134
+ const char* str = GetTempString().c_str(); // 应该报:获取临时字符串指针
135
+ return str;
136
+ }
137
+
138
+ std::vector<int>* trigger_bad_4() {
139
+ std::vector<int>* vec = &CreateVector(); // 应该报:获取临时容器指针
140
+ return vec;
141
+ }
142
+ ```
143
+
144
+ ### 安全用例(不应该报)
145
+
146
+ ```cpp
147
+ // test_Lifecycle_002_safe.cpp
148
+ std::string* safe_good_1() {
149
+ std::string temp = GetString();
150
+ std::string* ptr = &temp; // 安全:取局部变量地址
151
+ return ptr;
152
+ }
153
+
154
+ int* safe_good_2(int a, int b) {
155
+ int result = a + b;
156
+ int* ptr = &result; // 安全:取局部变量地址
157
+ return ptr;
158
+ }
159
+
160
+ const char* safe_good_3() {
161
+ std::string temp = GetTempString();
162
+ const char* str = temp.c_str(); // 安全:temp生命周期足够
163
+ return str;
164
+ }
165
+
166
+ class MyClass {
167
+ int* safe_good_4(int index) {
168
+ return &arr_[index]; // 安全:取成员数组元素地址
169
+ }
170
+ private:
171
+ int arr_[10];
172
+ };
173
+
174
+ int* safe_good_5(int& ref) {
175
+ return &ref; // 安全:取引用参数地址
176
+ }
177
+ ```
@@ -0,0 +1,332 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_MemoryStability_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
+ 内存分配失败时的处理方式因分配函数类型而异,判空检查必须根据具体情况区分:
15
+
16
+ **必须判空的场景**:
17
+ - `malloc/calloc/realloc` 在失败时返回 `nullptr`,必须判空后使用,否则会导致空指针解引用崩溃
18
+ - `new(std::nothrow)` 在失败时返回 `nullptr`,必须判空后使用,否则会导致空指针解引用崩溃
19
+
20
+ **不需要判空的场景**:
21
+ - 普通 `new` 在失败时会抛出 `std::bad_alloc` 异常,但由于 OpenHarmony 禁止使用异常,实际会直接终止程序,因此普通 new 后无需判空检查
22
+
23
+ 若对必须判空的内存分配未检查返回值就直接解引用,将导致空指针解引用,引发进程崩溃或拒绝服务。
24
+
25
+ ## 检测示例
26
+
27
+ ### ❌ 问题代码
28
+
29
+ ```cpp
30
+ // 场景1:malloc未判空直接使用
31
+ void ProcessData(int size)
32
+ {
33
+ char* buffer = (char*)malloc(size); // malloc
34
+ buffer[0] = '\0'; // 错误:buffer可能为nullptr,未判空直接访问
35
+ ProcessBuffer(buffer);
36
+ free(buffer);
37
+ }
38
+
39
+ // 场景2:calloc未判空
40
+ void AllocateArray(int count)
41
+ {
42
+ int* arr = (int*)calloc(count, sizeof(int)); // calloc
43
+ arr[0] = 100; // 错误:arr可能为nullptr
44
+ free(arr);
45
+ }
46
+
47
+ // 场景3:realloc未判空
48
+ void ResizeBuffer(char* oldBuffer, int newSize)
49
+ {
50
+ char* newBuffer = (char*)realloc(oldBuffer, newSize); // realloc
51
+ newBuffer[0] = '\0'; // 错误:realloc可能失败返回nullptr,oldBuffer已被释放
52
+ }
53
+
54
+ // 场景4:new(std::nothrow)未判空直接使用
55
+ void ProcessData()
56
+ {
57
+ Data* data = new(std::nothrow) Data(); // nothrow new
58
+ data->Initialize(); // 错误:未判空直接解引用,可能导致崩溃
59
+ data->Process();
60
+ delete data;
61
+ }
62
+
63
+ // 场景5:new(std::nothrow)数组未判空
64
+ void AllocateBuffer()
65
+ {
66
+ char* buffer = new(std::nothrow) char[1024]; // nothrow new
67
+ memcpy(buffer, source, 1024); // 错误:buffer可能为nullptr
68
+ delete[] buffer;
69
+ }
70
+
71
+ // 场景6:链式malloc未判空
72
+ void ChainAllocation()
73
+ {
74
+ Node* head = (Node*)malloc(sizeof(Node));
75
+ head->next = (Node*)malloc(sizeof(Node)); // 错误:head可能为nullptr
76
+ head->next->value = 100; // 错误:head->next可能为nullptr
77
+ }
78
+ ```
79
+
80
+ ### ✅ 修复方案
81
+
82
+ ```cpp
83
+ // 修复场景1:malloc正确判空(实际代码中的标准模式)
84
+ void ProcessData(int size)
85
+ {
86
+ void* buffer = malloc(size);
87
+ if (buffer == nullptr) { // ✅ 正确:malloc必须判空
88
+ ROSEN_LOGE("malloc failed, size:%{public}zu", size); // 实际代码使用ROSEN_LOGE
89
+ return nullptr;
90
+ }
91
+
92
+ errno_t err = memcpy_s(buffer, size, source, size);
93
+ if (err != EOK) { // ✅ 正确:异常分支也要释放内存
94
+ free(buffer);
95
+ buffer = nullptr;
96
+ ROSEN_LOGE("memcpy_s failed, err:%{public}d", err);
97
+ return nullptr;
98
+ }
99
+
100
+ // 正常使用
101
+ ProcessBuffer(buffer);
102
+ free(buffer); // 使用后释放
103
+ }
104
+
105
+ // 修复场景1b:使用RAII(智能指针)替代手动管理(推荐)
106
+ void ProcessDataRAII(int size)
107
+ {
108
+ std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size); // ✅ 推荐:使用RAII
109
+ if (!buffer) { // make_unique失败时返回nullptr(罕见)
110
+ ROSEN_LOGE("allocation failed");
111
+ return;
112
+ }
113
+
114
+ ProcessBuffer(buffer.get()); // ✅ 安全:自动释放,无需手动free
115
+ }
116
+
117
+ // 修复场景2:calloc正确判空
118
+ void AllocateArray(int count)
119
+ {
120
+ int* arr = (int*)calloc(count, sizeof(int));
121
+ if (arr == nullptr) {
122
+ ROSEN_LOGE("calloc failed, count:%{public}d", count);
123
+ return;
124
+ }
125
+ arr[0] = 100;
126
+ free(arr);
127
+ }
128
+
129
+ // 修复场景3:realloc正确判空(注意realloc失败时原指针仍有效)
130
+ void ResizeBuffer(char* oldBuffer, int newSize)
131
+ {
132
+ char* newBuffer = (char*)realloc(oldBuffer, newSize);
133
+ if (newBuffer == nullptr) { // 正确:realloc必须判空
134
+ LOGE("realloc failed");
135
+ free(oldBuffer); // realloc失败时需要释放原指针
136
+ return;
137
+ }
138
+ newBuffer[0] = '\0';
139
+ // 使用newBuffer
140
+ }
141
+
142
+ // 修复场景4:nothrow new正确判空
143
+ void ProcessData()
144
+ {
145
+ Data* data = new(std::nothrow) Data();
146
+ if (data == nullptr) { // 正确:nothrow new必须判空
147
+ LOGE("Failed to allocate Data");
148
+ return;
149
+ }
150
+ data->Initialize();
151
+ data->Process();
152
+ delete data;
153
+ }
154
+
155
+ // 修复场景5:nothrow new数组正确判空
156
+ void AllocateBuffer()
157
+ {
158
+ char* buffer = new(std::nothrow) char[1024];
159
+ if (buffer == nullptr) { // 正确:判空后使用
160
+ LOGE("Failed to allocate buffer");
161
+ return;
162
+ }
163
+ memcpy(buffer, source, 1024);
164
+ delete[] buffer;
165
+ }
166
+
167
+ // 修复场景6:链式malloc逐一判空
168
+ void ChainAllocation()
169
+ {
170
+ Node* head = (Node*)malloc(sizeof(Node));
171
+ if (head == nullptr) {
172
+ LOGE("Failed to allocate head");
173
+ return;
174
+ }
175
+
176
+ head->next = (Node*)malloc(sizeof(Node));
177
+ if (head->next == nullptr) {
178
+ LOGE("Failed to allocate next");
179
+ free(head);
180
+ return;
181
+ }
182
+
183
+ head->next->value = 100;
184
+ free(head->next);
185
+ free(head);
186
+ }
187
+
188
+ // 修复场景7:使用智能指针替代手动管理
189
+ void SmartPointerApproach()
190
+ {
191
+ auto data = std::make_unique<Data>(); // 推荐:无需判空
192
+ data->Process();
193
+
194
+ auto buffer = std::make_unique<char[]>(1024); // 推荐:无需判空
195
+ memcpy(buffer.get(), source, 1024);
196
+ }
197
+ ```
198
+
199
+ ## 检测范围
200
+
201
+ 检查以下模式:
202
+
203
+ - `malloc()` 分配后的判空检查
204
+ - `calloc()` 分配后的判空检查
205
+ - `realloc()` 分配后的判空检查
206
+ - `new(std::nothrow)` 分配后的判空检查
207
+ - `new(std::nothrow)[]` 数组分配后的判空检查
208
+ - 普通 `new` 后的冗余判空(作为提示)
209
+ - 内存分配后紧接着的解引用操作
210
+
211
+ ## 检测要点
212
+
213
+ 1. 识别 `malloc/calloc/realloc` 或 `new(std::nothrow)` 内存分配
214
+ 2. 检查分配后的代码行是否有判空操作(if ptr == nullptr 等)
215
+ 3. 检查是否在判空前有解引用操作(ptr->、*ptr、ptr[0]等)
216
+ 4. 普通new后的判空作为冗余提示(非错误)
217
+ 5. 排除NOPROTECT标记和智能指针使用场景
218
+
219
+ ## 风险流分析(RiskFlow)
220
+
221
+ - **RISK_SOURCE**:malloc/calloc/realloc/new(std::nothrow)分配的内存指针
222
+ - **RISK_TYPE**:空指针解引用
223
+ - **RISK_PATH**:内存分配返回nullptr -> 未判空直接使用 -> 空指针解引用崩溃
224
+ - **IMPACT_POINT**:程序崩溃、服务中断、系统稳定性受损
225
+
226
+ ## 影响分析(ImpactAnalysis)
227
+
228
+ - **Trigger**:内存不足时malloc/calloc/realloc/new(std::nothrow)返回nullptr
229
+ - **Propagation**:未判空直接解引用nullptr指针
230
+ - **Consequence**:空指针解引用导致程序崩溃(SIGSEGV),拒绝服务
231
+ - **Mitigation**:malloc/calloc/realloc/new(std::nothrow) 分配后必须判空,普通 new 不需要判空,或使用智能指针
232
+
233
+ ## 误报排除
234
+
235
+ | 场景 | 识别特征 | 处理方式 |
236
+ |------|----------|----------|
237
+ | 使用智能指针 | unique_ptr/shared_ptr/make_unique | 不报 |
238
+ | 有判空操作 | if (ptr == nullptr) 或 if (!ptr) | 不报 |
239
+ | NOPROTECT标记 | // NOPROTECT 注释 | 不报 |
240
+ | 赋值给成员变量 | ptr = new(nothrow) 后单独函数判空 | 需上下文分析 |
241
+ | 测试代码 | 文件名包含 _test.cpp | 白名单排除 |
242
+ ## 测试用例
243
+
244
+ ### 触发用例(应该报)
245
+
246
+ ```cpp
247
+ // test_MemoryStability_001_trigger.cpp
248
+ void trigger_bad_1()
249
+ {
250
+ char* buffer = (char*)malloc(1024); // 应该报:malloc未判空
251
+ buffer[0] = '\0'; // 直接使用,buffer可能为nullptr
252
+ }
253
+
254
+ void trigger_bad_2()
255
+ {
256
+ int* arr = (int*)calloc(100, sizeof(int)); // 应该报:calloc未判空
257
+ arr[0] = 100; // 直接使用,arr可能为nullptr
258
+ }
259
+
260
+ void trigger_bad_3()
261
+ {
262
+ Data* data = new(std::nothrow) Data(); // 应该报:nothrow new未判空
263
+ data->Process(); // 直接解引用,data可能为nullptr
264
+ }
265
+
266
+ void trigger_bad_4()
267
+ {
268
+ int* arr = new(std::nothrow) int[100]; // 应该报:nothrow new数组未判空
269
+ arr[0] = 1; // 直接使用,arr可能为nullptr
270
+ }
271
+
272
+ void trigger_bad_5()
273
+ {
274
+ char* buf = new(nothrow) char[256]; // 应该报:简写nothrow未判空
275
+ *buf = '\0'; // 直接解引用
276
+ }
277
+ ```
278
+
279
+ ### 安全用例(不应该报)
280
+
281
+ ```cpp
282
+ // test_MemoryStability_001_safe.cpp
283
+ void safe_good_1()
284
+ {
285
+ char* buffer = (char*)malloc(1024);
286
+ if (buffer == nullptr) { // 安全:malloc正确判空
287
+ return;
288
+ }
289
+ buffer[0] = '\0';
290
+ free(buffer);
291
+ }
292
+
293
+ void safe_good_2()
294
+ {
295
+ int* arr = (int*)calloc(100, sizeof(int));
296
+ if (arr == nullptr) { // 安全:calloc正确判空
297
+ return;
298
+ }
299
+ arr[0] = 100;
300
+ free(arr);
301
+ }
302
+
303
+ void safe_good_3()
304
+ {
305
+ Data* data = new(std::nothrow) Data();
306
+ if (data == nullptr) { // 安全:正确判空
307
+ return;
308
+ }
309
+ data->Process();
310
+ delete data;
311
+ }
312
+
313
+ void safe_good_4()
314
+ {
315
+ auto data = std::make_unique<Data>(); // 安全:使用智能指针
316
+ data->Process();
317
+ }
318
+
319
+ void safe_good_5()
320
+ {
321
+ Data* data = new Data(); // 安全:普通new,OpenHarmony禁止异常
322
+ data->Process(); // 普通new失败会终止程序,不需要判空
323
+ delete data;
324
+ }
325
+
326
+ // NOPROTECT: 特殊场景
327
+ void noprotect_case()
328
+ {
329
+ Data* data = new(std::nothrow) Data();
330
+ data->Process(); // NOPROTECT标记,不报
331
+ }
332
+ ```