19
2.1 Unreleased Resource Stream Vulnerability
The Unreleased Resource vulnerability (control flow issue) arises when the developer does not include
appropriate code that would guarantee the release of the system resources after their intended use (i.e., the
resources are no longer needed in the program).
In the context of the file writer program, the unreleased resource vulnerability was attributed due to the
possibility of the stream objects (the FileWriter and PrintWriter) that were instantiated to write the lines to
the text file not being released due to unanticipated errors during the file print (write) operation; the
control flow of the program could immediately switch to the catch block for the IOException (the
exception class handling most of the file read/write errors in Java) and not executing the release
statements (the close method calls) for the streams in the try block. Once the control exits the catch block,
the program continues to normally execute the code following the entire try-catch block and does not go
back to execute the remaining code in the try block where the error occurred. Hence, at most care should
be taken to release the resources that were allocated inside the try block.
However, since there can be more one than catch block, for a single try block, depending on the
specific exceptions that could be generated from the try block and need to be caught and processed, it
would not be a good idea to include statements pertaining to the release of the allocated system resources
in a particular catch block. This is because catch blocks are supposed to be listed in the increasing order
of the scope of the possible exceptions that could be generated from the try block, and hence if an
exception that is higher up in the hierarchy than an IOException is generated before completing the file
write operation, then the control would go to a catch block that is included somewhere below the catch
block for the IOException class, and the stream resources allocated for the file read operation would not
be released at all. To avoid such a scenario, one solution is to include redundant resource release
statements in each of the catch blocks. This would unnecessarily increase the code size and the memory
footprint of the program. An alternate and better solution is to include a finally block (optional in Java and
need not be used along with a try-catch block) following the catch blocks and include in it all the
statements related to the release of the allocated system resources in the corresponding try block. The
good news is the Java Virtual Machine will definitely execute the finally block after executing one or
more catch block(s), and will not skip it. This way, the allocated system resources in the try block are
guaranteed to be released.
Note that, we cannot directly call the close( ) method on the file writer object fw; it would generate an
IOException. Hence, we have to call the close( ) method inside a try-catch block within the finally block.
For clarity in the code, we have create a safeClose( ) method (called from the finally block) and close the
file writer inside that method.
import java.io.*;
import java.util.*;
/* Removing the Unreleased resource stream vulnerability on the resources
FileWriter and PrintWriter objects by closing them in the finally block */
/* Need to handle the IOException generated by the close() methods */
class fileWriter {
public static void safeClose(FileWriter fw){
try{
fw.close();
}
catch(IOException e){