org.sonar.l10n.java.rules.squid.S3034.html Maven / Gradle / Ivy
When reading bytes in order to build other primitive values such as int
s or long
s, the byte
values are automatically promoted, but that promotion can have unexpected results.
For instance, the binary representation of the integer 640 is 0b0000_0010_1000_0000
, which can also be written with the array of (unsigned) bytes [2, 128]
. However, since Java uses two's complement, the representation of the integer in signed bytes will be [2, -128]
(because the byte
0b1000_0000
is promoted to the int
0b1111_1111_1111_1111_1111_1111_1000_0000
). Consequently, trying to reconstruct the initial integer by shifting and adding the values of the bytes without taking care of the sign will not produce the expected result.
To prevent such accidental value conversion, use bitwise and (&
) to combine the byte
value with 0xff
(255) and turn all the higher bits back off.
This rule raises an issue any time a byte
value is used as an operand without & 0xff
, when combined with shifts.
Noncompliant Code Example
int intFromBuffer() {
int result = 0;
for (int i = 0; i < 4; i++) {
result = (result << 8) | readByte(); // Noncompliant
}
return result;
}
Compliant Solution
int intFromBuffer() {
int result = 0;
for (int i = 0; i < 4; i++) {
result = (result << 8) | (readByte() & 0xff);
}
return result;
}