Integer variables are frequently intended to represent either a numeric value or a bit collection. Numeric values must be exclusively operated on using arithmetic operations, while whereas bit collections must be exclusively operated on using bitwise operations. Bitwise operators include the unary operator ~ and the binary operators <<
, >>
, >>>
, &
, ^, and |
.
Performing bitwise and arithmetic operations on the same data can obscure the purpose of the data stored in the variable , and often indicates confusion regarding that purpose. Unfortunately, bitwise operations are frequently performed on arithmetic values as a form of premature optimization. Although such operations are valid and will compile, they can reduce code readability.
...
Left- and right-shift operators are often employed to multiply or divide a number by a power of two. This approach compromises code readability and portability for the sake of often-illusory speed gains. The Java Virtual Machine (JVM) usually makes such optimizations automatically, and, unlike a programmer, the JVM can optimize for the implementation details of the current platform. This noncompliant code example includes both bitwise and arithmetic manipulations of the integer x
that conceptually contains a numeric value. The result is a prematurely optimized statement that assigns the value 5x + 1
to x
, which is what the programmer intended to express.
...
After this code sequence is run, x
contains the value -13
rather than the expected -12
. Arithmetic right shift truncates the resulting value towards toward negative infinity, whereas integer division truncates toward zero.
...
In the bitwise operation, the value of the byte array element b[i]
is promoted to an int
by sign - extension. When a byte array element contains a negative value (for example, 0xff
), the sign - extension propagates 1-bits into the upper 24 bits of the int
. This behavior might be unexpected if the programmer is assuming that byte
is an unsigned type. In this example, adding the promoted byte values to result
fails to result in a packed integer representation of the bytes [FindBugs 2008].
...
Code Block | ||
---|---|---|
| ||
int value = /* interestingInteresting value */ Byte[] bytes = new Byte[4]; for (int i = 0; i < bytes.length; i++) { bytes[i] = value >> (i*8) & 0xFF; } /* bytes[] now has same bit representation as value */ |
...
Performing bitwise manipulation and arithmetic operations on the same variable obscures the programmer's intentions and reduces readability. This, in turn, makes it more difficult for a security auditor or maintainer to determine which checks must be performed to eliminate security flaws and ensure data integrity. For instance, overflow checks are critical for numeric types that undergo arithmetic operations , but less critical for numeric types that undergo bitwise operations.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
NUM01-J | mediumMedium | unlikelyUnlikely | mediumMedium | P4 | L3 |
Related Guidelines
INT14-C. Avoid performing bitwise and arithmetic operations on the same data | |
INT14-CPP. Avoid performing bitwise and arithmetic operations on the same data |
...
[Seacord 2015] | NUM01-J. Do not perform bitwise and arithmetic operations on the same data LiveLesson |
...