Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛解决cppcheck可能出现中文编码错误问题 #663

Merged
merged 1 commit into from
Oct 24, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions client/tool/cppcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# ==============================================================================

"""
cppcheck 扫描任务
cppcheck 分析任务
"""

import os
Expand Down Expand Up @@ -35,11 +35,11 @@ def __init__(self, params):
self.sensitive_word_maps = {"cppcheck": "Tool", "Cppcheck": "Tool"}

def analyze(self, params):
"""执行cppcheck扫描任务
"""执行cppcheck分析任务

:param params: 需包含下面键值:
'rules': lint扫描的规则列表
'incr_scan' : 是否增量扫描
'rules': lint分析的规则列表
'incr_scan' : 是否增量分析

:return: return a :py:class:`IssueResponse`
"""
Expand Down Expand Up @@ -112,20 +112,21 @@ def _get_id_severity_map(self):
return id_severity_map

def _get_needed_visitors(self, id_severity_map, rule_list):
"""cppcheck不能指定规则扫描,只能指定规则级别,这里通过rules获取所属的规则级别"""
"""cppcheck不能指定规则分析,只能指定规则级别,这里通过rules获取所属的规则级别"""
assert rule_list is not None
# cppcheck默认就是开启error规则(且无法指定enable=error),所以这里取补集
return {id_severity_map[rule_name] for rule_name in rule_list} - {"error"}

def _run_cppcheck(self, files_path, rules, id_severity_map):
"""
执行cppcheck扫描工具
执行cppcheck分析工具
:param files_path:
:param rules:
:param id_severity_map:
:return:
"""
CPPCHECK_HOME = os.environ["CPPCHECK_HOME"]
LogPrinter.info("使用 cppcheck 为 %s" % CPPCHECK_HOME)
path_mgr = PathMgr()
cmd_args = [
"cppcheck",
Expand Down Expand Up @@ -155,32 +156,37 @@ def _run_cppcheck(self, files_path, rules, id_severity_map):
custom_cfgs = ["--library=" + cfg for cfg in custom_cfgs]
cmd_args.extend(custom_cfgs)

# 指定扫描文件
# 指定分析文件
cmd_args.append("--file-list=%s" % files_path)
scan_result_path = "cppcheck_result.xml"
self.print_log(f"cmd: {' '.join(cmd_args)}")
cmd_args = path_mgr.format_cmd_arg_list(cmd_args)
SubProcController(
cmd_args,
cwd=CPPCHECK_HOME,
stderr_filepath=scan_result_path,
stderr_line_callback=self._error_callback,
stdout_line_callback=self.print_log,
).wait()
if not os.path.exists(scan_result_path):
return scan_result_path
if sys.platform == "win32":
result_content = open(scan_result_path, "r", encoding="gbk").read()
open(scan_result_path, "w", encoding="utf-8").write(result_content)
with open(scan_result_path, "r", encoding="utf-8") as rf:
scan_result = rf.read()

if not scan_result:
return scan_result_path
# if not os.path.exists(scan_result_path):
# return scan_result_path
# try:
# if sys.platform == "win32":
# result_content = open(scan_result_path, 'r', encoding='gbk').read()
# open(scan_result_path, 'w', encoding='utf-8').write(result_content)
# with open(scan_result_path, 'r', encoding='utf-8') as rf:
# scan_result = rf.read()
# except UnicodeDecodeError as e:
# LogPrinter.warning(e)
# with open(scan_result_path, 'rb')
# if not scan_result:
# return scan_result_path

# 2019-8-28 偶现因为系统编码输出到结果文件,导致解析失败的情况
error_msg = "/bin/sh: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)\n"
if scan_result.startswith(error_msg):
scan_result = scan_result[len(error_msg) :]
# 2022-10-14 解析结果不再使用xml格式而是逐行解析,故不需要在解析前查看该文件
# error_msg = "/bin/sh: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)\n"
# if scan_result.startswith(error_msg):
# scan_result = scan_result[len(error_msg):]

# self.print_log("%s's result: \n%s" % (scan_result_path, scan_result))

Expand All @@ -200,9 +206,13 @@ def _format_result(self, source_dir, scan_result_path, rules, supported_rules):
"""格式化工具执行结果"""
issues = []
relpos = len(source_dir) + 1
with open(scan_result_path, "r") as rf:
with open(scan_result_path, "rb") as rf:
lines = rf.readlines()
for line in lines:
try:
line = line.decode("utf-8")
except:
line = line.decode("gbk")
error = line.split("[CODEDOG]")
if len(error) != 5:
LogPrinter.info("该error信息不全或格式有误: %s" % line)
Expand Down Expand Up @@ -232,8 +242,8 @@ def _format_result(self, source_dir, scan_result_path, rules, supported_rules):
def check_tool_usable(self, tool_params):
"""
这里判断机器是否支持运行cppcheck
1. 支持的话,便在客户机器上扫描
2. 不支持的话,就发布任务到公线机器扫描
1. 支持的话,便在客户机器上分析
2. 不支持的话,就发布任务到公线机器分析
:return:
"""
if SubProcController(["cppcheck", "--version"], stderr_line_callback=self.print_log).wait() != 0:
Expand Down