@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,423 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ add-rule.py - 稳定性规则脚手架工具
4
+
5
+ 用法:
6
+ python add-rule.py --rule-id StabilityCodeReview_ExceptionHandling_008
7
+ --name "空catch块检测"
8
+ --category "异常处理"
9
+ --severity "HIGH"
10
+ --description "检测空的catch块"
11
+
12
+ 自动完成:
13
+ 1. 创建参考文档 references/分类/StabilityCodeReview_xxx.md
14
+ 2. 更新 config/rules.yaml 配置
15
+ """
16
+
17
+ import argparse
18
+ import re
19
+ import sys
20
+ from pathlib import Path
21
+ from string import Template
22
+
23
+ try:
24
+ import yaml
25
+ except ImportError:
26
+ yaml = None
27
+
28
+
29
+ CATEGORY_MAP = {
30
+ "异常处理": "ExceptionHandling",
31
+ "并发稳定性": "ConcurrencyStability",
32
+ "性能稳定性": "PerformanceStability",
33
+ "资源管理": "ResourceManagement",
34
+ "初始化顺序": "InitializationOrder",
35
+ "边界条件": "BoundaryCondition",
36
+ "生命周期": "Lifecycle",
37
+ "内存稳定性": "MemoryStability",
38
+ "图形稳定性": "GraphicsStability",
39
+ }
40
+
41
+
42
+ def validate_rule_id(rule_id: str) -> bool:
43
+ pattern = r"^StabilityCodeReview_([A-Za-z]+)_([0-9]+)$"
44
+ return bool(re.match(pattern, rule_id))
45
+
46
+
47
+ def create_reference_doc(rule_id: str, rule_name: str, category: str, severity: str, description: str) -> str:
48
+ template_str = '''---
49
+ rule_id: "$rule_id"
50
+ name: "$rule_name"
51
+ category: "$category"
52
+ severity: "$severity"
53
+ language: ["cpp", "c++"]
54
+ author: "OH-Department7 Stability Team"
55
+ ---
56
+
57
+ # $rule_name
58
+
59
+ ## 问题描述
60
+
61
+ $description
62
+
63
+ ## 检测示例
64
+
65
+ ### ❌ 问题代码
66
+
67
+ ```cpp
68
+ // 场景1:TODO: 添加具体问题描述
69
+ // TODO: 添加问题代码示例
70
+
71
+ // 场景2:TODO: 添加具体问题描述
72
+ // TODO: 添加问题代码示例
73
+
74
+ // 场景3:TODO: 添加具体问题描述
75
+ // TODO: 添加问题代码示例
76
+
77
+ // 场景4:TODO: 添加具体问题描述
78
+ // TODO: 添加问题代码示例
79
+
80
+ // 场景5:TODO: 添加具体问题描述
81
+ // TODO: 添加问题代码示例
82
+
83
+ // 建议:提供5-10个典型错误场景,覆盖常见变体和实际代码模式
84
+ ```
85
+
86
+ ### ✅ 修复方案
87
+
88
+ ```cpp
89
+ // 修复场景1:TODO: 添加修复方法说明
90
+ // TODO: 添加修复后的代码
91
+
92
+ // 修复场景2:TODO: 添加修复方法说明
93
+ // TODO: 添加修复后的代码
94
+
95
+ // 修复场景3:TODO: 添加修复方法说明
96
+ // TODO: 添加修复后的代码
97
+
98
+ // 修复场景4:TODO: 添加修复方法说明
99
+ // TODO: 添加修复后的代码
100
+
101
+ // 修复场景5:TODO: 添加修复方法说明
102
+ // TODO: 添加修复后的代码
103
+
104
+ // 建议:提供5-10个修复方案,包括最佳实践、RAII模式、实际代码中的标准写法
105
+ ```
106
+
107
+ ## 检测范围
108
+
109
+ 检查以下API/函数/模式/场景:
110
+
111
+ 1. TODO: 添加检测目标1
112
+ 2. TODO: 添加检测目标2
113
+ 3. TODO: 添加检测目标3
114
+ 4. TODO: 添加检测目标4
115
+ 5. TODO: 添加检测目标5
116
+
117
+ ## 检测要点
118
+
119
+ 1. TODO: 添加检测步骤1:如何识别目标
120
+ 2. TODO: 添加检测步骤2:如何检查问题
121
+ 3. TODO: 添加检测步骤3:如何判断风险
122
+ 4. TODO: 添加检测步骤4:如何排除误报
123
+ 5. TODO: 添加检测步骤5:特殊情况处理
124
+
125
+ ### TODO: 可选扩展说明章节
126
+
127
+ 根据规则特点添加以下可选章节:
128
+
129
+ #### 最佳实践说明
130
+
131
+ TODO: 说明该类问题的最佳实践模式
132
+
133
+ - **推荐方式1**:TODO: 说明适用场景和示例
134
+ - **推荐方式2**:TODO: 说明适用场景和示例
135
+
136
+ #### 实际代码参考
137
+
138
+ TODO: 引用实际项目中的具体函数、常量、模式
139
+
140
+ - **实际常量值**:TODO: 添加实际项目常量(如MAX_ITEM_COUNT = 1000)
141
+ - **实际函数名**:TODO: 添加实际项目函数名
142
+ - **实际日志函数**:TODO: 添加实际项目日志函数(如ROSEN_LOGE)
143
+
144
+ #### 特殊技术说明
145
+
146
+ TODO: 针对复杂技术点提供详细说明
147
+
148
+ #### 分类处理策略
149
+
150
+ TODO: 针对不同场景提供不同的处理方式
151
+
152
+ - **场景A**:TODO: 处理方式1
153
+ - **场景B**:TODO: 处理方式2
154
+
155
+ ## 风险流分析(RiskFlow)
156
+
157
+ - **RISK_SOURCE**: TODO: 添加稳定性风险来源描述(具体到代码元素)
158
+ - **RISK_TYPE**: TODO: 添加具体的稳定性风险类型(如空指针解引用、UAF、数据竞争等)
159
+ - **RISK_PATH**: TODO: 添加风险传播的完整路径(从来源到影响点)
160
+ - **IMPACT_POINT**: TODO: 添加最终影响系统稳定性的点(如崩溃、资源耗尽等)
161
+
162
+ ## 影响分析(ImpactAnalysis)
163
+
164
+ - **Trigger**: TODO: 添加触发条件(具体场景描述)
165
+ - **Propagation**: TODO: 添加风险传播方式(具体机制)
166
+ - **Consequence**: TODO: 添加稳定性后果(具体表现)
167
+ - **Mitigation**: TODO: 添加缓解建议(具体修复方案)
168
+
169
+ ## 误报排除
170
+
171
+ | 场景 | 识别特征 | 处理方式 |
172
+ |------|----------|----------|
173
+ | NOPROTECT标记 | 有 // NOPROTECT 注释 | 不报 |
174
+ | 已有安全防护 | TODO: 具体识别方法 | 不报 |
175
+ | 使用最佳实践 | TODO: 具体识别方法 | 不报 |
176
+ | 第三方库 | 位于 third_party 目录 | 白名单排除 |
177
+ | 测试代码 | 位于 test 目录或 _test.cpp 文件 | 自动跳过 |
178
+ | TODO: 其他场景 | TODO: 识别方法 | TODO: 处理方式 |
179
+
180
+ ## 测试用例
181
+
182
+ ### 触发用例(应该报)
183
+
184
+ ```cpp
185
+ // test_${rule_id}_trigger.cpp
186
+
187
+ // 触发用例1:TODO: 添加触发场景描述
188
+ void trigger_bad_1()
189
+ {
190
+ // TODO: 添加触发场景1的代码
191
+ }
192
+
193
+ // 触发用例2:TODO: 添加触发场景描述
194
+ void trigger_bad_2()
195
+ {
196
+ // TODO: 添加触发场景2的代码
197
+ }
198
+
199
+ // 触发用例3:TODO: 添加触发场景描述
200
+ void trigger_bad_3()
201
+ {
202
+ // TODO: 添加触发场景3的代码
203
+ }
204
+
205
+ // 触发用例4:TODO: 添加触发场景描述
206
+ void trigger_bad_4()
207
+ {
208
+ // TODO: 添加触发场景4的代码
209
+ }
210
+
211
+ // 触发用例5:TODO: 添加触发场景描述
212
+ void trigger_bad_5()
213
+ {
214
+ // TODO: 添加触发场景5的代码
215
+ }
216
+
217
+ // 建议:提供5-10个触发用例,覆盖典型错误模式和边界情况
218
+ ```
219
+
220
+ ### 安全用例(不应该报)
221
+
222
+ ```cpp
223
+ // test_${rule_id}_safe.cpp
224
+
225
+ // 安全用例1:TODO: 添加安全写法描述
226
+ void safe_good_1()
227
+ {
228
+ // TODO: 添加安全写法1的代码
229
+ }
230
+
231
+ // 安全用例2:TODO: 添加安全写法描述
232
+ void safe_good_2()
233
+ {
234
+ // TODO: 添加安全写法2的代码
235
+ }
236
+
237
+ // 安全用例3:TODO: 添加安全写法描述
238
+ void safe_good_3()
239
+ {
240
+ // TODO: 添加安全写法3的代码
241
+ }
242
+
243
+ // 安全用例4:TODO: 添加安全写法描述
244
+ void safe_good_4()
245
+ {
246
+ // TODO: 添加安全写法4的代码
247
+ }
248
+
249
+ // 安全用例5:TODO: 添加安全写法描述
250
+ void safe_good_5()
251
+ {
252
+ // TODO: 添加安全写法5的代码
253
+ }
254
+
255
+ // NOPROTECT用例:TODO: 添加特殊场景说明
256
+ void noprotect_case()
257
+ {
258
+ // NOPROTECT: TODO: 添加特殊场景说明
259
+ // TODO: 添加有NOPROTECT标记的代码
260
+ }
261
+
262
+ // 建议:提供5-10个安全用例,覆盖正确做法和误报排除场景
263
+ ```
264
+ '''
265
+
266
+ template = Template(template_str)
267
+ return template.substitute(
268
+ rule_id=rule_id,
269
+ rule_name=rule_name,
270
+ category=category,
271
+ severity=severity,
272
+ description=description,
273
+ )
274
+
275
+
276
+ def update_rules_config(config_path: Path, rule_id: str, rule_name: str, category: str, severity: str, description: str) -> bool:
277
+ if yaml is None:
278
+ print("Error: PyYAML not installed, cannot update config", file=sys.stderr)
279
+ return False
280
+
281
+ if not config_path.exists():
282
+ print(f"Error: Config file not found: {config_path}", file=sys.stderr)
283
+ return False
284
+
285
+ try:
286
+ with open(config_path, "r", encoding="utf-8") as f:
287
+ config = yaml.safe_load(f) or {}
288
+ except Exception as e:
289
+ print(f"Error: Failed to load config: {e}", file=sys.stderr)
290
+ return False
291
+
292
+ rules = config.get("rules", {})
293
+
294
+ if category not in rules:
295
+ print(f"Error: Category '{category}' not found in config", file=sys.stderr)
296
+ print(f"Available categories: {list(rules.keys())}", file=sys.stderr)
297
+ return False
298
+
299
+ rule_config = {
300
+ "enabled": True,
301
+ "id": rule_id,
302
+ "name": rule_name,
303
+ "severity": severity,
304
+ "description": description,
305
+ "reference": f"{CATEGORY_MAP[category]}/{rule_id}.md",
306
+ }
307
+
308
+ rules[category]["rules"][rule_id] = rule_config
309
+
310
+ try:
311
+ with open(config_path, "w", encoding="utf-8") as f:
312
+ yaml.dump(config, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
313
+ return True
314
+ except Exception as e:
315
+ print(f"Error: Failed to save config: {e}", file=sys.stderr)
316
+ return False
317
+
318
+
319
+ def main():
320
+ import io
321
+
322
+ if sys.stdout.encoding != 'utf-8':
323
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
324
+
325
+ parser = argparse.ArgumentParser(
326
+ description="Add a new stability rule to the framework",
327
+ formatter_class=argparse.RawDescriptionHelpFormatter,
328
+ )
329
+
330
+ parser.add_argument("--rule-id", required=True, help="Rule ID (e.g., StabilityCodeReview_ExceptionHandling_008)")
331
+ parser.add_argument("--name", required=True, help="Rule name (e.g., 空catch块检测)")
332
+ parser.add_argument("--category", required=True, help="Category (e.g., 异常处理)")
333
+ parser.add_argument("--severity", required=True, choices=["CRITICAL", "HIGH", "MEDIUM", "LOW"], help="Severity level")
334
+ parser.add_argument("--description", required=True, help="Rule description")
335
+ parser.add_argument("--dry-run", action="store_true", help="Show what would be created without actually creating")
336
+
337
+ args = parser.parse_args()
338
+
339
+ if not validate_rule_id(args.rule_id):
340
+ print(f"Error: Invalid rule ID format: {args.rule_id}", file=sys.stderr)
341
+ print("Expected format: StabilityCodeReview_<CategoryShort>_XXX", file=sys.stderr)
342
+ return 1
343
+
344
+ if args.category not in CATEGORY_MAP:
345
+ print(f"Error: Invalid category: {args.category}", file=sys.stderr)
346
+ print(f"Available categories: {list(CATEGORY_MAP.keys())}", file=sys.stderr)
347
+ return 1
348
+
349
+ script_dir = Path(__file__).resolve().parent.parent
350
+ references_dir = script_dir / "references"
351
+ config_path = script_dir / "config" / "rules.yaml"
352
+
353
+ reference_path = references_dir / CATEGORY_MAP[args.category] / f"{args.rule_id}.md"
354
+
355
+ if args.dry_run:
356
+ print("\n=== Dry Run - Files that would be created ===")
357
+ print(f"\n1. Reference doc: {reference_path}")
358
+ content = create_reference_doc(args.rule_id, args.name, args.category, args.severity, args.description)
359
+ print("\nPreview (first 800 chars):")
360
+ print(content[:800] + "...")
361
+ print(f"\nTotal length: {len(content)} chars")
362
+ print(f"\n2. Config update: {config_path}")
363
+ print(f" Adding rule to category: {args.category}")
364
+ return 0
365
+
366
+ # 先检查前置条件,避免创建半成品
367
+ if yaml is None:
368
+ print("Error: PyYAML not installed, cannot update config", file=sys.stderr)
369
+ return 1
370
+
371
+ if not config_path.exists():
372
+ print(f"Error: Config file not found: {config_path}", file=sys.stderr)
373
+ return 1
374
+
375
+ reference_content = create_reference_doc(args.rule_id, args.name, args.category, args.severity, args.description)
376
+ reference_path.parent.mkdir(parents=True, exist_ok=True)
377
+ with open(reference_path, "w", encoding="utf-8") as f:
378
+ f.write(reference_content)
379
+ print(f"✅ Created reference doc: {reference_path}")
380
+
381
+ if update_rules_config(config_path, args.rule_id, args.name, args.category, args.severity, args.description):
382
+ print(f"✅ Updated config: {config_path}")
383
+ else:
384
+ # 配置更新失败,删除已创建的文件
385
+ reference_path.unlink()
386
+ print("❌ Error: Failed to update config file", file=sys.stderr)
387
+ print(f" Deleted incomplete reference doc: {reference_path}", file=sys.stderr)
388
+ return 1
389
+
390
+ print("\n=== Next Steps ===")
391
+ print("1. Edit the reference doc to add examples and details:")
392
+ print(f" {reference_path}")
393
+ print("\n2. Fill in all TODO sections following RULE_TEMPLATE.md guidelines:")
394
+ print(" - Provide 5-10 problem code scenarios with detailed comments")
395
+ print(" - Provide 5-10 fix solutions with best practices")
396
+ print(" - Add specific detection targets (numbered list)")
397
+ print(" - Add 5+ detection steps (numbered list)")
398
+ print(" - Add optional extension sections if applicable:")
399
+ print(" * Best practices explanation")
400
+ print(" * Actual code references (function names, constants)")
401
+ print(" * Special technical details")
402
+ print(" * Classification strategies")
403
+ print(" - Complete RiskFlow (4 fields, specific to code elements)")
404
+ print(" - Complete ImpactAnalysis (4 fields, specific scenarios)")
405
+ print(" - Complete false positive exclusion table:")
406
+ print(" * NOPROTECT marker")
407
+ print(" * Third-party libraries")
408
+ print(" * Test code")
409
+ print(" * Rule-specific safe patterns")
410
+ print(" - Provide 5-10 trigger test cases")
411
+ print(" - Provide 5-10 safe test cases")
412
+ print(" - Add NOPROTECT example")
413
+ print("\n3. Use actual project references:")
414
+ print(" - Real function names (e.g., RSCanvasDrawingRenderNodeDrawable::CreateGpuSurface)")
415
+ print(" - Real constants (e.g., MAX_ITEM_COUNT = 1000)")
416
+ print(" - Real log functions (e.g., ROSEN_LOGE())")
417
+ print("\n4. Verify the rule with AI code review")
418
+
419
+ return 0
420
+
421
+
422
+ if __name__ == "__main__":
423
+ sys.exit(main())