【问题标题】:Java: (false?) positive S2637 in SonarQube 6.7.1 LTSJava:(错误?)SonarQube 6.7.1 LTS 中的 S2637 阳性
【发布时间】:2018-07-10 11:23:40
【问题描述】:

我在 Java 项目中使用 SonarQube 6.7.1 LTS,并使用 Maven 声纳插件对其进行分析。

我有以下代码示例,它在方法 testGregorianCalendar2 中发现了一个 S2637 问题:

public static final @Nonnull Calendar testGregorianCalendar1() {
    return GregorianCalendar.getInstance();
}

public static final @Nonnull Calendar testGregorianCalendar2() {
    return setTimeZone2(GregorianCalendar.getInstance());
}

public static final Calendar setTimeZone2(final Calendar inputCalendar) {
    if (null == inputCalendar) {
        return null;
    }
    return inputCalendar;
}

public static final @Nonnull Calendar testGregorianCalendar3() {
    return setTimeZone3(GregorianCalendar.getInstance());
}

public static final Calendar setTimeZone3(final Calendar inputCalendar) {
    return inputCalendar;
}

在方法testGregorianCalendar1testGregorianCalendar3 中,Sonar 没有发现该问题。 我认为在testGregorianCalendar2中应该也找不到,或者应该在testGregorianCalendar*的所有3种方法中都找到,因为:

Sonar 应该自行决定GregorianCalendar.getInstance() 是否可以返回 null。 如果是,所有 3 种方法都可以返回 null,Sonar 应该在所有这些方法中找到问题。

如果否,则调用setTimeZone2 方法时使用非空值,然后它将返回非空值,因此testGregorianCalendar2 将返回非空值。

那里出了什么问题?

【问题讨论】:

    标签: java sonarqube


    【解决方案1】:

    我不确定,但我猜会发生以下情况:setTimeZone2 有一个条件 return null,因此如果没有检查那个空值。

    即分析器看到:

    public static final Calendar setTimeZone2(final Calendar inputCalendar) {
        if (/* something */) {
            return null;
        }
        return /* null if inputCalendar is null */;
    }
    

    它确定:setTimeZone2 的返回值是(可能)@Nullable

    然后它看到:

    public static final @Nonnull Calendar testGregorianCalendar2() {
        return setTimeZone2(/* something */);
    }
    

    它看到一个潜在的@Nullable 值从标记为@Nonnull 的方法返回,这会产生警告。

    你和我都可以推断,setTimeZone2 永远不会返回 null,除非 inputCalendar 为 null,而 inputCalendar 永远不会为 null,因为 GregorianCalendar.getInstance() 永远不会返回 null,但分析器可能不会在what条件setTimeZone2可以返回null,只是在一些条件下可以。

    【讨论】:

    • 正确。它是一个静态代码分析工具。为了建立可能或不可能的值(包括null),SonarCube 必须编译、构建和运行它,这违背了目的。
    • @diginoise:一个足够先进的静态分析工具可以证明这段代码是安全的——它并不比编译器和JIT 已经做到了。 (例如,我敢打赌,如果这是一个性能热点,JIT 会内联 setTimeZone2 方法,然后窥视孔优化器会完全忽略空值检查。)但 Sonar 可能只是没有实现这种分析,因为它是一个大量的工作和它产生有意义的差异的情况(比如这个)比没有帮助的情况要少得多。
    • @DanielPryden 您的解释几乎是正确的,但是您对 SonarJava 分析器的符号执行引擎的工作方式做了一些错误的假设。在这种情况下,您对我们如何解释方法setTimeZone2 的解释是错误的。其余的与实际行为相距不远。 SonarJava 是开源的,所以你仍然可以在那里查看引擎:github.com/SonarSource/sonar-java/tree/master/java-frontend/src/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多