You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
7.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
C++代码分析器
"""
import re
import os
from typing import List, Dict, Any
from .base_analyzer import BaseAnalyzer
class CppAnalyzer(BaseAnalyzer):
"""C++代码分析器"""
def __init__(self):
super().__init__()
self.name = "C++ Analyzer"
self.version = "1.0.0"
self.supported_extensions = ["cpp", "cc", "cxx", "hpp", "h"]
self.description = "C++代码静态分析器"
async def analyze(self, project_path: str, config: Dict[str, Any] = None) -> List[Dict[str, Any]]:
"""分析C++代码"""
vulnerabilities = []
# 获取所有C++文件
cpp_files = self.get_project_files(project_path)
for file_path in cpp_files:
try:
# 读取文件内容
content = self.read_file_content(file_path)
if not content:
continue
lines = content.split('\n')
# 执行各种检查
vulnerabilities.extend(self._check_memory_issues(lines, file_path))
vulnerabilities.extend(self._check_security_issues(lines, file_path))
vulnerabilities.extend(self._check_performance_issues(lines, file_path))
except Exception as e:
# 分析错误
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP000",
message=f"分析错误: {str(e)}",
file_path=file_path,
severity="high",
category="reliability"
))
return vulnerabilities
def _check_memory_issues(self, lines: List[str], file_path: str) -> List[Dict[str, Any]]:
"""检查内存相关问题"""
vulnerabilities = []
for i, line in enumerate(lines):
line_num = i + 1
line_stripped = line.strip()
# 检查裸指针使用
if re.search(r'\*[a-zA-Z_][a-zA-Z0-9_]*\s*[=;]', line_stripped):
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP101",
message="使用裸指针,建议使用智能指针",
file_path=file_path,
line_number=line_num,
severity="medium",
category="reliability",
code_snippet=line_stripped
))
# 检查malloc/free使用
elif 'malloc(' in line_stripped or 'free(' in line_stripped:
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP102",
message="使用malloc/free建议使用new/delete或智能指针",
file_path=file_path,
line_number=line_num,
severity="medium",
category="reliability",
code_snippet=line_stripped
))
# 检查数组越界风险
elif re.search(r'\[[a-zA-Z_][a-zA-Z0-9_]*\]', line_stripped):
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP103",
message="数组访问未进行边界检查",
file_path=file_path,
line_number=line_num,
severity="high",
category="reliability",
code_snippet=line_stripped
))
return vulnerabilities
def _check_security_issues(self, lines: List[str], file_path: str) -> List[Dict[str, Any]]:
"""检查安全问题"""
vulnerabilities = []
for i, line in enumerate(lines):
line_num = i + 1
line_stripped = line.strip()
# 检查strcpy使用
if 'strcpy(' in line_stripped:
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP201",
message="使用strcpy(),存在缓冲区溢出风险",
file_path=file_path,
line_number=line_num,
severity="critical",
category="security",
code_snippet=line_stripped
))
# 检查sprintf使用
elif 'sprintf(' in line_stripped:
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP202",
message="使用sprintf(),存在缓冲区溢出风险",
file_path=file_path,
line_number=line_num,
severity="critical",
category="security",
code_snippet=line_stripped
))
# 检查gets使用
elif 'gets(' in line_stripped:
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP203",
message="使用gets(),存在缓冲区溢出风险",
file_path=file_path,
line_number=line_num,
severity="critical",
category="security",
code_snippet=line_stripped
))
# 检查system调用
elif 'system(' in line_stripped:
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP204",
message="使用system()调用,存在命令注入风险",
file_path=file_path,
line_number=line_num,
severity="high",
category="security",
code_snippet=line_stripped
))
return vulnerabilities
def _check_performance_issues(self, lines: List[str], file_path: str) -> List[Dict[str, Any]]:
"""检查性能问题"""
vulnerabilities = []
for i, line in enumerate(lines):
line_num = i + 1
line_stripped = line.strip()
# 检查循环中的字符串连接
if re.search(r'for\s*\([^)]*\)\s*\{', line_stripped):
# 查找循环体中的字符串连接
for j in range(i + 1, min(i + 20, len(lines))): # 检查循环体前20行
loop_line = lines[j].strip()
if loop_line == '}':
break
if '+' in loop_line and ('"' in loop_line or "'" in loop_line):
vulnerabilities.append(self.create_vulnerability(
rule_id="CPP301",
message="循环中使用字符串连接,影响性能",
file_path=file_path,
line_number=j + 1,
severity="low",
category="performance",
code_snippet=loop_line
))
# 检查未使用的头文件包含
elif line_stripped.startswith('#include'):
# 这里可以添加更复杂的检查逻辑
pass
return vulnerabilities