循环条件中窄类型与宽类型的比较¶
ID: java/comparison-with-wider-type
Kind: problem
Security severity: 8.1
Severity: warning
Precision: medium
Tags:
- reliability
- security
- external/cwe/cwe-190
- external/cwe/cwe-197
Query suites:
- java-security-extended.qls
- java-security-and-quality.qls
在循环条件中,如果较宽的值足够大(或小),则窄类型的值与宽类型的值的比较可能始终评估为 true
。这是因为较窄的值可能会溢出。这可能导致无限循环。
建议¶
更改比较值的类型,以便比较中较窄一侧的值至少与它进行比较的值一样宽。
示例¶
在此示例中,bytesReceived
在 while
循环中与 MAXGET
进行比较。但是,bytesReceived
是 short
,而 MAXGET
是 long
。因为 MAXGET
大于 Short.MAX_VALUE
,所以循环条件始终为 true
,因此循环永远不会终止。
在“GOOD”案例中避免了此问题,因为 bytesReceived2
是 long
,它与 MAXGET
的类型一样宽。
class Test {
public static void main(String[] args) {
{
int BIGNUM = Integer.MAX_VALUE;
long MAXGET = Short.MAX_VALUE + 1;
char[] buf = new char[BIGNUM];
short bytesReceived = 0;
// BAD: 'bytesReceived' is compared with a value of wider type.
// 'bytesReceived' overflows before reaching MAXGET,
// causing an infinite loop.
while (bytesReceived < MAXGET) {
bytesReceived += getFromInput(buf, bytesReceived);
}
}
{
long bytesReceived2 = 0;
// GOOD: 'bytesReceived2' has a type at least as wide as MAXGET.
while (bytesReceived2 < MAXGET) {
bytesReceived2 += getFromInput(buf, bytesReceived2);
}
}
}
public static int getFromInput(char[] buf, short pos) {
// write to buf
// ...
return 1;
}
}
参考¶
SEI CERT Java 编码标准:NUM00-J. 检测或防止整数溢出。
通用弱点枚举:CWE-190。
通用弱点枚举:CWE-197。