@comate/zulu 1.4.0-beta.2 → 1.4.0-beta.3
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/comate-engine/assets/skills/auto-commit/SKILL.md +241 -0
- package/comate-engine/assets/skills/auto-commit/references/data_structures.md +183 -0
- package/comate-engine/assets/skills/auto-commit/references/interaction_instruction.md +220 -0
- package/comate-engine/assets/skills/auto-commit/references/issue_type_mapping.json +19 -0
- package/comate-engine/assets/skills/auto-commit/references/query_reference.md +176 -0
- package/comate-engine/assets/skills/auto-commit/scripts/build_git_commit_payload.py +195 -0
- package/comate-engine/assets/skills/auto-commit/scripts/build_icafe_cards_payload.py +80 -0
- package/comate-engine/assets/skills/auto-commit/scripts/cache_manager.py +69 -0
- package/comate-engine/assets/skills/auto-commit/scripts/create_card_cli.py +67 -0
- package/comate-engine/assets/skills/auto-commit/scripts/git_diff_cli.py +201 -0
- package/comate-engine/assets/skills/auto-commit/scripts/git_utils.py +230 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/__init__.py +66 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/client.py +473 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/farseer.py +52 -0
- package/comate-engine/assets/skills/auto-commit/scripts/icafe/matching.py +784 -0
- package/comate-engine/assets/skills/auto-commit/scripts/logger.py +32 -0
- package/comate-engine/assets/skills/auto-commit/scripts/match_card_cli.py +41 -0
- package/comate-engine/assets/skills/auto-commit/scripts/payload_validators.py +309 -0
- package/comate-engine/assets/skills/auto-commit/scripts/recognize_card_cli.py +63 -0
- package/comate-engine/assets/skills/{automation-browser-comate → automation-browser}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{cnap-comate → cnap}/SKILL.md +1 -0
- package/comate-engine/assets/skills/code-review/SKILL.md +202 -0
- package/comate-engine/assets/skills/code-review/agents/correctness-reviewer.md +62 -0
- package/comate-engine/assets/skills/code-review/agents/custom-reviewer.md +53 -0
- package/comate-engine/assets/skills/code-review/agents/meta-reviewer.md +84 -0
- package/comate-engine/assets/skills/code-review/agents/reliability-reviewer.md +72 -0
- package/comate-engine/assets/skills/code-review/agents/reuse-reviewer.md +101 -0
- package/comate-engine/assets/skills/code-review/agents/style-reviewer.md +65 -0
- package/comate-engine/assets/skills/code-review/evals/SKILL.md +334 -0
- package/comate-engine/assets/skills/code-review/evals/agents/gt-generator.md +76 -0
- package/comate-engine/assets/skills/code-review/evals/agents/miner.md +87 -0
- package/comate-engine/assets/skills/code-review/evals/agents/score-judge.md +168 -0
- package/comate-engine/assets/skills/code-review/evals/references/cli-query-template.md +114 -0
- package/comate-engine/assets/skills/code-review/evals/references/gt-schema.md +77 -0
- package/comate-engine/assets/skills/code-review/references/custom-rules/RULE_TEMPLATE.md +141 -0
- package/comate-engine/assets/skills/code-review/references/dispatch-template.md +142 -0
- package/comate-engine/assets/skills/code-review/references/output-schema.md +197 -0
- package/comate-engine/assets/skills/code-review/references/report-format.md +41 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_AUTH_RULES.md +29 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_CORRECTNESS_RULES.md +111 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_RESOURCE_CONCURRENCY_RULES.md +190 -0
- package/comate-engine/assets/skills/code-review/references/rules/Go/GO_STYLE_RULES.md +354 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_AUTH_RULES.md +34 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_CORRECTNESS_RULES.md +207 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_RESOURCE_CONCURRENCY_RULES.md +220 -0
- package/comate-engine/assets/skills/code-review/references/rules/Java/JAVA_STYLE_RULES.md +306 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_AUTH_RULES.md +48 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_CORRECTNESS_RULES.md +364 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_RESOURCE_CONCURRENCY_RULES.md +180 -0
- package/comate-engine/assets/skills/code-review/references/rules/Js/JS_STYLE_RULES.md +350 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_AUTH_RULES.md +38 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_CORRECTNESS_RULES.md +255 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_RESOURCE_CONCURRENCY_RULES.md +180 -0
- package/comate-engine/assets/skills/code-review/references/rules/Python/PYTHON_STYLE_RULES.md +195 -0
- package/comate-engine/assets/skills/code-review/references/telemetry.md +27 -0
- package/comate-engine/assets/skills/{code-security-comate → code-security}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/SKILL.md +1 -1
- package/comate-engine/assets/skills/create-automation-tasks-comate/SKILL.md +300 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/backend_dev.md +109 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/env_setup.md +130 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/frontend_dev.md +74 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/git_operations.md +88 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/long_running_task.md +96 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/references/testing_strategy.md +94 -0
- package/comate-engine/assets/skills/create-automation-tasks-comate/scripts/check_config.py +397 -0
- package/comate-engine/assets/skills/{create-rule-comate → create-rule}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{create-skill-comate → create-skill}/SKILL.md +1 -1
- package/comate-engine/assets/skills/{figma2code-comate → figma2code}/SKILL.md +1 -0
- package/comate-engine/assets/skills/{icafe-comate → icafe}/SKILL.md +1 -13
- package/comate-engine/assets/skills/{icode-comate → icode}/SKILL.md +1 -0
- package/comate-engine/node_modules/@comate/plugin-shared-internals/dist/index.js +3 -3
- package/comate-engine/server.js +136 -82
- package/dist/bundle/index.js +20 -9
- package/package.json +1 -1
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/cases.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/deploy-troubleshoot.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/install.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/kubectl.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/login.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/references/oncall.md +0 -0
- /package/comate-engine/assets/skills/{cnap-comate → cnap}/scripts/install_cnap_cli.sh +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/credential_hosting.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-go_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-java_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-php_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair-python_sql_injection.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/references/vul_repair_sensitive.md +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/credential_hosting.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/credential_poll.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/http_client.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/parse_scan_result.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/repair_vulnerability.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/report_chat.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/scan_vulnerability.py +0 -0
- /package/comate-engine/assets/skills/{code-security-comate → code-security}/scripts/utils.py +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/doc-map-extended.md +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/models-and-billing.md +0 -0
- /package/comate-engine/assets/skills/{comate-docs-comate → comate-docs}/references/product-overview.md +0 -0
- /package/comate-engine/assets/skills/{create-image-comate → create-image}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/LICENSE.txt +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/analyzer.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/comparator.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/agents/grader.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/assets/eval_review.html +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/eval-viewer/generate_review.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/eval-viewer/viewer.html +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/references/schemas.md +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__init__.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/__pycache__/aggregate_benchmark.cpython-311.pyc +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/aggregate_benchmark.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/generate_report.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/package_skill.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/quick_validate.py +0 -0
- /package/comate-engine/assets/skills/{create-skill-comate → create-skill}/scripts/utils.py +0 -0
- /package/comate-engine/assets/skills/{create-subagent-comate → create-subagent}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/codeConnect.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/designToken.md +0 -0
- /package/comate-engine/assets/skills/{figma2code-comate → figma2code}/references/image2design.md +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/fetch_skills.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/get_download_url.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/install_skill.py +0 -0
- /package/comate-engine/assets/skills/{find-skills-comate → find-skills}/scripts/preview_skill.py +0 -0
- /package/comate-engine/assets/skills/{get-ugate-token-comate → get-ugate-token}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{get-ugate-token-comate → get-ugate-token}/getUgateToken.py +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/ai-workflows.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/commands.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/error-handling.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/git-auto-bindcard-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/git-bindcard-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/iql-syntax.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/platform-concepts.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-create-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-find-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icafe-comate → icafe}/references/smart-update-workflow.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/add_reviewers.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/build_fetch_command.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/check_repo_permission.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/create_branch.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/create_draft_comment.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_ai_cr_result.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_ai_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_diff_content.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_diff_file.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_machine_check.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_my_reviews.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_person_commit.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_person_repo.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_branch.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_config.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_members.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_repo_reviews.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_review_comments.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_review_info.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/get_submit_settings.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/icode-api.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/publish_comments.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/set_review_score.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/start_ai_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/submit_review.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/api/trigger_ai_cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/add-reviewer.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/fix-machine-check.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/merge-cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/ssh-setup.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/submit-acr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/feature/submit-cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/clone.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/icode-git.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/push.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/git/push_cr.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/install.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/references/login.md +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/add-reviewer.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/common.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/fix-machine-check.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/merge-cr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/ssh-setup.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/submit-acr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/submit-cr.sh +0 -0
- /package/comate-engine/assets/skills/{icode-comate → icode}/scripts/test-preflight.sh +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/SKILL.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/examples.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/add_member.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/change_scope.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/copy_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/create_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/delete_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/edit_content.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/move_doc.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_comment.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_content.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_flowchart.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_permission.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_recent_view.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_repo.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/query_user_info.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/update_member.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/references/upload_attachment.md +0 -0
- /package/comate-engine/assets/skills/{ku-operator-comate → ku-operator}/scripts/ku_operator.py +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Java 资源并发类规则
|
|
2
|
+
|
|
3
|
+
涵盖线程安全、资源泄漏、数据库操作、性能及接口鉴权问题。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 一、并发与线程安全(11项)
|
|
8
|
+
|
|
9
|
+
### RACE_JAVA_01. 非线程安全集合在多线程环境并发修改 [high]
|
|
10
|
+
- **检测**:多线程共享 HashMap/ArrayList 并发修改,可能死循环(JDK7)、数据错乱、ConcurrentModificationException
|
|
11
|
+
- **排除**:已用 ConcurrentHashMap/CopyOnWriteArrayList;有锁保护
|
|
12
|
+
|
|
13
|
+
### RACE_JAVA_02. SimpleDateFormat 多线程共享 [high]
|
|
14
|
+
- **检测**:`static` 或 `@Service` 单例中的 `SimpleDateFormat` 成员变量被多线程共用
|
|
15
|
+
- **排除**:已用 ThreadLocal;已改用 DateTimeFormatter(线程安全)
|
|
16
|
+
|
|
17
|
+
### RACE_JAVA_03. 双重检查锁单例未用 volatile [high]
|
|
18
|
+
- **检测**:DCL 单例 `instance` 字段缺少 `volatile`,可能因指令重排返回未完成初始化的对象
|
|
19
|
+
|
|
20
|
+
```java
|
|
21
|
+
private static Singleton instance; // 缺 volatile
|
|
22
|
+
// 正确:private static volatile Singleton instance;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### RACE_JAVA_04. synchronized 锁对象选择不当 [Critical]
|
|
26
|
+
- **检测**:
|
|
27
|
+
- 锁 String 常量池对象(`synchronized("lock")`)—— 不同类共享同一 String 常量,跨类互相阻塞
|
|
28
|
+
- 锁 Integer 缓存值(`synchronized(Integer.valueOf(n))`)—— -128~127 范围内对象被缓存共享
|
|
29
|
+
- 锁非 `private final` 对象 —— 字段可被外部替换,锁失效
|
|
30
|
+
- `synchronized(this.getClass())` —— 子类共享父类锁对象
|
|
31
|
+
- **排除**:使用 `private final Object lock = new Object()`
|
|
32
|
+
|
|
33
|
+
```java
|
|
34
|
+
// 错误写法 — String 常量池共享
|
|
35
|
+
synchronized ("myLock") { ... }
|
|
36
|
+
|
|
37
|
+
// 错误写法 — 非 private final,可被外部替换
|
|
38
|
+
public Object lock = new Object();
|
|
39
|
+
synchronized (lock) { ... }
|
|
40
|
+
|
|
41
|
+
// 正确写法
|
|
42
|
+
private final Object lock = new Object();
|
|
43
|
+
synchronized (lock) { ... }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### RACE_JAVA_05. 死锁导致线程挂起 [high]
|
|
47
|
+
- **检测**:多线程加锁顺序不一致(线程1: A→B,线程2: B→A)形成循环等待
|
|
48
|
+
- **排除**:固定加锁顺序;使用 tryLock 超时
|
|
49
|
+
|
|
50
|
+
### RACE_JAVA_06. ConcurrentHashMap 复合操作非原子 [high]
|
|
51
|
+
- **检测**:`if(!map.containsKey(k)) { map.put(k,v) }` 两步操作间有竞态
|
|
52
|
+
- **排除**:已用 `computeIfAbsent`/`putIfAbsent`
|
|
53
|
+
|
|
54
|
+
### RACE_JAVA_07. volatile 使用错误 [high]
|
|
55
|
+
- **检测**:误以为 volatile 保证原子性(`volatile int count; count++` 仍非原子);应用 volatile 保可见性却未用(stop flag 死循环)
|
|
56
|
+
- **排除**:用 AtomicInteger 等原子类;volatile 仅用于可见性保证
|
|
57
|
+
|
|
58
|
+
### RACE_JAVA_08. ThreadLocal 使用后未清理 [high]
|
|
59
|
+
- **检测**:线程池中 ThreadLocal.set() 后无 remove(),线程复用时数据串用或内存泄漏
|
|
60
|
+
- **排除**:在 finally/拦截器后置处理中有 remove()
|
|
61
|
+
|
|
62
|
+
### RACE_JAVA_09. 线程池使用无界队列或无上限线程数 [high]
|
|
63
|
+
- **检测**:`Executors.newFixedThreadPool`(无界队列)/`newCachedThreadPool`(无上限线程);`new ThreadPoolExecutor(..., new LinkedBlockingQueue<>())` 无容量限制
|
|
64
|
+
- **排除**:有界队列且容量合理;已用 ThreadPoolExecutor 显式配置
|
|
65
|
+
|
|
66
|
+
### RACE_JAVA_10. Future.get() 未设置超时 [high]
|
|
67
|
+
- **检测**:`future.get()` 无超时参数,远程任务挂起时线程永久阻塞,耗尽线程池
|
|
68
|
+
- **排除**:已用 `future.get(timeout, unit)`
|
|
69
|
+
|
|
70
|
+
### RACE_JAVA_11. @Async 注解失效 [middle]
|
|
71
|
+
- **检测**:同类内部调用 @Async 方法(通过 this 调用,不经代理);@Async 加在 private/final 方法上
|
|
72
|
+
- **排除**:通过注入自身代理调用;从外部 Bean 调用
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 二、资源泄漏(6项)
|
|
77
|
+
|
|
78
|
+
### RES_JAVA_01. 数据库连接未正确关闭 [high]
|
|
79
|
+
- **检测**:Connection/Statement/ResultSet 未在 finally 或 try-with-resources 中关闭
|
|
80
|
+
- **排除**:已用 try-with-resources;框架自动管理(Spring JdbcTemplate/MyBatis)
|
|
81
|
+
|
|
82
|
+
### RES_JAVA_02. IO 流未关闭 [high]
|
|
83
|
+
- **检测**:InputStream/OutputStream/Reader/Writer 未 close
|
|
84
|
+
- **排除**:已用 try-with-resources
|
|
85
|
+
|
|
86
|
+
### RES_JAVA_03. HTTP 连接未释放 [high]
|
|
87
|
+
- **检测**:CloseableHttpResponse 未消费 entity 或未 close,连接无法归还连接池
|
|
88
|
+
- **排除**:已用 try-with-resources + EntityUtils.consume
|
|
89
|
+
|
|
90
|
+
### RES_JAVA_04. ReentrantLock 未在 finally 中 unlock [high]
|
|
91
|
+
- **检测**:lock() 后无 try-finally 包裹,异常时锁永不释放导致死锁
|
|
92
|
+
|
|
93
|
+
```java
|
|
94
|
+
lock.lock();
|
|
95
|
+
try { process(); } finally { lock.unlock(); } // 正确
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### RES_JAVA_05. 本地缓存无限增长 OOM [high]
|
|
99
|
+
- **检测**:静态 Map/List 只增不删,无容量限制/TTL/淘汰策略
|
|
100
|
+
- **排除**:有 Guava Cache/Caffeine 等带淘汰策略的缓存;数量有界
|
|
101
|
+
|
|
102
|
+
### RES_JAVA_06. ExecutorService 未 shutdown [middle]
|
|
103
|
+
- **检测**:方法/类中创建的 ExecutorService 未调用 shutdown/shutdownNow,线程泄漏
|
|
104
|
+
- **排除**:Spring 管理的 ThreadPoolTaskExecutor;有 shutdown 调用
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 三、数据库操作(5项)
|
|
109
|
+
|
|
110
|
+
### DB_JAVA_01. N+1 查询 [middle]
|
|
111
|
+
- **检测**:循环中对每条记录单独执行 SQL 查询
|
|
112
|
+
- **排除**:已用 IN 批量查询;JOIN 查询;循环次数极少
|
|
113
|
+
|
|
114
|
+
### DB_JAVA_02. 大批量数据操作未分批 [high]
|
|
115
|
+
- **检测**:`selectAll()` 百万条数据一次加载到内存;批量 insert 无分批
|
|
116
|
+
- **排除**:数据量确认有限;有分页/分批处理
|
|
117
|
+
|
|
118
|
+
### DB_JAVA_03. Spring 事务失效 [high]
|
|
119
|
+
- **检测**:同类内部方法调用 @Transactional 方法(不经代理);@Transactional 加在 private 方法;catch 住异常未重新抛出导致事务不回滚
|
|
120
|
+
- **排除**:通过代理 Bean 调用;有 @Transactional(rollbackFor=Exception.class) + 异常传播
|
|
121
|
+
|
|
122
|
+
### DB_JAVA_04. 数据库免密连接 [Critical]
|
|
123
|
+
- **检测**:JDBC URL 中 password 为空;无密码认证
|
|
124
|
+
- **排除**:受信任的内网场景且有其他安全控制
|
|
125
|
+
|
|
126
|
+
### DB_JAVA_05. 数据库密码明文硬编码 [Critical]
|
|
127
|
+
- **检测**:源码中直接写死数据库密码字符串
|
|
128
|
+
- **排除**:已从配置中心/KMS 获取;已加密存储
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 四、性能(3项)
|
|
133
|
+
|
|
134
|
+
### PERF_JAVA_01. 循环中字符串 + 拼接 [low]
|
|
135
|
+
- **检测**:循环内 `result += item`,每次创建新 String 对象,应用 StringBuilder
|
|
136
|
+
- **排除**:循环次数极少(<10)
|
|
137
|
+
|
|
138
|
+
### PERF_JAVA_02. 正则表达式灾难性回溯 ReDoS [high]
|
|
139
|
+
- **检测**:`(a+)+`、`(a|aa)+` 等嵌套量词匹配长字符串,CPU 耗尽
|
|
140
|
+
- **排除**:输入长度有限制;正则已优化
|
|
141
|
+
|
|
142
|
+
### PERF_JAVA_03. 循环中创建重量级对象 [middle]
|
|
143
|
+
- **检测**:循环内 `new ObjectMapper()`/`new SimpleDateFormat()` 等代价高的对象每次新建
|
|
144
|
+
- **排除**:已提取到循环外;已用静态/线程本地实例
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 五、效率与正确性补充(4项)
|
|
149
|
+
|
|
150
|
+
### EFF_JAVA_01. 可并行的串行 Future.get() [middle]
|
|
151
|
+
- **检测**:连续提交多个互不依赖的 `CompletableFuture` 或 `Future`,却串行调用各自的 `.get()` 阻塞等待,而非用 `CompletableFuture.allOf()` 并行等待
|
|
152
|
+
- **排除**:后一个操作依赖前一个的返回值;操作间有顺序语义
|
|
153
|
+
|
|
154
|
+
```java
|
|
155
|
+
// 反例 — 串行阻塞,总耗时 = tA + tB
|
|
156
|
+
CompletableFuture<User> userFuture = fetchUserAsync(uid);
|
|
157
|
+
User user = userFuture.get(); // 阻塞等待
|
|
158
|
+
CompletableFuture<Config> cfgFuture = fetchConfigAsync();
|
|
159
|
+
Config cfg = cfgFuture.get(); // 再阻塞等待
|
|
160
|
+
|
|
161
|
+
// 正例 — 并行,总耗时 = max(tA, tB)
|
|
162
|
+
CompletableFuture<User> userFuture = fetchUserAsync(uid);
|
|
163
|
+
CompletableFuture<Config> cfgFuture = fetchConfigAsync();
|
|
164
|
+
CompletableFuture.allOf(userFuture, cfgFuture).join();
|
|
165
|
+
User user = userFuture.get();
|
|
166
|
+
Config cfg = cfgFuture.get();
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### EFF_JAVA_02. 文件/资源存在性预检查(TOCTOU) [low]
|
|
170
|
+
- **检测**:操作前先调用 `file.exists()`/`Files.exists()` 检查存在性,再执行实际操作,形成 check-then-act 竞态
|
|
171
|
+
- **排除**:业务逻辑确实需要分支且不可用异常替代
|
|
172
|
+
|
|
173
|
+
```java
|
|
174
|
+
// 反例
|
|
175
|
+
if (file.exists()) {
|
|
176
|
+
Files.readAllBytes(file.toPath());
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 正例
|
|
180
|
+
try {
|
|
181
|
+
Files.readAllBytes(file.toPath());
|
|
182
|
+
} catch (NoSuchFileException e) {
|
|
183
|
+
// 处理不存在
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### EFF_JAVA_03. 正则校验缺少锚点 [middle]
|
|
188
|
+
- **检测**:用于输入校验的正则表达式缺少 `^` 和 `$` 锚点,`Pattern.matcher(input).find()` 导致部分匹配通过本应拒绝的字符串
|
|
189
|
+
- **排除**:明确需要部分匹配;已使用 `matches()` 方法(自带全串匹配语义)
|
|
190
|
+
|
|
191
|
+
```java
|
|
192
|
+
// 反例 — "123abc" 能通过纯数字校验
|
|
193
|
+
Pattern.compile("\\d+").matcher(input).find();
|
|
194
|
+
|
|
195
|
+
// 正例
|
|
196
|
+
Pattern.compile("^\\d+$").matcher(input).matches();
|
|
197
|
+
// 或直接用 String.matches(),它等价于全串匹配
|
|
198
|
+
input.matches("\\d+");
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### EFF_JAVA_04. 抛出异常时未保留原始异常(错误链断裂) [middle]
|
|
202
|
+
- **检测**:在 `catch` 块中 `throw new XxxException("msg")` 时未将原始异常作为 `cause` 参数传入,导致原始堆栈信息丢失
|
|
203
|
+
- **排除**:有意隐藏底层异常(安全场景);原始异常已记录到日志
|
|
204
|
+
|
|
205
|
+
```java
|
|
206
|
+
// 反例 — 原始 cause 丢失
|
|
207
|
+
try {
|
|
208
|
+
db.execute(sql);
|
|
209
|
+
} catch (SQLException e) {
|
|
210
|
+
throw new ServiceException("数据库写入失败"); // e 丢失
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// 正例
|
|
214
|
+
try {
|
|
215
|
+
db.execute(sql);
|
|
216
|
+
} catch (SQLException e) {
|
|
217
|
+
throw new ServiceException("数据库写入失败", e);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Java 代码风格扫描规则(共14条)
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 一、Import 规则(2项)
|
|
6
|
+
|
|
7
|
+
### 1. JAVA010 UnusedImports - 未使用的 import 必须删除 [Critical]
|
|
8
|
+
|
|
9
|
+
**缺陷描述**:所有未使用的 import 语句应该被删除。
|
|
10
|
+
|
|
11
|
+
**判定方法**:在 import 声明之后的整个文件正文中(包括代码、注解、泛型参数),搜索该 import 引入的**简单类名**(最后一个 `.` 之后的部分)。如果该简单类名在文件正文中**从未以独立标识符形式出现**,则判定为未使用。
|
|
12
|
+
|
|
13
|
+
**经典案例**:
|
|
14
|
+
```java
|
|
15
|
+
// 错误写法
|
|
16
|
+
import java.util.HashMap; // 文件中从未使用 HashMap
|
|
17
|
+
import java.util.List; // 文件中从未使用 List
|
|
18
|
+
|
|
19
|
+
public class Example {
|
|
20
|
+
private String name;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**注意 — 以下场景中 import 视为「已使用」,不应报告**:类名出现在类型声明、注解、泛型参数、Javadoc(`@see`/`@link`)、throws 子句、静态方法调用、instanceof 中。
|
|
25
|
+
|
|
26
|
+
**核心原则:仅在确信类名在整个文件中完全不存在时才报告。如果无法确定,不报告。**
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
### 2. JAVA008 AvoidStarImport - 禁止通配符 import [Critical]
|
|
31
|
+
|
|
32
|
+
**缺陷描述**:非 static 的 import 语句,禁止使用通配符(`*`)导入。
|
|
33
|
+
|
|
34
|
+
**经典案例**:
|
|
35
|
+
```java
|
|
36
|
+
// 错误写法
|
|
37
|
+
import java.util.*;
|
|
38
|
+
import com.baidu.service.*;
|
|
39
|
+
|
|
40
|
+
// 正确写法
|
|
41
|
+
import java.util.List;
|
|
42
|
+
import java.util.Map;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**不应报告的场景**:`import static org.junit.Assert.*` 等 static import 不受此规则限制。
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 二、命名规则(3项)
|
|
50
|
+
|
|
51
|
+
### 3. JAVA028 MethodName - 方法名必须小驼峰 [Critical]
|
|
52
|
+
|
|
53
|
+
**缺陷描述**:方法名必须以小写字母开头,遵循驼峰命名方式,匹配正则 `^[a-z][a-zA-Z0-9]*$`。
|
|
54
|
+
|
|
55
|
+
**经典案例**:
|
|
56
|
+
```java
|
|
57
|
+
// 错误写法
|
|
58
|
+
public void GetUserName() {} // Pascal 风格
|
|
59
|
+
public void get_user_name() {} // 蛇形命名
|
|
60
|
+
public void _init() {} // 下划线开头
|
|
61
|
+
|
|
62
|
+
// 正确写法
|
|
63
|
+
public void getUserName() {}
|
|
64
|
+
public void init() {}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**不应报告的场景**:`@Test` 注解标记的测试方法;`@Override` 覆写父类/框架方法。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### 4. JAVA029 ConstantName - 常量命名必须全大写下划线分隔 [Critical]
|
|
72
|
+
|
|
73
|
+
**缺陷描述**:`static final` 修饰的基本类型或 String 字段(常量)命名全部大写,单词间用下划线隔开。
|
|
74
|
+
|
|
75
|
+
**「常量」判定标准**:同时满足:① `static final` 修饰;② 类型为基本数据类型或 String;③ 字段名不是 `serialVersionUID`。
|
|
76
|
+
|
|
77
|
+
**经典案例**:
|
|
78
|
+
```java
|
|
79
|
+
// 错误写法
|
|
80
|
+
public static final String max_count = "100";
|
|
81
|
+
public static final int defaultSize = 10;
|
|
82
|
+
|
|
83
|
+
// 正确写法
|
|
84
|
+
public static final String MAX_COUNT = "100";
|
|
85
|
+
public static final int DEFAULT_SIZE = 10;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**不应报告的场景**:Logger 对象、集合类型、工具对象、非 static 的 final 字段、枚举值、`serialVersionUID`(均不属于「常量」)。
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### 5. JAVA032 PackageName - 包名只允许小写字母和数字 [Critical]
|
|
93
|
+
|
|
94
|
+
**缺陷描述**:包名统一使用小写,每个 `.` 分隔的片段只包含小写字母 `[a-z]` 和数字 `[0-9]`。
|
|
95
|
+
|
|
96
|
+
**经典案例**:
|
|
97
|
+
```java
|
|
98
|
+
// 错误写法
|
|
99
|
+
package com.baidu.UserService;
|
|
100
|
+
package com.baidu.user_service;
|
|
101
|
+
|
|
102
|
+
// 正确写法
|
|
103
|
+
package com.baidu.userservice;
|
|
104
|
+
package org.apache.logging.log4j;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 三、格式规则(5项)
|
|
110
|
+
|
|
111
|
+
### 6. JAVA018 LineLength - 单行不超过120字符 [Critical]
|
|
112
|
+
|
|
113
|
+
**缺陷描述**:单行字符数不超过 120 个字符,超出需要换行。Tab 按 1 个字符计算。
|
|
114
|
+
|
|
115
|
+
**豁免场景**:package 语句;import 语句;包含 URL 的行;单行字符串字面量。
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### 7. JAVA003 FileTabCharacter - 禁止使用 Tab 字符 [Critical]
|
|
120
|
+
|
|
121
|
+
**缺陷描述**:缩进必须使用空格而不是 Tab(ASCII 0x09)。
|
|
122
|
+
|
|
123
|
+
**不应报告的场景**:字符串字面量内部的 `\t` 转义序列;无法确定是 Tab 还是空格时不报告。
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### 8. JAVA014 LeftCurly - 左花括号遵循 K&R 风格 [Critical]
|
|
128
|
+
|
|
129
|
+
**缺陷描述**:左花括号 `{` 不单独另起一行,放在前一语句的行末(K&R 风格)。
|
|
130
|
+
|
|
131
|
+
**经典案例**:
|
|
132
|
+
```java
|
|
133
|
+
// 错误写法(Allman 风格)
|
|
134
|
+
public class Example
|
|
135
|
+
{
|
|
136
|
+
public void method()
|
|
137
|
+
{
|
|
138
|
+
if (condition)
|
|
139
|
+
{
|
|
140
|
+
doSomething();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 正确写法(K&R 风格)
|
|
146
|
+
public class Example {
|
|
147
|
+
public void method() {
|
|
148
|
+
if (condition) {
|
|
149
|
+
doSomething();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**不应报告的场景**:空代码块 `{}` 可直接使用。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### 9. JAVA068 NeedBraces - if/else/for/while/do 必须使用花括号 [Critical]
|
|
160
|
+
|
|
161
|
+
**缺陷描述**:`if`、`else`、`for`、`while`、`do` 语句中即使只有一行代码也必须使用花括号。
|
|
162
|
+
|
|
163
|
+
**经典案例**:
|
|
164
|
+
```java
|
|
165
|
+
// 错误写法
|
|
166
|
+
if (condition) doSomething();
|
|
167
|
+
for (int i = 0; i < 10; i++) count++;
|
|
168
|
+
|
|
169
|
+
// 正确写法
|
|
170
|
+
if (condition) {
|
|
171
|
+
doSomething();
|
|
172
|
+
}
|
|
173
|
+
for (int i = 0; i < 10; i++) {
|
|
174
|
+
count++;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**不应报告的场景**:Lambda 表达式;switch-case 语句。
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### 10. JAVA020 WhitespaceAround - 关键字和运算符周围空格 [Critical]
|
|
183
|
+
|
|
184
|
+
**缺陷描述**:以下位置必须加空格:① `if`/`for`/`while`/`switch` 等关键字与括号之间;② 左花括号 `{` 之前;③ 二元和三元运算符两边;④ 逗号后。
|
|
185
|
+
|
|
186
|
+
**经典案例**:
|
|
187
|
+
```java
|
|
188
|
+
// 错误写法
|
|
189
|
+
if(condition){}
|
|
190
|
+
int result=a+b;
|
|
191
|
+
method(a,b,c);
|
|
192
|
+
|
|
193
|
+
// 正确写法
|
|
194
|
+
if (condition) {}
|
|
195
|
+
int result = a + b;
|
|
196
|
+
method(a, b, c);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**核心原则:仅对上述 4 个场景中最明显的违规进行报告。对于不确定或边界情况,不报告。**
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 四、结构规则(1项)
|
|
204
|
+
|
|
205
|
+
### 11. JAVA013 OverloadMethodsDeclarationOrder - 重载方法必须相邻 [Critical]
|
|
206
|
+
|
|
207
|
+
**缺陷描述**:同名的构造函数或方法之间禁止插入其他成员,重载方法必须放在一起。
|
|
208
|
+
|
|
209
|
+
**经典案例**:
|
|
210
|
+
```java
|
|
211
|
+
// 错误写法
|
|
212
|
+
public class Example {
|
|
213
|
+
public void process(String s) {}
|
|
214
|
+
public void handle() {} // 插入了其他方法
|
|
215
|
+
public void process(int n) {} // 与上面的 process 被隔开
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 正确写法
|
|
219
|
+
public class Example {
|
|
220
|
+
public void process(String s) {}
|
|
221
|
+
public void process(int n) {} // 紧跟同名方法
|
|
222
|
+
public void handle() {}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**不应报告的场景**:内部类中的同名方法与外部类独立判断;不同名方法之间的顺序不受约束。
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 五、注释规则(1项)
|
|
231
|
+
|
|
232
|
+
### 12. JAVA070 CommentsMustBeJavadocInSomeCase - 类/属性/方法注释必须用 Javadoc [Critical]
|
|
233
|
+
|
|
234
|
+
**缺陷描述**:类、public/protected 字段、public/protected 方法的注释必须使用 `/** 内容 */` 格式,不得使用 `// xxx` 方式。
|
|
235
|
+
|
|
236
|
+
**经典案例**:
|
|
237
|
+
```java
|
|
238
|
+
// 错误写法
|
|
239
|
+
// 用户服务类
|
|
240
|
+
public class UserService {}
|
|
241
|
+
|
|
242
|
+
// 错误写法
|
|
243
|
+
// 创建订单
|
|
244
|
+
public Order createOrder(OrderDTO dto) {}
|
|
245
|
+
|
|
246
|
+
// 正确写法
|
|
247
|
+
/** 用户服务类 */
|
|
248
|
+
public class UserService {}
|
|
249
|
+
|
|
250
|
+
/** 创建订单 */
|
|
251
|
+
public Order createOrder(OrderDTO dto) {}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**不应报告的场景**:方法体内部的行间注释;private 成员注释;行尾注释;无注释的类/字段/方法(此规则只检查格式,不检查是否有注释)。
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 六、编程实践规则(2项)
|
|
259
|
+
|
|
260
|
+
### 13. JAVA044 ObjectEquals - equals 方法防空指针 [Critical]
|
|
261
|
+
|
|
262
|
+
**缺陷描述**:`Object.equals()` 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals(字面量放左侧),或使用 `Objects.equals()`。
|
|
263
|
+
|
|
264
|
+
**判定方法**:检查 **变量在左、字符串字面量在右** 的 `.equals(字面量)` 模式。
|
|
265
|
+
|
|
266
|
+
**经典案例**:
|
|
267
|
+
```java
|
|
268
|
+
// 错误写法
|
|
269
|
+
if (name.equals("admin")) {}
|
|
270
|
+
if (status.equals("SUCCESS")) {}
|
|
271
|
+
|
|
272
|
+
// 正确写法
|
|
273
|
+
if ("admin".equals(name)) {}
|
|
274
|
+
if (Objects.equals(status, "SUCCESS")) {}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**不应报告的场景**:字面量已在左侧;使用 `Objects.equals`;两侧都是变量(`a.equals(b)`);枚举类型比较。
|
|
278
|
+
|
|
279
|
+
**核心原则:只报告「变量.equals(字符串字面量)」的明确模式,其余情况不报告。**
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### 14. JAVA041 OverrideWithAnnotation - 覆写方法必须加 @Override [Critical]
|
|
284
|
+
|
|
285
|
+
**缺陷描述**:所有覆写方法必须加 `@Override` 注解,防止方法签名拼写错误时编译器不报错。
|
|
286
|
+
|
|
287
|
+
**经典案例**:
|
|
288
|
+
```java
|
|
289
|
+
// 错误写法
|
|
290
|
+
public class User {
|
|
291
|
+
public String toString() { return "User{" + name + "}"; } // 缺少 @Override
|
|
292
|
+
public boolean equals(Object o) { return this == o; } // 缺少 @Override
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// 正确写法
|
|
296
|
+
public class User {
|
|
297
|
+
@Override
|
|
298
|
+
public String toString() { return "User{" + name + "}"; }
|
|
299
|
+
@Override
|
|
300
|
+
public boolean equals(Object o) { return this == o; }
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**不应报告的场景**:类没有 extends/implements 且方法名不是 Object 的标准方法;无法从当前文件确定是否为覆写方法。
|
|
305
|
+
|
|
306
|
+
**核心原则:只报告能高度确信是覆写方法(toString/equals/hashCode/clone/finalize,或有 super 调用)且缺少 @Override 的情况。**
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 接口鉴权与越权检测规则
|
|
2
|
+
|
|
3
|
+
本文件检测对外暴露接口的鉴权缺失与越权访问风险。适用于 JS/TS Node.js 后端服务。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
### AUTH_01. 对外接口缺少鉴权 [high]
|
|
8
|
+
- **检测**:有路由定义(router.get/post/put/delete)但无身份校验(req.user/req.session/ctx.user 校验)且无鉴权中间件(auth/authenticate/jwt/passport)
|
|
9
|
+
- **排除**:健康检查(/health/ping/status)、登录注册、静态资源、Swagger、Webhook 回调、全局中间件统一鉴权
|
|
10
|
+
- **复核**:确认无全局 auth 中间件;确认非公开接口
|
|
11
|
+
|
|
12
|
+
### AUTH_02. 越权访问 - 未校验资源归属 [high]
|
|
13
|
+
- **检测**:接口能获取用户身份(req.user),但操作资源时只用传入 ID(req.params.id/req.body.userId),未关联校验资源所有者
|
|
14
|
+
- **排除**:管理员接口有角色校验;公共资源;ORM 关联查询间接校验
|
|
15
|
+
- **复核**:确认能获取用户身份;确认未校验归属;确认非公共资源
|
|
16
|
+
|
|
17
|
+
### AUTH_03. 身份校验逻辑错误 [high]
|
|
18
|
+
- **检测**:用 `==` 而非 `===` 做 ID 比较;校验变量来自请求参数而非 token(req.params/query/body);校验条件有赋值操作(`=` 代替 `==`);校验位置在 early return 之后可被跳过
|
|
19
|
+
- **排除**:校验逻辑有效;框架内置权限;中间件统一处理
|
|
20
|
+
- **复核**:确认缺陷可被利用;确认变量来源错误
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// 错误写法 — 校验变量来自请求参数,可被伪造
|
|
24
|
+
router.get('/orders/:id', (req, res) => {
|
|
25
|
+
const userId = req.params.userId; // 来自请求,不可信
|
|
26
|
+
if (order.userId === userId) { ... }
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// 正确写法 — 从已验证的 token 中获取
|
|
30
|
+
router.get('/orders/:id', authMiddleware, (req, res) => {
|
|
31
|
+
const userId = req.user.id; // 来自解析后的 token
|
|
32
|
+
if (order.userId === userId) { ... }
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### AUTH_04. 鉴权中间件配置遗漏 [middle]
|
|
37
|
+
- **检测**:有全局鉴权中间件但部分路由组未被覆盖;中间件只保护特定 HTTP 方法
|
|
38
|
+
- **排除**:明确分开的公开/受保护路由文件;NestJS Guards 等框架统一鉴权
|
|
39
|
+
- **复核**:确认中间件确实未覆盖
|
|
40
|
+
|
|
41
|
+
### AUTH_05. 垂直越权 - 敏感操作缺少角色/权限校验 [high]
|
|
42
|
+
- **检测**:删除用户/修改权限/导出数据等管理员级别操作,未校验 `req.user.role` 或权限标记,普通用户可执行
|
|
43
|
+
- **排除**:有角色校验(admin/superuser);框架级权限管理(RBAC 中间件)
|
|
44
|
+
- **复核**:确认该操作需要特权;确认无权限校验
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
**通用排除**:健康检查/登录/静态资源/Webhook 回调;全局中间件统一鉴权;框架统一权限管理(NestJS Guards、Passport)
|