危险的非短路逻辑¶
ID: java/non-short-circuit-evaluation
Kind: problem
Security severity:
Severity: warning
Precision: medium
Tags:
- reliability
- readability
- external/cwe/cwe-691
Query suites:
- java-security-and-quality.qls
在条件与或条件或运算符 (&&
或 ||
) 预期的情况下,对布尔值使用按位逻辑运算符 (&
或 |
) 可能产生错误的结果或导致异常。如果左操作数是右操作数的保护措施,则尤其如此。
通常,如下面的示例所示,这种缺陷是由于简单地输入错误的预期逻辑运算符而不是程序员的任何概念错误而引入的。
建议¶
如果表达式右侧仅在左侧求值为 true
时才打算求值,请使用条件与。
类似地,如果表达式右侧仅在左侧求值为 false
时才打算求值,请使用条件或。
示例¶
在以下示例中,hasForename
方法已正确实现。要使名字有效,它必须是非空字符串且长度非零。该方法有两个表达式 (forename != null
和 forename.length() > 0
) 来检查这两个属性。仅当第一个检查成功时才执行第二个检查,因为它们使用条件与运算符 (&&
) 组合在一起。
相比之下,虽然 hasSurname
看起来几乎相同,但它包含一个缺陷。同样有两个测试 (surname != null
和 surname.length() > 0
),但它们通过按位逻辑运算符 (&
) 链接。按位逻辑运算符的两侧始终被评估,因此如果 surname
为 null
,则 hasSurname
方法会抛出 NullPointerException
。要修复缺陷,请将 &
更改为 &&
。
public class Person
{
private String forename;
private String surname;
public boolean hasForename() {
return forename != null && forename.length() > 0; // GOOD: Conditional-and operator
}
public boolean hasSurname() {
return surname != null & surname.length() > 0; // BAD: Bitwise AND operator
}
// ...
}
参考¶
J. Bloch 和 N. Gafter,Java 难题:陷阱、缺陷和特殊情况,第 42 个难题。Addison-Wesley,2005 年。
Java 语言规范:15.22.2 布尔逻辑运算符 &、^ 和 |,15.23 条件与运算符 &&,15.24 条件或运算符 ||。
常见弱点枚举:CWE-691。