...
While inefficient, it is generally feasible to convert numeric values to strings and then reverse the process. However, the binary numeric value may not be representable in any particular character encodingset, because not all bit patterns represent valid characters. Consequently, programmers must never convert directly from a binary numeric value to a string.
Noncompliant Code Example
This noncompliant code example attempts to convert
...
a BigInteger
...
value to a String
and then restore it back again. The toByteArray()
method used returns a byte array containing the two's-complement representation of this BigInteger
. The byte array is in big-endian byte-order: the most significant byte is in the zeroth element.
...
The program uses the String(byte[] bytes)
constructor to create the string from the byte array. The behavior of this constructor when the given bytes are not valid in the default character set is unspecified, which is likely to be the case. Specifying the character set as a string also has unspecified behavior, although the Java API [API 2014] document claims that the String(byte[], Charset)
method always replaces malformed-input and unmappable-character sequences with this character set's default replacement string. In any case, converting the String
back to a BigInteger
...
is unlikely to reproduce the original value.
Code Block | ||
---|---|---|
| ||
BigInteger x = new BigInteger("530500452766"); // convert x to a String byte[] byteArray = x.toByteArray(); String s = new String(byteArray); // convert s back to a BigInteger byteArray = s.getBytes(); x = new BigInteger(byteArray); |
...
Compliant Solution
This compliant solution first produces a String
representation of the BigInteger
object and then converts the String
object to a byte array. This process is then reversed on input. Because the textual representation in the String
object was is generated by the BigInteger
class, it contains valid characterscharacter data in the default character set.
Code Block | ||
---|---|---|
| ||
BigInteger x = new BigInteger("530500452766"); String s = x.toString(); // valid character data try { byte[] byteArray = s.getBytes("UTF8"); // ns prints as "530500452766" String ns = new String(byteArray, "UTF8"); // construct the original BigInteger BigInteger x1 x = new BigInteger(ns); } catch (UnsupportedEncodingException ex) { // handle error } |
Do not try to convert the String
object to a byte array to obtain the original BigInteger
. Character encoded data may yield a byte array that, when converted to a BigInteger
, results in a completely different value.
Risk Assessment
Risk Assessment
Storing numeric data as a string is likely to result in a loss of data integrityAttempting to read a byte array containing binary data as if it were character data can produce erroneous results.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
STR05-J | low | unlikely | medium | P2 | L3 |
Related Guidelines
Bibliography