Install
openclaw skills install laosi-code-review多视角代码审查 - 安全(OWASP)/性能/正确性/风格,每视角输出严重级别+修复建议,支持PASS/BLOCK裁定
openclaw skills install laosi-code-review激活词: 审查 / code review / CR
┌────────────────────────────────────────┐
│ 代码审查 整体裁定 │
├──────────┬──────────┬─────────┬─────────┤
│ SECURITY │PERFORM- │CORRECT- │ STYLE │
│ 安全 │ ANCE 性能 │ NESS正确│ 风格 │
├──────────┼──────────┼─────────┼─────────┤
│ CRITICAL │ MAJOR │ MINOR │ INFO │
└──────────┴──────────┴─────────┴─────────┘
from dataclasses import dataclass, field
from typing import List, Optional
from enum import Enum
class Severity(Enum):
CRITICAL = "CRITICAL" # 必须修复
MAJOR = "MAJOR" # 强烈建议
MINOR = "MINOR" # 建议改进
INFO = "INFO" # 仅供参考
class Verdict(Enum):
PASS = "PASS"
PASS_WITH_COMMENTS = "PASS_WITH_COMMENTS"
BLOCK = "BLOCK"
@dataclass
class Finding:
perspective: str
severity: Severity
file: str
line: int
title: str
detail: str
suggestion: str
@dataclass
class ReviewResult:
findings: List[Finding] = field(default_factory=list)
def add(self, perspective: str, severity: Severity, file: str,
line: int, title: str, detail: str, suggestion: str = ""):
self.findings.append(Finding(
perspective, severity, file, line, title, detail, suggestion
))
def security_check(self, code: str, file: str = "unknown"):
"""安全视角检查"""
checks = [
("SQL注入风险", "execute(", "使用参数化查询代替字符串拼接"),
("XSS风险", "innerHTML", "使用textContent或安全转义"),
("硬编码密钥", "api_key", "移动到环境变量或密钥管理服务"),
("路径遍历", "../", "验证用户输入路径,使用basename"),
("命令注入", "os.system(", "使用subprocess.run传参数组"),
("eval执行", "eval(", "避免使用eval,改用安全替代方案"),
]
for title, pattern, suggestion in checks:
for i, line_text in enumerate(code.split('\n'), 1):
if pattern in line_text:
self.add("SECURITY", Severity.CRITICAL, file, i,
f"发现{title}: `{line_text.strip()}`",
f"第{i}行: `{line_text.strip()}`",
suggestion)
def performance_check(self, code: str, file: str = "unknown"):
perform_checks = [
("N+1查询", "for.*in.*query"),
("大循环", "for.*in range"),
("重复计算", ".count("),
]
# 简化示例
for title, _, _ in perform_checks:
pass # 实际检查会解析AST
def correctness_check(self, code: str, file: str = "unknown"):
correct_checks = [
("除以0", "/ (", "除法前检查分母是否为0"),
("空指针", "None."),
("索引越界", "[len("),
]
def style_check(self, code: str, file: str = "unknown"):
style_checks = [
("行长超限", lambda l: len(l) > 100),
("驼峰vs蛇形", lambda l: any(w.isupper() for w in l.split())),
]
def verdict(self) -> Verdict:
criticals = [f for f in self.findings
if f.severity in (Severity.CRITICAL, Severity.MAJOR)]
if any(f.severity == Severity.CRITICAL for f in self.findings):
return Verdict.BLOCK
if criticals:
return Verdict.PASS_WITH_COMMENTS
return Verdict.PASS
def report(self) -> str:
out = ["# Code Review Report\n"]
by_perspective = {}
for f in self.findings:
by_perspective.setdefault(f.perspective, []).append(f)
for perspective in ["SECURITY", "PERFORMANCE", "CORRECTNESS", "STYLE"]:
items = by_perspective.get(perspective, [])
if not items:
continue
sev = max(items, key=lambda x: x.severity.value).severity.value
out.append(f"## {perspective} [{sev}]")
for f in items:
sev_icon = {"CRITICAL": "🔴", "MAJOR": "🟡", "MINOR": "🔵", "INFO": "⚪"}
out.append(
f"- {sev_icon.get(f.severity.value, '')} "
f"`{f.file}:{f.line}` {f.title}\n"
f" > {f.detail}\n"
f" 💡 {f.suggestion}"
)
out.append("")
v = self.verdict()
v_icon = {"PASS": "✅", "PASS_WITH_COMMENTS": "⚠️", "BLOCK": "🚫"}
out.append(f"## 裁定: {v_icon[v.value]} {v.value}")
out.append(f"共 {len(self.findings)} 个发现项")
return "\n".join(out)
# 使用示例
code = """
def get_user(name):
query = "SELECT * FROM users WHERE name = '" + name + "'"
result = execute(query)
data = result.fetchall()
for row in data:
print(row)
"""
review = ReviewResult()
review.security_check(code, "users.py")
review.performance_check(code, "users.py")
review.correctness_check(code, "users.py")
review.style_check(code, "users.py")
print(review.report())
| 视角 | 典型问题 | 严重程度 |
|---|---|---|
| SECURITY | SQL注入、XSS、硬编码密钥、路径遍历 | CRITICAL |
| PERFORMANCE | N+1查询、内存泄漏、热点路径、缓存缺失 | MAJOR |
| CORRECTNESS | 除0、空指针、索引越界、竞态条件 | MAJOR |
| STYLE | 命名规范、死代码、类型安全、格式化 | MINOR |