I’m picking up the theme of the CWE Top 25 today (see posts below for more detail on the list itself, or check out this blog posting for a more exhaustive description) as we run into what is described as CWE-404 all the time in managed code environments.
Although most C/C++ developers recognize explicit resource management as an issue, I’ve recently found out talking to some of our customers that they are totally unaware of the need to worry about such things in Java and especially C#. I even had one customer tell me in the context of C# that the CLR will “take care” of the issue. While it’s perhaps true that eventually the Finalize() method might take care of many resources, professional developers really should take the utmost care in dealing with precious unmanaged resources like file handles, graphics handles, or database connections.
A simple but surprisingly common example in C# illustrates the point:
static void Main()
StreamReader r = null;
r = File.OpenText (“blah.txt”);
if (r.EndOfStream) return;
The StreamReader class used here encapsulates an unmanaged resource, the underlying file handle that the O/S allocates to the CLR during the call to OpenText(). As you can see, that unmanaged resource is never released back to the O/S (until such time as the application terminates, of course).
A simple statement:
in a finally block would clean it up. Calling Close directly is okay but it is crucial to make sure you put that in the finally block. The most common resource leaks that I see static analysis tools find are the ones where you see a developer has been smart enough to dispose of his resource but there is another path (such as an exception that can be thrown on a method) where the resource is not disposed.
Another easier way to dispose of the resource is to apply the “using” statement, which calls Dispose on an IDisposable object automatically for you. This code:
using (Streamreader r = File.OpenText (“blah.txt”))
is the same as writing:
Streamreader r = File.OpenText (“blah.txt”);
if (r != null)
So make sure you know that you need to dispose of certain resources. In fairness, these can be hard issues to detect, particularly in an inter-procedural context, but good regimented use of code reviews, coupled with a good static analyzer should get you well on your way.