Incorrect absolute value of random number¶
ID: java/abs-of-randomKind: problemSecurity severity: Severity: warningPrecision: mediumTags: - quality - reliability - correctnessQuery suites: - java-security-and-quality.qls
Click to see the query in the CodeQL repository
UsingMath.abs on the result of a call toRandom.nextInt() (orRandom.nextLong()) is not guaranteed to return a non-negative number.Random.nextInt() can returnInteger.MIN_VALUE, which when passed toMath.abs results in the same value,Integer.MIN_VALUE. (Because of the two’s-complement representation of integers in Java, the positive equivalent ofInteger.MIN_VALUE cannot be represented in the same number of bits.) The case forRandom.nextLong() is similar.
Recommendation¶
If a non-negative random integer is required, useRandom.nextInt(int) instead, and useInteger.MAX_VALUE as its parameter. The values that might be returned do not includeInteger.MAX_VALUE itself, but this solution is likely to be sufficient for most purposes.
Another solution is to increment the value ofRandom.nextInt() by one, if it is negative, before passing the result toMath.abs. This solution has the advantage that0 has the same probability as other numbers.
Example¶
In the following example,mayBeNegativeInt is negative ifnextInt returnsInteger.MIN_VALUE. The example shows how using the two solutions described above means thatpositiveInt is always assigned a positive number.
publicstaticvoidmain(Stringargs[]){Randomr=newRandom();// BAD: 'mayBeNegativeInt' is negative if// 'nextInt()' returns 'Integer.MIN_VALUE'.intmayBeNegativeInt=Math.abs(r.nextInt());// GOOD: 'nonNegativeInt' is always a value between 0 (inclusive)// and Integer.MAX_VALUE (exclusive).intnonNegativeInt=r.nextInt(Integer.MAX_VALUE);// GOOD: When 'nextInt' returns a negative number increment the returned value.intnextInt=r.nextInt();if(nextInt<0)nextInt++;intnonNegativeInt=Math.abs(nextInt);}
References¶
Java API Specification:Math.abs(int),Math.abs(long),Random.
Java Language Specification:4.2.1 Integral Types and Values.