# 代码漏扫工具
author:韩皖
createTime:2022-5-16
updateTime:2022-5-16
2022-05-16: 培训结束
# 使用教程
# 代码提交
登录 SonarQube 服务,点击新增项目
在新增项目的界面,填写
项目名称
和项目标识
(项目标识全局唯一),然后再点击设置
, 进入二级界面进入二级界面后选择
手工
方式分析项目,创建令牌,并记录下令牌的值在pom文件中添加属性 sonar.host.url 、sonar.login, 值为上一步骤创建的令牌值
在项目的根目录下执行命令(后续的代码提交只需执行该命令,以上的步骤省略)
# 中括号中的值可选,如果没有在pom文件中的属性中配置, 则必填 mvn clean verify sonar:sonar [-Dsonar.host.url=''] [-Dsonar.login='']
构建成功后, 登录后端 SonarQube 服务,即可看到提交记录,该记录简略地显示了各个指标项值
# 处理漏扫问题
进入项目的问题界面 , 分为左右两部分,左边为各种过滤筛选条件,右边是Bug的详情信息,违反了什么校验规则
过滤筛选后,点击Bug标题右边的
为何是问题
,界面底部有一个弹窗,弹窗中有该规则的详细说明,并且会有对应的正例反例了解规范后,点击
打开
,里面的流程就跟禅道差不多了,有 确认、解决、误判、标记为不会修复等选项
# Bug示例
Use try-with-resources or close this "FileOutputStream" in a "finally" clause.
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception { File targetFile = new File(filePath); if (!targetFile.exists()) { targetFile.mkdirs(); } // 可能造成资源泄漏,应使用 try-with-resources 或在 finally 中关闭资源 FileOutputStream out = new FileOutputStream(filePath + "/" + fileName); out.write(file); out.flush(); out.close(); } // ---》 改造后 public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception { File targetFile = new File(filePath); if (!targetFile.exists()) { targetFile.mkdirs(); } try(FileOutputStream out = new FileOutputStream(filePath + "/" + fileName)){ out.write(file); } }
Either re-interrupt this method or rethrow the "InterruptedException" that can be caught here.
中断是线程间通信的一种方式,一个线程向另一个线程发起中断请求后,接收到中断信号的线程应显示地处理它。如清除中断信号继续业务处理,或者停止业务处理继续向上层调用者传播中断异常
// 忽略中断异常,不做处理 try { ...业务处理... Thread.sleep(50); } catch (InterruptedException e) { ...ignore... } // ---》 改造后 try { ...业务处理... Thread.sleep(50); } catch (InterruptedException e) { Thread.interrupted(); }
Cognitive Complexity of methods should not be too high
代码中出现过多的 if 等分支语句,逻辑处理过于复杂,可读性降低
反例:如P010处理抄表结果返回时,其中一个步骤有15个分支
改造后:仅剩下三四个分支
This method's return value is marked "javax.annotation.Nonnull" but null is returned
该示例中,在接口的上方通过注解 @NotNull 标记方法的放回值不为空,但在实现里却存在返回Null的情况
@Override @Nonnull public Template createTemplate(@Nonnull NotifyType type, @Nonnull TemplateProperties prop) { Map<String, TemplateProvider> templateProviders = providers.get(type.getId()); if (templateProviders.isEmpty()){ log.info("不支持的通知类型【{}】", type.getId()); return null; } TemplateProvider templateProvider = templateProviders.get(prop.getProvider()); if (templateProvider == null){ log.info("不支持的服务商【{}】", prop.getProvider()); return null; } return templateProvider.createTemplate(prop); }
Prevent "int" promotion by adding "& 0xff" to this expression.
该示例中是一个byte类型的值与一个int类型执行位运算,由于byte类型的数值在执行运算时会隐式类型提升为int, 所以当byte值 > 127 时转换为int型时就会变为一个负数,出现bug。 所以正确的方式是在代码中显示地将其转换为正确的int值
int = getByte() | (1 << 4) // ---> 改造后 int = (getByte() && 0xff) | (1 << 4)
← 运维周报表规范 JAVA代码覆盖率检测 →