The contracts of the read methods for InputStream and Reader classes and their subclasses are complicated with regard to filling byte or character arrays. According to the Java API [API 20062014] for the class InputStream, the read(byte[] b, int off, int len) method, provides the following behavior:
...
However, the read(byte[] b) method:
reads some number of bytes from the input stream and stores them into the buffer array
b. The number of bytes actually read is returned as an integer. The number of bytes read is, at most, equal to the length ofb.
...
Ignoring the result returned by the read() methods is a violation of rule EXP00-J. Do not ignore values returned by methods. Security issues can arise even when return values are considered because the default behavior of the read() methods lacks any guarantee that the entire buffer array is filled. Consequently, when using read() to fill an array, the program must check the return value of read() and must handle the case where the array is only partially filled. In such cases, the program may try to fill the rest of the array, or work only with the subset of the array that was filled, or throw an exception.
...
This noncompliant code example attempts to read 1024 bytes encoded in UTF-8 from an InputStream and return them as a String. It explicitly specifies the character encoding used to build the string, in compliance with rule STR04-J. Use compatible character encodings when communicating string data between JVMs.
...
This compliant solution reads all the desired bytes into its buffer, accounting for the total number of bytes read and adjusting the remaining bytes' offset, consequently ensuring that the required data is read in full. It also avoids splitting multibyte encoded characters across buffers by deferring construction of the result string until the data has been fully read. (See rule see IDS10-J. Do not assume every character in a string is the same size for more information).)
| Code Block | ||
|---|---|---|
| ||
public static String readBytes(InputStream in) throws IOException {
int offset = 0;
int bytesRead = 0;
byte[] data = new byte[1024];
while ((bytesRead = in.read(data, offset, data.length - offset))
!= -1) {
offset += bytesRead;
if (offset >= data.length) {
break;
}
}
String str = new String(data, "UTF-8");
return str;
}
|
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
FIO10-J | lowLow | unlikelyUnlikely | mediumMedium | P2 | L3 |
Related Guidelines
Bibliography
[API 2006] | |
Section 8.1, "Handling Errors with Return Codes" | |
Chapter 7, "Data Streams, Reading Byte Arrays" | |
|
...