43 lines
1.6 KiB
Plaintext
43 lines
1.6 KiB
Plaintext
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;
|
|
}
|
|
----
|
|
|
|
|
|
== See
|
|
|
|
* https://wiki.sei.cmu.edu/confluence/x/kDZGBQ[CERT, NUM52-J.] - Be aware of numeric promotion behavior
|
|
|