将字段设置为 null 时的 Java Null 取消引用 - Fortify

Posted

技术标签:

【中文标题】将字段设置为 null 时的 Java Null 取消引用 - Fortify【英文标题】:Java Null Dereference when setting a field to null - Fortify 【发布时间】:2019-10-20 05:33:05 【问题描述】:

当我将字段设置为 null 时,Fortify 抱怨 Null 取消引用:

String sortName = null;
if (lastName != null && lastName.length() > 0) 
   sortName = lastName;

sortOptions.setSortField(sortName);  <--  Fortify Null Dereference

Fortify 的分析轨迹显示:

Assigned null: sortName
Branch taken: if (lastName != null && lastName.length() > 0)
Dereferenced: sortName

我可以试试:

if (sortName == null)
   sortOptions.setSortField(null);
else
   sortOptions.setSortField(sortName);

但这看起来真的很愚蠢。有人有这方面的经验吗?我宁愿摆脱这个发现而不是把它写下来。

【问题讨论】:

如果将 null 值传递给 setSortField 会导致 NullPointer,那么传入显式 null 也会做同样的事情 请出示minimal reproducible example。 如果只是为了测试,你会发生什么String sortName = "" ; 添加了 Fortify 的分析跟踪,这表明取消引用 sortName 是问题所在。我们在代码中的很多地方都将字段设置为“null”,而 Fortify 很好。 【参考方案1】:

Thierry 的回答效果很好。这也通过了 Fortify 的扫描:

Optional<String> sortName = Optional.empty();
if (lastName != null && lastName.length() > 0) 
   sortName = Optional.ofNullable(lastName);

sortOptions.setSortField(sortName.orElse(null));

【讨论】:

你应该可以在这里使用Optional.of而不是ofNullable,因为你已经检查过它不为空。【参考方案2】:

fortify 不喜欢的是你先用null 初始化变量,没有条件,然后再改变它。

这应该可行:

String sortName;
if (lastName != null && lastName.length() > 0) 
   sortName = lastName;
 else 
   sortName = null;

sortOptions.setSortField(sortName);

(如果您愿意,也可以使用三元运算符)

这样你只初始化一次sortName,并明确表明null的值在某些情况下是正确的,而不是你忘记了某些情况,导致var保持null,而这是出乎意料的.

Null dereference 错误出现在代码行 sortName = lastName; 上,而不是 setter 的调用:fortify 不希望您有条件地更改设置为 null 的变量的值没有在所有分支中这样做。

【讨论】:

我会试试这个解决方案。不幸的是,我们的 Fortify 扫描需要几个小时才能运行。我会在有更多信息后立即更新...谢谢蒂埃里 此解决方案通过了 Fortify 扫描。感谢您的意见!

以上是关于将字段设置为 null 时的 Java Null 取消引用 - Fortify的主要内容,如果未能解决你的问题,请参考以下文章

Cassandra - 将一个巨大的字段设置为 null 而不归还磁盘空间

将学说实体布尔字段设置为 0 而不是 null

Mybatis-Plus将字段设置为null

在save()之前将null设置为mongo必填字段

我怎么能阻止JPA将embeddable对象设置为null只是因为它的所有字段都是null?

Java导出excel的程序里去除字段为null的数据,取出不为空的数据